diff --git a/CHANGELOG.md b/CHANGELOG.md index 29c6324e..bd15edc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## To Be Released +* feat(one-off): allow attached one-off to be run asynchronously * feat(stacks): add support for Deployment `stack_base_image` * feat(backup): add `StartedAt` and `Method` fields diff --git a/go.mod b/go.mod index 3387ff4f..0b0569eb 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/Scalingo/go-scalingo/v6 go 1.20 require ( + github.com/Scalingo/go-utils/errors/v2 v2.2.0 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 github.com/gorilla/websocket v1.5.0 @@ -12,6 +13,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4b40087d..d5982e32 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,8 @@ +github.com/Scalingo/errgo-rollbar v0.2.0/go.mod h1:InPX+PbaicLpePiWdmay2bJ4gtF4anm2L8T6rITx41A= +github.com/Scalingo/go-utils/errors/v2 v2.2.0 h1:n93hge0DzfZ3KbI/jdnxKDTRDD+PXsGwNPKyHRzQYEE= +github.com/Scalingo/go-utils/errors/v2 v2.2.0/go.mod h1:pkLy6Qz9UNm6FpXtFJGZRC0W5lqbqHpPchrQV80gw5E= +github.com/Scalingo/go-utils/logger v1.2.0/go.mod h1:JArjD1gHdB/vwnlcVG7rYxuIY0tk8/VG4MtirnRwn8k= +github.com/Scalingo/logrus-rollbar v1.4.1/go.mod h1:ilLLgqIMzc5qXCGdMTEfbd7dM/zyOdOcO2YkpHVX+8k= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -16,13 +21,23 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rollbar/rollbar-go v1.4.0/go.mod h1:kLQ9gP3WCRGrvJmF0ueO3wK9xWocej8GRX98D8sa39w= +github.com/rollbar/rollbar-go v1.4.2/go.mod h1:kLQ9gP3WCRGrvJmF0ueO3wK9xWocej8GRX98D8sa39w= +github.com/rollbar/rollbar-go v1.4.4/go.mod h1:kLQ9gP3WCRGrvJmF0ueO3wK9xWocej8GRX98D8sa39w= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -36,9 +51,11 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/operations.go b/operations.go index bbf58fb3..50947a83 100644 --- a/operations.go +++ b/operations.go @@ -27,22 +27,29 @@ const ( type OperationType string const ( - OperationTypeScale OperationType = "scale" - OperationTypeStart OperationType = "start" + OperationTypeScale OperationType = "scale" + OperationTypeStart OperationType = "start" + OperationTypeStartOneOff OperationType = "start-one-off" ) type OperationResponse struct { Op Operation `json:"operation"` } +type OperationRunOneOffData struct { + AttachURL string `json:"attach_url"` + ContainerID map[string]string `json:"container_id"` +} + type Operation struct { - ID string `json:"id"` - AppID string `json:"app_id"` - CreatedAt time.Time `json:"created_at"` - FinishedAt time.Time `json:"finished_at"` - Status OperationStatus `json:"status"` - Type OperationType `json:"type"` - Error string `json:"error"` + ID string `json:"id"` + AppID string `json:"app_id"` + CreatedAt time.Time `json:"created_at"` + FinishedAt time.Time `json:"finished_at"` + Status OperationStatus `json:"status"` + Type OperationType `json:"type"` + Error string `json:"error"` + OneOffData OperationRunOneOffData `json:"one_off_data"` } func (op *Operation) ElapsedDuration() float64 { diff --git a/run.go b/run.go index dbfca90e..59549c9e 100644 --- a/run.go +++ b/run.go @@ -5,9 +5,8 @@ import ( "encoding/json" "strings" - "gopkg.in/errgo.v1" - "github.com/Scalingo/go-scalingo/v6/http" + errors "github.com/Scalingo/go-utils/errors/v2" ) type RunsService interface { @@ -22,12 +21,14 @@ type RunOpts struct { Env map[string]string Size string Detached bool + Async bool HasUploads bool } type RunRes struct { - Container *Container `json:"container"` - AttachURL string `json:"attach_url"` + Container *Container `json:"container"` + AttachURL string `json:"attach_url"` + OperationURL string `json:"-"` } func (c *Client) Run(ctx context.Context, opts RunOpts) (*RunRes, error) { @@ -39,20 +40,23 @@ func (c *Client) Run(ctx context.Context, opts RunOpts) (*RunRes, error) { "env": opts.Env, "size": opts.Size, "detached": opts.Detached, + "async": opts.Async, "has_uploads": opts.HasUploads, }, } res, err := c.ScalingoAPI().Do(ctx, req) if err != nil { - return nil, errgo.Mask(err) + return nil, errors.Notef(ctx, err, "request endpoint %v", req.Endpoint) } defer res.Body.Close() var runRes RunRes err = json.NewDecoder(res.Body).Decode(&runRes) if err != nil { - return nil, errgo.Mask(err) + return nil, errors.Notef(ctx, err, "decode response body") } + runRes.OperationURL = res.Header.Get("Location") + return &runRes, nil }