backend.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package build
  2. import (
  3. "fmt"
  4. "github.com/docker/distribution/reference"
  5. "github.com/docker/docker/api/types/backend"
  6. "github.com/docker/docker/builder"
  7. "github.com/docker/docker/builder/dockerfile"
  8. "github.com/docker/docker/image"
  9. "github.com/docker/docker/pkg/idtools"
  10. "github.com/docker/docker/pkg/stringid"
  11. "github.com/pkg/errors"
  12. "golang.org/x/net/context"
  13. )
  14. // ImageComponent provides an interface for working with images
  15. type ImageComponent interface {
  16. SquashImage(from string, to string) (string, error)
  17. TagImageWithReference(image.ID, reference.Named) error
  18. }
  19. // Backend provides build functionality to the API router
  20. type Backend struct {
  21. manager *dockerfile.BuildManager
  22. imageComponent ImageComponent
  23. }
  24. // NewBackend creates a new build backend from components
  25. func NewBackend(components ImageComponent, builderBackend builder.Backend, idMappings *idtools.IDMappings) *Backend {
  26. manager := dockerfile.NewBuildManager(builderBackend, idMappings)
  27. return &Backend{imageComponent: components, manager: manager}
  28. }
  29. // Build builds an image from a Source
  30. func (b *Backend) Build(ctx context.Context, config backend.BuildConfig) (string, error) {
  31. options := config.Options
  32. tagger, err := NewTagger(b.imageComponent, config.ProgressWriter.StdoutFormatter, options.Tags)
  33. if err != nil {
  34. return "", err
  35. }
  36. build, err := b.manager.Build(ctx, config)
  37. if err != nil {
  38. return "", err
  39. }
  40. var imageID = build.ImageID
  41. if options.Squash {
  42. if imageID, err = squashBuild(build, b.imageComponent); err != nil {
  43. return "", err
  44. }
  45. }
  46. stdout := config.ProgressWriter.StdoutFormatter
  47. fmt.Fprintf(stdout, "Successfully built %s\n", stringid.TruncateID(imageID))
  48. err = tagger.TagImages(image.ID(imageID))
  49. return imageID, err
  50. }
  51. func squashBuild(build *builder.Result, imageComponent ImageComponent) (string, error) {
  52. var fromID string
  53. if build.FromImage != nil {
  54. fromID = build.FromImage.ImageID()
  55. }
  56. imageID, err := imageComponent.SquashImage(build.ImageID, fromID)
  57. if err != nil {
  58. return "", errors.Wrap(err, "error squashing image")
  59. }
  60. return imageID, nil
  61. }