2017-02-11 00:48:15 +08:00
|
|
|
package buildah
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2017-05-09 23:56:44 +08:00
|
|
|
"io"
|
2017-02-24 06:56:48 +08:00
|
|
|
"io/ioutil"
|
2017-03-16 04:44:52 +08:00
|
|
|
"os"
|
2017-02-11 00:48:15 +08:00
|
|
|
"path/filepath"
|
|
|
|
|
2017-05-17 23:53:28 +08:00
|
|
|
"github.com/containers/storage"
|
2017-02-24 06:56:48 +08:00
|
|
|
"github.com/containers/storage/pkg/ioutils"
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
"github.com/opencontainers/image-spec/specs-go/v1"
|
2017-06-03 00:17:27 +08:00
|
|
|
"github.com/pkg/errors"
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
"github.com/projectatomic/buildah/docker"
|
2017-02-11 00:48:15 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2017-02-11 03:45:06 +08:00
|
|
|
// Package is the name of this package, used in help output and to
|
|
|
|
// identify working containers.
|
2017-04-19 03:52:53 +08:00
|
|
|
Package = "buildah"
|
|
|
|
// Version for the Package
|
2017-06-14 21:55:20 +08:00
|
|
|
Version = "0.1"
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
containerType = Package + " 0.0.1"
|
2017-02-24 06:56:48 +08:00
|
|
|
stateFile = Package + ".json"
|
2017-02-11 00:48:15 +08:00
|
|
|
)
|
|
|
|
|
2017-04-11 02:15:30 +08:00
|
|
|
const (
|
|
|
|
// PullIfMissing is one of the values that BuilderOptions.PullPolicy
|
|
|
|
// can take, signalling that the source image should be pulled from a
|
|
|
|
// registry if a local copy of it is not already present.
|
|
|
|
PullIfMissing = iota
|
|
|
|
// PullAlways is one of the values that BuilderOptions.PullPolicy can
|
|
|
|
// take, signalling that a fresh, possibly updated, copy of the image
|
|
|
|
// should be pulled from a registry before the build proceeds.
|
|
|
|
PullAlways
|
|
|
|
// PullNever is one of the values that BuilderOptions.PullPolicy can
|
|
|
|
// take, signalling that the source image should not be pulled from a
|
|
|
|
// registry if a local copy of it is not already present.
|
|
|
|
PullNever
|
|
|
|
)
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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.
|
2017-02-11 00:48:15 +08:00
|
|
|
type Builder struct {
|
|
|
|
store storage.Store
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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"`
|
2017-03-16 05:19:29 +08:00
|
|
|
// FromImageID is the ID of the source image which was used to create
|
|
|
|
// the container, if one was used. It should not be modified.
|
|
|
|
FromImageID string `json:"image-id"`
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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 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"`
|
2017-02-11 00:48:15 +08:00
|
|
|
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
// ImageAnnotations is a set of key-value pairs which is stored in the
|
2017-02-11 03:45:06 +08:00
|
|
|
// image's manifest.
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
ImageAnnotations map[string]string `json:"annotations,omitempty"`
|
|
|
|
// ImageCreatedBy is a description of how this container was built.
|
|
|
|
ImageCreatedBy string `json:"created-by,omitempty"`
|
2017-02-11 00:48:15 +08:00
|
|
|
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
// Image metadata and runtime settings, in multiple formats.
|
2017-05-17 05:07:31 +08:00
|
|
|
OCIv1 v1.Image `json:"ociv1,omitempty"`
|
|
|
|
Docker docker.V2Image `json:"docker,omitempty"`
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
// BuilderOptions are used to initialize a new Builder.
|
2017-02-11 00:48:15 +08:00
|
|
|
type BuilderOptions struct {
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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
|
2017-04-11 02:15:30 +08:00
|
|
|
// PullPolicy decides whether or not we should pull the image that
|
|
|
|
// we're using as a base image. It should be PullIfMissing,
|
|
|
|
// PullAlways, or PullNever.
|
|
|
|
PullPolicy int
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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
|
|
|
|
// 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.
|
2017-02-11 00:48:15 +08:00
|
|
|
SignaturePolicyPath string
|
2017-05-09 23:56:44 +08:00
|
|
|
// ReportWriter is an io.Writer which will be used to log the reading
|
|
|
|
// of the source image from a registry, if we end up pulling the image.
|
|
|
|
ReportWriter io.Writer
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
// ImportOptions are used to initialize a Builder from an existing container
|
|
|
|
// which was created elsewhere.
|
2017-02-25 04:18:35 +08:00
|
|
|
type ImportOptions struct {
|
|
|
|
// Container is the name of the build container.
|
|
|
|
Container 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
|
|
|
|
}
|
|
|
|
|
2017-05-19 05:38:41 +08:00
|
|
|
// ImportFromImageOptions are used to initialize a Builder from an image.
|
|
|
|
type ImportFromImageOptions struct {
|
|
|
|
// Image is the name or ID of the image we'd like to examine.
|
|
|
|
Image 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
|
|
|
|
}
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// NewBuilder creates a new build container.
|
2017-02-11 00:48:15 +08:00
|
|
|
func NewBuilder(store storage.Store, options BuilderOptions) (*Builder, error) {
|
|
|
|
return newBuilder(store, options)
|
|
|
|
}
|
|
|
|
|
2017-02-25 04:18:35 +08:00
|
|
|
// ImportBuilder creates a new build configuration using an already-present
|
|
|
|
// container.
|
|
|
|
func ImportBuilder(store storage.Store, options ImportOptions) (*Builder, error) {
|
|
|
|
return importBuilder(store, options)
|
|
|
|
}
|
|
|
|
|
2017-05-19 05:38:41 +08:00
|
|
|
// ImportBuilderFromImage creates a new builder configuration using an image.
|
|
|
|
// The returned object can be modified and examined, but it can not be saved
|
|
|
|
// or committed because it is not associated with a working container.
|
|
|
|
func ImportBuilderFromImage(store storage.Store, options ImportFromImageOptions) (*Builder, error) {
|
|
|
|
return importBuilderFromImage(store, options)
|
|
|
|
}
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// OpenBuilder loads information about a build container given its name or ID.
|
2017-02-11 00:48:15 +08:00
|
|
|
func OpenBuilder(store storage.Store, container string) (*Builder, error) {
|
2017-05-17 23:53:28 +08:00
|
|
|
cdir, err := store.ContainerDirectory(container)
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-02-24 06:56:48 +08:00
|
|
|
buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile))
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
b := &Builder{}
|
2017-04-04 05:44:23 +08:00
|
|
|
err = json.Unmarshal(buildstate, &b)
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-02-11 03:45:06 +08:00
|
|
|
if b.Type != containerType {
|
2017-06-03 00:17:27 +08:00
|
|
|
return nil, errors.Errorf("container is not a %s container", Package)
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
b.store = store
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
b.fixupConfig()
|
2017-02-11 00:48:15 +08:00
|
|
|
return b, nil
|
|
|
|
}
|
|
|
|
|
2017-03-24 01:32:16 +08:00
|
|
|
// OpenBuilderByPath loads information about a build container given a
|
|
|
|
// path to the container's root filesystem
|
2017-02-11 00:48:15 +08:00
|
|
|
func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) {
|
|
|
|
containers, err := store.Containers()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
abs, err := filepath.Abs(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
builderMatchesPath := func(b *Builder, path string) bool {
|
2017-05-28 18:52:18 +08:00
|
|
|
return (b.MountPoint == path)
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
for _, container := range containers {
|
2017-05-17 23:53:28 +08:00
|
|
|
cdir, err := store.ContainerDirectory(container.ID)
|
2017-03-16 04:42:37 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile))
|
2017-02-11 00:48:15 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
b := &Builder{}
|
2017-04-04 05:44:23 +08:00
|
|
|
err = json.Unmarshal(buildstate, &b)
|
2017-02-11 03:45:06 +08:00
|
|
|
if err == nil && b.Type == containerType && builderMatchesPath(b, abs) {
|
2017-02-11 00:48:15 +08:00
|
|
|
b.store = store
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
b.fixupConfig()
|
2017-02-11 00:48:15 +08:00
|
|
|
return b, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, storage.ErrContainerUnknown
|
|
|
|
}
|
|
|
|
|
2017-03-16 04:44:52 +08:00
|
|
|
// OpenAllBuilders loads all containers which have a state file that we use in
|
|
|
|
// their data directory, typically so that they can be listed.
|
|
|
|
func OpenAllBuilders(store storage.Store) (builders []*Builder, err error) {
|
|
|
|
containers, err := store.Containers()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, container := range containers {
|
2017-05-17 23:53:28 +08:00
|
|
|
cdir, err := store.ContainerDirectory(container.ID)
|
2017-03-16 04:44:52 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile))
|
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
b := &Builder{}
|
2017-04-04 05:44:23 +08:00
|
|
|
err = json.Unmarshal(buildstate, &b)
|
2017-03-16 04:44:52 +08:00
|
|
|
if err == nil && b.Type == containerType {
|
|
|
|
b.store = store
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
b.fixupConfig()
|
2017-03-16 04:44:52 +08:00
|
|
|
builders = append(builders, b)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return builders, nil
|
|
|
|
}
|
|
|
|
|
2017-02-11 03:45:06 +08:00
|
|
|
// 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.
|
2017-02-11 00:48:15 +08:00
|
|
|
func (b *Builder) Save() error {
|
|
|
|
buildstate, err := json.Marshal(b)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-05-17 23:53:28 +08:00
|
|
|
cdir, err := b.store.ContainerDirectory(b.ContainerID)
|
2017-02-24 06:56:48 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return ioutils.AtomicWriteFile(filepath.Join(cdir, stateFile), buildstate, 0600)
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|