Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -79,8 +79,10 @@ func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string |
| 79 | 79 |
} |
| 80 | 80 |
} |
| 81 | 81 |
|
| 82 |
- stdout := config.ProgressWriter.StdoutFormatter |
|
| 83 |
- fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID)) |
|
| 82 |
+ if !useBuildKit {
|
|
| 83 |
+ stdout := config.ProgressWriter.StdoutFormatter |
|
| 84 |
+ fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID)) |
|
| 85 |
+ } |
|
| 84 | 86 |
err = tagger.TagImages(image.ID(imageID)) |
| 85 | 87 |
return imageID, err |
| 86 | 88 |
} |
| ... | ... |
@@ -94,6 +96,10 @@ func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport, |
| 94 | 94 |
return &types.BuildCachePruneReport{SpaceReclaimed: size}, nil
|
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 |
+func (b *Backend) Cancel(ctx context.Context, id string) error {
|
|
| 98 |
+ return b.buildkit.Cancel(ctx, id) |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 97 | 101 |
func squashBuild(build *builder.Result, imageComponent ImageComponent) (string, error) {
|
| 98 | 102 |
var fromID string |
| 99 | 103 |
if build.FromImage != nil {
|
| ... | ... |
@@ -25,5 +25,6 @@ func (r *buildRouter) initRoutes() {
|
| 25 | 25 |
r.routes = []router.Route{
|
| 26 | 26 |
router.NewPostRoute("/build", r.postBuild, router.WithCancel),
|
| 27 | 27 |
router.NewPostRoute("/build/prune", r.postPrune, router.WithCancel),
|
| 28 |
+ router.NewPostRoute("/build/cancel", r.postCancel),
|
|
| 28 | 29 |
} |
| 29 | 30 |
} |
| ... | ... |
@@ -145,6 +145,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui |
| 145 | 145 |
options.CacheFrom = cacheFrom |
| 146 | 146 |
} |
| 147 | 147 |
options.SessionID = r.FormValue("session")
|
| 148 |
+ options.BuildID = r.FormValue("buildid")
|
|
| 148 | 149 |
|
| 149 | 150 |
return options, nil |
| 150 | 151 |
} |
| ... | ... |
@@ -157,6 +158,17 @@ func (br *buildRouter) postPrune(ctx context.Context, w http.ResponseWriter, r * |
| 157 | 157 |
return httputils.WriteJSON(w, http.StatusOK, report) |
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 |
+func (br *buildRouter) postCancel(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
| 161 |
+ w.Header().Set("Content-Type", "application/json")
|
|
| 162 |
+ |
|
| 163 |
+ id := r.FormValue("id")
|
|
| 164 |
+ if id == "" {
|
|
| 165 |
+ return errors.Errorf("build ID not provided")
|
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ return br.backend.Cancel(ctx, id) |
|
| 169 |
+} |
|
| 170 |
+ |
|
| 160 | 171 |
func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 161 | 172 |
var ( |
| 162 | 173 |
notVerboseBuffer = bytes.NewBuffer(nil) |
| ... | ... |
@@ -59,6 +59,9 @@ type Opt struct {
|
| 59 | 59 |
type Builder struct {
|
| 60 | 60 |
controller *control.Controller |
| 61 | 61 |
results *results |
| 62 |
+ |
|
| 63 |
+ mu sync.Mutex |
|
| 64 |
+ jobs map[string]func() |
|
| 62 | 65 |
} |
| 63 | 66 |
|
| 64 | 67 |
func New(opt Opt) (*Builder, error) {
|
| ... | ... |
@@ -71,11 +74,30 @@ func New(opt Opt) (*Builder, error) {
|
| 71 | 71 |
b := &Builder{
|
| 72 | 72 |
controller: c, |
| 73 | 73 |
results: results, |
| 74 |
+ jobs: map[string]func(){},
|
|
| 74 | 75 |
} |
| 75 | 76 |
return b, nil |
| 76 | 77 |
} |
| 77 | 78 |
|
| 79 |
+func (b *Builder) Cancel(ctx context.Context, id string) error {
|
|
| 80 |
+ b.mu.Lock() |
|
| 81 |
+ if cancel, ok := b.jobs[id]; ok {
|
|
| 82 |
+ cancel() |
|
| 83 |
+ } |
|
| 84 |
+ b.mu.Unlock() |
|
| 85 |
+ return nil |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 78 | 88 |
func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.Result, error) {
|
| 89 |
+ if buildID := opt.Options.BuildID; buildID != "" {
|
|
| 90 |
+ b.mu.Lock() |
|
| 91 |
+ ctx, b.jobs[buildID] = context.WithCancel(ctx) |
|
| 92 |
+ b.mu.Unlock() |
|
| 93 |
+ defer func() {
|
|
| 94 |
+ delete(b.jobs, buildID) |
|
| 95 |
+ }() |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 79 | 98 |
id := identity.NewID() |
| 80 | 99 |
|
| 81 | 100 |
attrs := map[string]string{
|
| 82 | 101 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+package client // import "github.com/docker/docker/client" |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "net/url" |
|
| 4 |
+ |
|
| 5 |
+ "golang.org/x/net/context" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// BuildCancel requests the daemon to cancel ongoing build request |
|
| 9 |
+func (cli *Client) BuildCancel(ctx context.Context, id string) error {
|
|
| 10 |
+ query := url.Values{}
|
|
| 11 |
+ query.Set("id", id)
|
|
| 12 |
+ |
|
| 13 |
+ serverResp, err := cli.post(ctx, "/build/cancel", query, nil, nil) |
|
| 14 |
+ if err != nil {
|
|
| 15 |
+ return err |
|
| 16 |
+ } |
|
| 17 |
+ defer ensureReaderClosed(serverResp) |
|
| 18 |
+ |
|
| 19 |
+ return nil |
|
| 20 |
+} |
| ... | ... |
@@ -133,5 +133,8 @@ func (cli *Client) imageBuildOptionsToQuery(options types.ImageBuildOptions) (ur |
| 133 | 133 |
if options.Platform != "" {
|
| 134 | 134 |
query.Set("platform", strings.ToLower(options.Platform))
|
| 135 | 135 |
} |
| 136 |
+ if options.BuildID != "" {
|
|
| 137 |
+ query.Set("buildid", options.BuildID)
|
|
| 138 |
+ } |
|
| 136 | 139 |
return query, nil |
| 137 | 140 |
} |
| ... | ... |
@@ -86,6 +86,7 @@ type DistributionAPIClient interface {
|
| 86 | 86 |
type ImageAPIClient interface {
|
| 87 | 87 |
ImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) |
| 88 | 88 |
BuildCachePrune(ctx context.Context) (*types.BuildCachePruneReport, error) |
| 89 |
+ BuildCancel(ctx context.Context, id string) error |
|
| 89 | 90 |
ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) |
| 90 | 91 |
ImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error) |
| 91 | 92 |
ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) |