diff --git a/buildah.go b/buildah.go index 87208a12f..13703825a 100644 --- a/buildah.go +++ b/buildah.go @@ -9,55 +9,124 @@ import ( ) const ( + // Package is the name of this package, used in help output and to + // identify working containers. Package = "buildah" - ContainerType = Package + " 0.0.0" + containerType = Package + " 0.0.0" ) +// Builder objects are used to represent containers which are being used to +// build images. They also carry potential updates which will be applied to +// the image's configuration when the container's contents are used to build an +// image. type Builder struct { store storage.Store - Type string - FromImage string - Config []byte - Manifest []byte + // Type is used to help identify a build container's metadata. It + // should not be modified. + Type string `json:"type"` + // FromImage is the name of the source image which was used to create + // the container, if one was used. It should not be modified. + FromImage string `json:"image,omitempty"` + // Config is the source image's configuration. It should not be + // modified. + Config []byte `json:"config,omitempty"` + // Manifest is the source image's manifest. It should not be modified. + Manifest []byte `json:"manifest,omitempty"` - Container string - ContainerID string - MountPoint string - Mounts []string - Links []string - Annotations map[string]string + // Container is the name of the build container. It should not be modified. + Container string `json:"container-name,omitempty"` + // ContainerID is the ID of the build container. It should not be modified. + ContainerID string `json:"container-id,omitempty"` + // MountPoint is the last location where the container's root + // filesystem was mounted. It should not be modified. + MountPoint string `json:"mountpoint,omitempty"` + // Mounts is a list of places where the container's root filesystem has + // been mounted. It should not be modified. + Mounts []string `json:"mounts,omitempty"` + // Links is a list of symbolic links to the currently-mounted container + // root filesystem. They will be removed when the container is + // unmounted. It should not be modified. + Links []string `json:"links,omitempty"` - CreatedBy string - OS string - Architecture string - Maintainer string - User string - Workdir string - Env []string - Cmd []string - Entrypoint []string - Expose map[string]interface{} - Labels map[string]string - Volumes []string - Arg map[string]string + // Annotations is a set of key-value pairs which is stored in the + // image's manifest. + Annotations map[string]string `json:"annotations,omitempty"` + + // CreatedBy is a description of how this container was built. + CreatedBy string `json:"created-by,omitempty"` + // OS is the operating system for which binaries in the image are + // built. The default is the current OS. + OS string `json:"os,omitempty"` + // Architecture is the type of processor for which binaries in the + // image are built. The default is the current architecture. + Architecture string `json:"arch,omitempty"` + // Maintainer is the point of contact for this container. + Maintainer string `json:"maintainer,omitempty"` + // User is the user as whom commands are run in the container. + User string `json:"user,omitempty"` + // Workdir is the default working directory for commands started in the + // container. + Workdir string `json:"workingdir,omitempty"` + // Env is a list of environment variables to set for the container, in + // the form NAME=VALUE. + Env []string `json:"env,omitempty"` + // Cmd sets a default command to run in containers based on the image. + Cmd []string `json:"cmd,omitempty"` + // Entrypoint is an entry point for containers based on the image. + Entrypoint []string `json:"entrypoint,omitempty"` + // Expose is a map keyed by specifications of ports to expose when a + // container based on the image is run. + Expose map[string]interface{} `json:"expose,omitempty"` + // Labels is a set of key-value pairs which is stored in the + // image's configuration. + Labels map[string]string `json:"labels,omitempty"` + // Volumes is a list of data volumes which will be created in + // containers based on the image. + Volumes []string `json:"volumes,omitempty"` + // Arg is a set of build-time variables. + Arg map[string]string `json:"arg,omitempty"` } +// BuilderOptions are used to initialize a Builder. type BuilderOptions struct { - FromImage string - Container string - PullIfMissing bool - PullAlways bool - Mount bool - Link string - Registry string + // FromImage is the name of the image which should be used as the + // starting point for the container. It can be set to an empty value + // or "scratch" to indicate that the container should not be based on + // an image. + FromImage string + // Container is a desired name for the build container. + Container string + // PullIfMissing signals to NewBuilder() that it should pull the image + // if it is not present in the local Store. + PullIfMissing bool + // PullAlways signals to NewBuilder() that it should pull the source + // image before creating the container. + PullAlways bool + // Registry is a value which is prepended to the image's name, if it + // needs to be pulled and the image name alone can not be resolved to a + // reference to a source image. + Registry string + // Mount signals to NewBuilder() that the container should be mounted + // immediately. + Mount bool + // Link specifies a location for a symbolic link which should be + // created if the container is mounted immediately. + Link string + // SignaturePolicyPath specifies an override location for the signature + // policy which should be used for verifying the new image as it is + // being written. Except in specific circumstances, no value should be + // specified, indicating that the shared, system-wide default policy + // should be used. SignaturePolicyPath string } +// NewBuilder creates a new build container. func NewBuilder(store storage.Store, options BuilderOptions) (*Builder, error) { return newBuilder(store, options) } +// OpenBuilder loads information about a build container given its name or ID. func OpenBuilder(store storage.Store, container string) (*Builder, error) { c, err := store.GetContainer(container) if err != nil { @@ -72,13 +141,16 @@ func OpenBuilder(store storage.Store, container string) (*Builder, error) { if err != nil { return nil, err } - if b.Type != ContainerType { + if b.Type != containerType { return nil, fmt.Errorf("container is not a %s container", Package) } b.store = store return b, nil } +// OpenBuilderByPath loads information about a build container given either a +// path to the container's root filesystem or a the path of a symbolic link +// which points to it. func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) { containers, err := store.Containers() if err != nil { @@ -111,7 +183,7 @@ func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) { } b := &Builder{} err = json.Unmarshal([]byte(buildstate), &b) - if err == nil && b.Type == ContainerType && builderMatchesPath(b, abs) { + if err == nil && b.Type == containerType && builderMatchesPath(b, abs) { b.store = store return b, nil } @@ -119,6 +191,9 @@ func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) { return nil, storage.ErrContainerUnknown } +// Save saves the builder's current state to the build container's metadata. +// This should not need to be called directly, as other methods of the Builder +// object take care of saving their state. func (b *Builder) Save() error { buildstate, err := json.Marshal(b) if err != nil { diff --git a/cmd/buildah/config.go b/cmd/buildah/config.go index a6492d751..8a5a11df8 100644 --- a/cmd/buildah/config.go +++ b/cmd/buildah/config.go @@ -11,6 +11,8 @@ import ( ) const ( + // DefaultCreatedBy is the default description of how an image layer + // was created that we use when adding to an image's history. DefaultCreatedBy = "manual edits" ) diff --git a/cmd/buildah/from.go b/cmd/buildah/from.go index e2efb4768..07bdc9454 100644 --- a/cmd/buildah/from.go +++ b/cmd/buildah/from.go @@ -8,6 +8,9 @@ import ( ) const ( + // DefaultRegistry is a prefix that we apply to an image name if we + // can't find one in the local Store, in order to generate a source + // reference for the image that we can then copy to the local Store. DefaultRegistry = "docker://" ) diff --git a/commit.go b/commit.go index 2ede35492..f90dbf41c 100644 --- a/commit.go +++ b/commit.go @@ -7,11 +7,22 @@ import ( "github.com/containers/storage/pkg/archive" ) +// CommitOptions can be used to alter how an image is committed. type CommitOptions struct { - Compression archive.Compression + // Compression specifies the type of compression which is applied to + // layer blobs. The default is to not use compression, but + // archive.Gzip is recommended. + Compression archive.Compression + // SignaturePolicyPath specifies an override location for the signature + // policy which should be used for verifying the new image as it is + // being written. Except in specific circumstances, no value should be + // specified, indicating that the shared, system-wide default policy + // should be used. SignaturePolicyPath string } +// Commit writes the contents of the container, along with its updated +// configuration, to a new image in the specified location. func (b *Builder) Commit(dest types.ImageReference, options CommitOptions) error { policy, err := signature.DefaultPolicy(getSystemContext(options.SignaturePolicyPath)) if err != nil { diff --git a/config.go b/config.go index 066387785..589b75e66 100644 --- a/config.go +++ b/config.go @@ -121,7 +121,7 @@ func (b *Builder) updatedConfig() []byte { if image.Config.ExposedPorts == nil { image.Config.ExposedPorts = make(map[string]struct{}) } - for k, _ := range b.Expose { + for k := range b.Expose { image.Config.ExposedPorts[k] = struct{}{} } } diff --git a/delete.go b/delete.go index bf60ccf42..125087489 100644 --- a/delete.go +++ b/delete.go @@ -5,6 +5,8 @@ import ( "os" ) +// Delete removes the working container. The Builder object should not be used +// after this method is called. func (b *Builder) Delete() error { for _, link := range b.Links { if err := os.Remove(link); err != nil { diff --git a/link.go b/link.go index f2ce17d2a..7c38e3e76 100644 --- a/link.go +++ b/link.go @@ -6,6 +6,9 @@ import ( "path/filepath" ) +// Link creates a symbolic link in a specified location which points to the +// root filesystem of a working container. The container should be mounted +// using the Mount() method before calling this method. func (b *Builder) Link(location string) error { if b.MountPoint == "" { return fmt.Errorf("build container is not mounted") diff --git a/mount.go b/mount.go index 1f073d473..f79abd324 100644 --- a/mount.go +++ b/mount.go @@ -1,5 +1,7 @@ package buildah +// Mount mounts a container's root filesystem in a location which can be +// accessed from the host, and returns the location. func (b *Builder) Mount(label string) (string, error) { mountpoint, err := b.store.Mount(b.ContainerID, label) if err != nil { diff --git a/new.go b/new.go index 9b8287604..800d56ddc 100644 --- a/new.go +++ b/new.go @@ -9,6 +9,8 @@ import ( ) const ( + // BaseImageFakeName is the "name" of a source image which we interpret + // as "no image". BaseImageFakeName = "scratch" ) @@ -18,6 +20,9 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) { config := []byte{} name := "working-container" + if options.FromImage == BaseImageFakeName { + options.FromImage = "" + } image := options.FromImage if options.Container != "" { name = options.Container @@ -42,7 +47,7 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) { systemContext := getSystemContext(options.SignaturePolicyPath) - if options.FromImage != "" && options.FromImage != BaseImageFakeName { + if image != "" { if options.PullAlways { err := pullImage(store, options, systemContext) if err != nil { @@ -103,8 +108,8 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) { builder := &Builder{ store: store, - Type: ContainerType, - FromImage: options.FromImage, + Type: containerType, + FromImage: image, Config: config, Manifest: manifest, Container: name, diff --git a/unmount.go b/unmount.go index 2246bf2eb..62dbe193c 100644 --- a/unmount.go +++ b/unmount.go @@ -6,6 +6,8 @@ import ( "github.com/Sirupsen/logrus" ) +// Unmount unmounts a build container, removing any links which have been made +// to its root. func (b *Builder) Unmount() error { err := b.store.Unmount(b.ContainerID) if err == nil {