diff options
Diffstat (limited to 'libpod/runtime.go')
-rw-r--r-- | libpod/runtime.go | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/libpod/runtime.go b/libpod/runtime.go new file mode 100644 index 000000000..80202c567 --- /dev/null +++ b/libpod/runtime.go @@ -0,0 +1,192 @@ +package libpod + +import ( + "os" + "sync" + + is "github.com/containers/image/storage" + "github.com/containers/image/types" + "github.com/containers/storage" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/ulule/deepcopier" +) + +// A RuntimeOption is a functional option which alters the Runtime created by +// NewRuntime +type RuntimeOption func(*Runtime) error + +// Runtime is the core libpod runtime +type Runtime struct { + config *RuntimeConfig + state State + store storage.Store + storageService *storageService + imageContext *types.SystemContext + ociRuntime *OCIRuntime + valid bool + lock sync.RWMutex +} + +// RuntimeConfig contains configuration options used to set up the runtime +type RuntimeConfig struct { + StorageConfig storage.StoreOptions + ImageDefaultTransport string + InsecureRegistries []string + Registries []string + SignaturePolicyPath string + RuntimePath string + ConmonPath string + ConmonEnvVars []string + CgroupManager string + StaticDir string + TmpDir string + SelinuxEnabled bool + PidsLimit int64 + MaxLogSize int64 + NoPivotRoot bool +} + +var ( + defaultRuntimeConfig = RuntimeConfig{ + // Leave this empty so containers/storage will use its defaults + StorageConfig: storage.StoreOptions{}, + ImageDefaultTransport: "docker://", + RuntimePath: "/usr/bin/runc", + ConmonPath: "/usr/local/libexec/crio/conmon", + ConmonEnvVars: []string{ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + }, + CgroupManager: "cgroupfs", + StaticDir: "/var/lib/libpod", + TmpDir: "/var/run/libpod", + SelinuxEnabled: false, + PidsLimit: 1024, + MaxLogSize: -1, + NoPivotRoot: false, + } +) + +// NewRuntime creates a new container runtime +// Options can be passed to override the default configuration for the runtime +func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) { + runtime = new(Runtime) + runtime.config = new(RuntimeConfig) + + // Copy the default configuration + deepcopier.Copy(defaultRuntimeConfig).To(runtime.config) + + // Overwrite it with user-given configuration options + for _, opt := range options { + if err := opt(runtime); err != nil { + return nil, errors.Wrapf(err, "error configuring runtime") + } + } + + // Set up containers/storage + store, err := storage.GetStore(runtime.config.StorageConfig) + if err != nil { + return nil, err + } + 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) + } + } + }() + + // Set up a storage service for creating container root filesystems from + // images + storageService, err := getStorageService(runtime.store) + if err != nil { + return nil, err + } + runtime.storageService = storageService + + // Set up containers/image + runtime.imageContext = &types.SystemContext{ + SignaturePolicyPath: runtime.config.SignaturePolicyPath, + } + + // Set up the state + state, err := NewInMemoryState() + if err != nil { + return nil, err + } + runtime.state = state + + // Make an OCI runtime to perform container operations + ociRuntime, err := newOCIRuntime("runc", runtime.config.RuntimePath, + runtime.config.ConmonPath, runtime.config.ConmonEnvVars, + runtime.config.CgroupManager, runtime.config.TmpDir, + runtime.config.MaxLogSize, runtime.config.NoPivotRoot) + if err != nil { + return nil, err + } + runtime.ociRuntime = ociRuntime + + // Make the static files directory if it does not exist + if err := os.MkdirAll(runtime.config.StaticDir, 0755); err != nil { + // The directory is allowed to exist + if !os.IsExist(err) { + return nil, errors.Wrapf(err, "error creating runtime static files directory %s", + runtime.config.StaticDir) + } + } + + // Make the per-boot files directory if it does not exist + if err := os.MkdirAll(runtime.config.TmpDir, 0755); err != nil { + // The directory is allowed to exist + if !os.IsExist(err) { + return nil, errors.Wrapf(err, "error creating runtime temporary files directory %s", + runtime.config.TmpDir) + } + } + + // Mark the runtime as valid - ready to be used, cannot be modified + // further + runtime.valid = true + + return runtime, nil +} + +// GetConfig returns a copy of the configuration used by the runtime +func (r *Runtime) GetConfig() *RuntimeConfig { + r.lock.RLock() + defer r.lock.RUnlock() + + if !r.valid { + return nil + } + + config := new(RuntimeConfig) + + // Copy so the caller won't be able to modify the actual config + deepcopier.Copy(r.config).To(config) + + return config +} + +// Shutdown shuts down the runtime and associated containers and storage +// If force is true, containers and mounted storage will be shut down before +// cleaning up; if force is false, an error will be returned if there are +// still containers running or mounted +func (r *Runtime) Shutdown(force bool) error { + r.lock.Lock() + defer r.lock.Unlock() + + if !r.valid { + return ErrRuntimeStopped + } + + r.valid = false + + _, err := r.store.Shutdown(force) + return err +} |