diff --git a/libpod/container.go b/libpod/container.go index ad4ee0f7..390b20b3 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -2,6 +2,7 @@ package libpod import ( "encoding/json" + "fmt" "io/ioutil" "path/filepath" "sync" @@ -100,6 +101,11 @@ type containerConfig struct { StaticDir string `json:"staticDir"` // Pod the container belongs to Pod string `json:"pod,omitempty"` + // Labels is a set of key-value pairs providing additional information + // about a container + Labels map[string]string `json:"labels,omitempty"` + // StopSignal is the signal that will be used to stop the container + StopSignal uint `json:"stopSignal,omitempty"` // Shared namespaces with container SharedNamespaceCtr *string `json:"shareNamespacesWith,omitempty"` SharedNamespaceMap map[string]string `json:"sharedNamespaces"` @@ -130,6 +136,16 @@ func (c *Container) Spec() *spec.Spec { return spec } +// Labels returns the container's labels +func (c *Container) Labels() map[string]string { + labels := make(map[string]string) + for key, value := range c.config.Labels { + labels[key] = value + } + + return labels +} + // State returns the current state of the container func (c *Container) State() (ContainerState, error) { c.lock.Lock() @@ -301,6 +317,7 @@ func (c *Container) Create() (err error) { deepcopier.Copy(c.config.Spec).To(c.runningSpec) c.runningSpec.Root.Path = c.state.Mountpoint c.runningSpec.Annotations[crioAnnotations.Created] = c.config.CreatedTime.Format(time.RFC3339Nano) + c.runningSpec.Annotations["org.opencontainers.image.stopSignal"] = fmt.Sprintf("%d", c.config.StopSignal) // Save the OCI spec to disk jsonPath := filepath.Join(c.bundlePath(), "config.json") diff --git a/libpod/options.go b/libpod/options.go index 3d424bb7..982655fc 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -320,12 +320,18 @@ func (r *Runtime) WithPod(pod *Pod) CtrCreateOption { // WithLabels adds labels to the container func WithLabels(labels map[string]string) CtrCreateOption { - return ctrNotImplemented -} + return func(ctr *Container) error { + if ctr.valid { + return ErrCtrFinalized + } -// WithAnnotations adds annotations to the container -func WithAnnotations(annotations map[string]string) CtrCreateOption { - return ctrNotImplemented + ctr.config.Labels = make(map[string]string) + for key, value := range labels { + ctr.config.Labels[key] = value + } + + return nil + } } // WithName sets the container's name @@ -343,7 +349,21 @@ func WithName(name string) CtrCreateOption { // WithStopSignal sets the signal that will be sent to stop the container func WithStopSignal(signal uint) CtrCreateOption { - return ctrNotImplemented + return func(ctr *Container) error { + if ctr.valid { + return ErrCtrFinalized + } + + if signal == 0 { + return errors.Wrapf(ErrInvalidArg, "stop signal cannot be 0") + } else if signal > 64 { + return errors.Wrapf(ErrInvalidArg, "stop signal cannot be greater than 64 (SIGRTMAX)") + } + + ctr.config.StopSignal = signal + + return nil + } } // Pod Creation Options diff --git a/libpod/runtime.go b/libpod/runtime.go index 48c710bc..80202c56 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -8,6 +8,7 @@ import ( "github.com/containers/image/types" "github.com/containers/storage" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/ulule/deepcopier" ) @@ -68,8 +69,8 @@ var ( // NewRuntime creates a new container runtime // Options can be passed to override the default configuration for the runtime -func NewRuntime(options ...RuntimeOption) (*Runtime, error) { - runtime := new(Runtime) +func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { + runtime = new(Runtime) runtime.config = new(RuntimeConfig) // Copy the default configuration @@ -89,9 +90,19 @@ func NewRuntime(options ...RuntimeOption) (*Runtime, error) { } runtime.store = store is.Transport.SetStore(store) + defer func() { + if err != nil { + // Don't forcibly shut down + // We could be opening a store in use by another libpod + _, err2 := runtime.store.Shutdown(false) + if err2 != nil { + logrus.Errorf("Error removing store for partially-created runtime: %s", err2) + } + } + }() - // TODO remove StorageImageServer and make its functions work directly - // on Runtime (or convert to something that satisfies an image) + // Set up a storage service for creating container root filesystems from + // images storageService, err := getStorageService(runtime.store) if err != nil { return nil, err