forked from concourse/concourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create.go
74 lines (57 loc) · 2.19 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package artifactserver
import (
"encoding/json"
"net/http"
"github.com/concourse/baggageclaim"
"github.com/pf-qiu/concourse/v6/atc/api/present"
"github.com/pf-qiu/concourse/v6/atc/db"
"github.com/pf-qiu/concourse/v6/atc/worker"
)
func (s *Server) CreateArtifact(team db.Team) http.Handler {
hLog := s.logger.Session("create-artifact")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
// TODO: can probably check if fly sent us an etag header
// which we can lookup in the checksum field
// that way we don't have to create another volume.
workerSpec := worker.WorkerSpec{
TeamID: team.ID(),
Platform: r.FormValue("platform"),
Tags: r.Form["tags"],
}
volumeSpec := worker.VolumeSpec{
Strategy: baggageclaim.EmptyStrategy{},
}
volume, err := s.workerClient.CreateVolume(hLog, volumeSpec, workerSpec, db.VolumeTypeArtifact)
if err != nil {
hLog.Error("failed-to-create-volume", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// NOTE: there's a race condition here between when the
// volume gets created and when the artifact gets initialized
// Within this timeframe there's a chance that the volume could
// get garbage collected out from under us.
// This happens because CreateVolume returns a 'created' instead
// of 'creating' volume.
// In the long run CreateVolume should probably return a 'creating'
// volume, but there are other changes needed in FindOrCreateContainer
// with the way we create volumes for a container
// I think leaving the race condition is fine for now. Worst case
// is a fly execute will fail and the user will need to rerun it.
artifact, err := volume.InitializeArtifact("", 0)
if err != nil {
hLog.Error("failed-to-initialize-artifact", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = volume.StreamIn(r.Context(), "/", baggageclaim.GzipEncoding, r.Body)
if err != nil {
hLog.Error("failed-to-stream-volume-contents", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(present.WorkerArtifact(artifact))
})
}