github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/packager/packing.go (about) 1 package packager 2 3 import ( 4 "archive/tar" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "path/filepath" 9 10 "github.com/docker/app/internal" 11 "github.com/docker/app/types" 12 "github.com/docker/cli/cli/command" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 ) 16 17 const ( 18 // DefaultCNABBaseImageName is the name of the default base invocation image. 19 DefaultCNABBaseImageName = "docker/cnab-app-base" 20 21 dockerIgnore = "Dockerfile" 22 ) 23 24 func tarAdd(tarout *tar.Writer, path, file string) error { 25 payload, err := ioutil.ReadFile(file) 26 if err != nil { 27 return err 28 } 29 return tarAddBytes(tarout, path, payload) 30 } 31 32 func tarAddBytes(tarout *tar.Writer, path string, payload []byte) error { 33 h := &tar.Header{ 34 Name: path, 35 Size: int64(len(payload)), 36 Mode: 0644, 37 Typeflag: tar.TypeReg, 38 } 39 err := tarout.WriteHeader(h) 40 if err != nil { 41 return err 42 } 43 _, err = tarout.Write(payload) 44 return err 45 } 46 47 // PackInvocationImageContext creates a Docker build context for building a CNAB invocation image 48 func PackInvocationImageContext(cli command.Cli, app *types.App, target io.Writer) error { 49 logrus.Debug("Packing invocation image context") 50 tarout := tar.NewWriter(target) 51 defer tarout.Close() 52 prefix := fmt.Sprintf("%s%s/", app.Metadata().Name, internal.AppExtension) 53 if len(app.Composes()) != 1 { 54 return errors.New("app should have one and only one compose file") 55 } 56 if len(app.ParametersRaw()) != 1 { 57 return errors.New("app should have one and only one parameters file") 58 } 59 if err := tarAddBytes(tarout, "Dockerfile", []byte(dockerFile(cli))); err != nil { 60 return errors.Wrap(err, "failed to add Dockerfile to the invocation image build context") 61 } 62 if err := tarAddBytes(tarout, ".dockerignore", []byte(dockerIgnore)); err != nil { 63 return errors.Wrap(err, "failed to add .dockerignore to the invocation image build context") 64 } 65 if err := tarAddBytes(tarout, prefix+internal.MetadataFileName, app.MetadataRaw()); err != nil { 66 return errors.Wrapf(err, "failed to add %q to the invocation image build context", prefix+internal.MetadataFileName) 67 } 68 if err := tarAddBytes(tarout, prefix+internal.ComposeFileName, app.Composes()[0]); err != nil { 69 return errors.Wrapf(err, "failed to add %q to the invocation image build context", prefix+internal.ComposeFileName) 70 } 71 if err := tarAddBytes(tarout, prefix+internal.ParametersFileName, app.ParametersRaw()[0]); err != nil { 72 return errors.Wrapf(err, "failed to add %q to the invocation image build context", prefix+internal.ParametersFileName) 73 } 74 for _, attachment := range app.Attachments() { 75 if err := tarAdd(tarout, prefix+attachment.Path(), filepath.Join(app.Path, attachment.Path())); err != nil { 76 return errors.Wrapf(err, "failed to add attachment %q to the invocation image build context", prefix+attachment.Path()) 77 } 78 } 79 return nil 80 } 81 82 // BaseInvocationImage returns the name and tag of the CNAB base invocation image 83 func BaseInvocationImage(cli command.Cli) string { 84 img := DefaultCNABBaseImageName + `:` + internal.Version 85 if cfg := cli.ConfigFile(); cfg != nil { 86 if v, ok := cfg.PluginConfig("app", "base-invocation-image"); ok { 87 return v 88 } 89 } 90 return img 91 } 92 93 func dockerFile(cli command.Cli) string { 94 return fmt.Sprintf("FROM %s\nCOPY . .", BaseInvocationImage(cli)) 95 }