diff options
-rw-r--r-- | cmd/podman/exists.go | 6 | ||||
-rw-r--r-- | cmd/podman/history.go | 4 | ||||
-rw-r--r-- | cmd/podman/images.go | 6 | ||||
-rw-r--r-- | cmd/podman/info.go | 6 | ||||
-rw-r--r-- | cmd/podman/pull.go | 4 | ||||
-rw-r--r-- | cmd/podman/rmi.go | 2 | ||||
-rw-r--r-- | cmd/podman/tag.go | 2 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 2 | ||||
-rw-r--r-- | docs/podman.1.md | 2 | ||||
-rw-r--r-- | libpod.conf | 23 | ||||
-rw-r--r-- | libpod/adapter/runtime.go | 18 | ||||
-rw-r--r-- | libpod/adapter/runtime_remote.go | 86 | ||||
-rw-r--r-- | libpod/container.go | 3 | ||||
-rw-r--r-- | libpod/info.go | 6 | ||||
-rw-r--r-- | libpod/oci.go | 6 | ||||
-rw-r--r-- | libpod/options.go | 6 | ||||
-rw-r--r-- | libpod/runtime.go | 77 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 2 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.c | 9 |
19 files changed, 190 insertions, 80 deletions
diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go index e6d2c8a11..a7601aaa2 100644 --- a/cmd/podman/exists.go +++ b/cmd/podman/exists.go @@ -71,7 +71,7 @@ func imageExistsCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) if _, err := runtime.NewImageFromLocal(args[0]); err != nil { //TODO we need to ask about having varlink defined errors exposed //so we can reuse them @@ -88,13 +88,13 @@ func containerExistsCmd(c *cli.Context) error { if len(args) > 1 || len(args) < 1 { return errors.New("you may only check for the existence of one container at a time") } - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := adapter.GetRuntime(c) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) if _, err := runtime.LookupContainer(args[0]); err != nil { - if errors.Cause(err) == libpod.ErrNoSuchCtr { + if errors.Cause(err) == libpod.ErrNoSuchCtr || err.Error() == "io.podman.ContainerNotFound" { os.Exit(1) } return err diff --git a/cmd/podman/history.go b/cmd/podman/history.go index 802047071..8a9b6cd94 100644 --- a/cmd/podman/history.go +++ b/cmd/podman/history.go @@ -1,13 +1,13 @@ package main import ( - "github.com/containers/libpod/libpod/adapter" "reflect" "strconv" "strings" "time" "github.com/containers/libpod/cmd/podman/formats" + "github.com/containers/libpod/libpod/adapter" "github.com/containers/libpod/libpod/image" "github.com/docker/go-units" "github.com/pkg/errors" @@ -76,7 +76,7 @@ func historyCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) format := genHistoryFormat(c.String("format"), c.Bool("quiet")) diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 2b4187a9a..031f06618 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -2,8 +2,6 @@ package main import ( "context" - "github.com/containers/libpod/cmd/podman/imagefilters" - "github.com/containers/libpod/libpod/adapter" "reflect" "sort" "strings" @@ -11,6 +9,8 @@ import ( "unicode" "github.com/containers/libpod/cmd/podman/formats" + "github.com/containers/libpod/cmd/podman/imagefilters" + "github.com/containers/libpod/libpod/adapter" "github.com/containers/libpod/libpod/image" "github.com/docker/go-units" "github.com/opencontainers/go-digest" @@ -156,7 +156,7 @@ func imagesCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "Could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) if len(c.Args()) == 1 { newImage, err = runtime.NewImageFromLocal(c.Args().Get(0)) if err != nil { diff --git a/cmd/podman/info.go b/cmd/podman/info.go index 1ec4011da..c33ede548 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -1,11 +1,11 @@ package main import ( - "github.com/containers/libpod/libpod/adapter" "runtime" "github.com/containers/libpod/cmd/podman/formats" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/adapter" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -43,9 +43,9 @@ func infoCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) - infoArr, err := runtime.Runtime.Info() + infoArr, err := runtime.Info() if err != nil { return errors.Wrapf(err, "error getting info") } diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index d81457c67..2a78d0c54 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "github.com/containers/libpod/libpod/adapter" "io" "os" "strings" @@ -10,6 +9,7 @@ import ( dockerarchive "github.com/containers/image/docker/archive" "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" + "github.com/containers/libpod/libpod/adapter" image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" @@ -68,7 +68,7 @@ func pullCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) args := c.Args() if len(args) == 0 { diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index 58a78a924..fbf860eb2 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -61,7 +61,7 @@ func rmiCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) args := c.Args() if len(args) == 0 && !removeAll { diff --git a/cmd/podman/tag.go b/cmd/podman/tag.go index 8e92ca2fa..d19cf69a2 100644 --- a/cmd/podman/tag.go +++ b/cmd/podman/tag.go @@ -27,7 +27,7 @@ func tagCmd(c *cli.Context) error { if err != nil { return errors.Wrapf(err, "could not create runtime") } - defer runtime.Runtime.Shutdown(false) + defer runtime.Shutdown(false) newImage, err := runtime.NewImageFromLocal(args[0]) if err != nil { diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index a3e8c050e..c6f1d3f1b 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -61,7 +61,7 @@ type ImageSearch ( star_count: int ) -# ListContainer is the returned struct for an individual container +# ListContainerData is the returned struct for an individual container type ListContainerData ( id: string, image: string, diff --git a/docs/podman.1.md b/docs/podman.1.md index a73ebb55e..74e700fac 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -68,7 +68,7 @@ Default state dir is configured in /etc/containers/storage.conf. **--runtime**=**value** -Path to the OCI compatible binary used to run containers +Name of the OCI runtime as specified in libpod.conf or absolute path to the OCI compatible binary used to run containers. **--storage-driver, -s**=**value** diff --git a/libpod.conf b/libpod.conf index cfdf83775..acd6c8982 100644 --- a/libpod.conf +++ b/libpod.conf @@ -4,17 +4,6 @@ # Default transport method for pulling and pushing for images image_default_transport = "docker://" -# Paths to look for a valid OCI runtime (runc, runv, etc) -runtime_path = [ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc" -] - # Paths to look for the Conmon container manager binary conmon_path = [ "/usr/libexec/podman/conmon", @@ -98,3 +87,15 @@ pause_command = "/pause" # Default libpod support for container labeling # label=true + +# Paths to look for a valid OCI runtime (runc, runv, etc) +[runtimes] +runc = [ + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc" +] diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go index 883ae2c76..1f3599082 100644 --- a/libpod/adapter/runtime.go +++ b/libpod/adapter/runtime.go @@ -15,8 +15,8 @@ import ( // LocalRuntime describes a typical libpod runtime type LocalRuntime struct { - Runtime *libpod.Runtime - Remote bool + *libpod.Runtime + Remote bool } // ContainerImage ... @@ -24,6 +24,11 @@ type ContainerImage struct { *image.Image } +// Container ... +type Container struct { + *libpod.Container +} + // GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it func GetRuntime(c *cli.Context) (*LocalRuntime, error) { runtime, err := libpodruntime.GetRuntime(c) @@ -85,3 +90,12 @@ func (r *LocalRuntime) New(ctx context.Context, name, signaturePolicyPath, authf func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, force bool) (string, error) { return r.Runtime.RemoveImage(ctx, img.Image, force) } + +// LookupContainer ... +func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) { + ctr, err := r.Runtime.LookupContainer(idOrName) + if err != nil { + return nil, err + } + return &Container{ctr}, nil +} diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go index 5413385d2..8ef8fe167 100644 --- a/libpod/adapter/runtime_remote.go +++ b/libpod/adapter/runtime_remote.go @@ -22,13 +22,13 @@ type RemoteImageRuntime struct{} // RemoteRuntime describes a wrapper runtime struct type RemoteRuntime struct { + Conn *varlink.Connection + Remote bool } // LocalRuntime describes a typical libpod runtime type LocalRuntime struct { - Runtime *RemoteRuntime - Remote bool - Conn *varlink.Connection + *RemoteRuntime } // GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it @@ -38,11 +38,14 @@ func GetRuntime(c *cli.Context) (*LocalRuntime, error) { if err != nil { return nil, err } - return &LocalRuntime{ - Runtime: &runtime, - Remote: true, - Conn: conn, - }, nil + rr := RemoteRuntime{ + Conn: conn, + Remote: true, + } + foo := LocalRuntime{ + &rr, + } + return &foo, nil } // Shutdown is a bogus wrapper for compat with the libpod runtime @@ -70,6 +73,30 @@ type remoteImage struct { Runtime *LocalRuntime } +// Container ... +type Container struct { + remoteContainer +} + +// remoteContainer .... +type remoteContainer struct { + ID string + Image string + ImageID string + Command []string + Created time.Time + RunningFor string + Status string + //Ports []ocicni.PortMapping + RootFsSize int64 + RWSize int64 + Names string + Labels []map[string]string + // Mounts []string + // ContainerRunning bool + //Namespaces []LinuxNameSpace +} + // GetImages returns a slice of containerimages over a varlink connection func (r *LocalRuntime) GetImages() ([]*ContainerImage, error) { var newImages []*ContainerImage @@ -213,10 +240,6 @@ func (ci *ContainerImage) TagImage(tag string) error { return err } -func (r RemoteRuntime) RemoveImage(force bool) error { - return nil -} - // RemoveImage calls varlink to remove an image func (r *LocalRuntime) RemoveImage(ctx context.Context, img *ContainerImage, force bool) (string, error) { return iopodman.RemoveImage().Call(r.Conn, img.InputName, force) @@ -246,3 +269,42 @@ func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error) } return imageHistories, nil } + +// LookupContainer gets basic information about container over a varlink +// connection and then translates it to a *Container +func (r *RemoteRuntime) LookupContainer(idOrName string) (*Container, error) { + container, err := iopodman.GetContainer().Call(r.Conn, idOrName) + if err != nil { + return nil, err + } + return listContainerDataToContainer(container) +} + +// listContainerDataToContainer takes a varlink listcontainerData struct and makes +// an "adapted" Container +func listContainerDataToContainer(listData iopodman.ListContainerData) (*Container, error) { + created, err := splitStringDate(listData.Createdat) + if err != nil { + return nil, err + } + rc := remoteContainer{ + // TODO commented out attributes will be populated when podman-remote ps + // is implemented. They are not needed yet for basic container operations. + ID: listData.Id, + Image: listData.Image, + ImageID: listData.Imageid, + Command: listData.Command, + Created: created, + RunningFor: listData.Runningfor, + Status: listData.Status, + //ports: + RootFsSize: listData.Rootfssize, + RWSize: listData.Rwsize, + Names: listData.Names, + //Labels: + //Mounts + //ContainerRunning: + //namespaces: + } + return &Container{rc}, nil +} diff --git a/libpod/container.go b/libpod/container.go index ca83bbffe..95f7a2972 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -350,6 +350,9 @@ type ContainerConfig struct { PostConfigureNetNS bool `json:"postConfigureNetNS"` + // OCIRuntime used to create the container + OCIRuntime string `json:"runtime,omitempty"` + // ExitCommand is the container's exit command. // This Command will be executed when the container exits ExitCommand []string `json:"exitCommand,omitempty"` diff --git a/libpod/info.go b/libpod/info.go index a98f93897..191ce6810 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -4,7 +4,6 @@ import ( "bufio" "bytes" "fmt" - "github.com/containers/buildah" "io/ioutil" "os" "runtime" @@ -12,6 +11,7 @@ import ( "strings" "time" + "github.com/containers/buildah" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" @@ -184,12 +184,12 @@ func (r *Runtime) GetConmonVersion() (string, error) { // GetOCIRuntimePath returns the path to the OCI Runtime Path the runtime is using func (r *Runtime) GetOCIRuntimePath() string { - return r.ociRuntimePath + return r.ociRuntimePath.Paths[0] } // GetOCIRuntimeVersion returns a string representation of the oci runtimes version func (r *Runtime) GetOCIRuntimeVersion() (string, error) { - output, err := utils.ExecCmd(r.ociRuntimePath, "--version") + output, err := utils.ExecCmd(r.ociRuntimePath.Paths[0], "--version") if err != nil { return "", err } diff --git a/libpod/oci.go b/libpod/oci.go index 7a908db2e..4092657f8 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -75,10 +75,10 @@ type syncInfo struct { } // Make a new OCI runtime with provided options -func newOCIRuntime(name string, path string, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool) (*OCIRuntime, error) { +func newOCIRuntime(oruntime OCIRuntimePath, conmonPath string, conmonEnv []string, cgroupManager string, tmpDir string, logSizeMax int64, noPivotRoot bool, reservePorts bool) (*OCIRuntime, error) { runtime := new(OCIRuntime) - runtime.name = name - runtime.path = path + runtime.name = oruntime.Name + runtime.path = oruntime.Paths[0] runtime.conmonPath = conmonPath runtime.conmonEnv = conmonEnv runtime.cgroupManager = cgroupManager diff --git a/libpod/options.go b/libpod/options.go index 319e1f6c6..d965c058e 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -137,17 +137,17 @@ func WithStateType(storeType RuntimeStateStore) RuntimeOption { } // WithOCIRuntime specifies an OCI runtime to use for running containers. -func WithOCIRuntime(runtimePath string) RuntimeOption { +func WithOCIRuntime(runtime string) RuntimeOption { return func(rt *Runtime) error { if rt.valid { return ErrRuntimeFinalized } - if runtimePath == "" { + if runtime == "" { return errors.Wrapf(ErrInvalidArg, "must provide a valid path") } - rt.config.RuntimePath = []string{runtimePath} + rt.config.OCIRuntime = runtime return nil } diff --git a/libpod/runtime.go b/libpod/runtime.go index c9471247c..5ff8b30f6 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -86,7 +86,7 @@ type Runtime struct { imageContext *types.SystemContext ociRuntime *OCIRuntime netPlugin ocicni.CNIPlugin - ociRuntimePath string + ociRuntimePath OCIRuntimePath conmonPath string valid bool lock sync.RWMutex @@ -96,6 +96,14 @@ type Runtime struct { configuredFrom *runtimeConfiguredFrom } +// OCIRuntimePath contains information about an OCI runtime. +type OCIRuntimePath struct { + // Name of the runtime to refer to by the --runtime flag + Name string `toml:"name"` + // Paths to check for this executable + Paths []string `toml:"paths"` +} + // RuntimeConfig contains configuration options used to set up the runtime type RuntimeConfig struct { // StorageConfig is the configuration used by containers/storage @@ -118,10 +126,10 @@ type RuntimeConfig struct { // cause conflicts in containers/storage // As such this is not exposed via the config file StateType RuntimeStateStore `toml:"-"` - // RuntimePath is the path to OCI runtime binary for launching - // containers - // The first path pointing to a valid file will be used - RuntimePath []string `toml:"runtime_path"` + // OCIRuntime is the OCI runtime to use. + OCIRuntime string `toml:"runtime"` + // OCIRuntimes are the set of configured OCI runtimes (default is runc) + OCIRuntimes map[string][]string `toml:"runtimes"` // ConmonPath is the path to the Conmon binary used for managing // containers // The first path pointing to a valid file will be used @@ -213,14 +221,17 @@ var ( StorageConfig: storage.StoreOptions{}, ImageDefaultTransport: DefaultTransport, StateType: BoltDBStateStore, - RuntimePath: []string{ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc", + OCIRuntime: "runc", + OCIRuntimes: map[string][]string{ + "runc": { + "/usr/bin/runc", + "/usr/sbin/runc", + "/usr/local/bin/runc", + "/usr/local/sbin/runc", + "/sbin/runc", + "/bin/runc", + "/usr/lib/cri-o-runc/sbin/runc", + }, }, ConmonPath: []string{ "/usr/libexec/podman/conmon", @@ -414,8 +425,9 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime runtime.config = new(RuntimeConfig) runtime.configuredFrom = new(runtimeConfiguredFrom) - // Set two fields not in the TOML config + // Set three fields not in the TOML config runtime.config.StateType = defaultRuntimeConfig.StateType + runtime.config.OCIRuntime = defaultRuntimeConfig.OCIRuntime runtime.config.StorageConfig = storage.StoreOptions{} // Check to see if the given configuration file exists @@ -453,22 +465,35 @@ func NewRuntimeFromConfig(configPath string, options ...RuntimeOption) (runtime func makeRuntime(runtime *Runtime) (err error) { // Find a working OCI runtime binary foundRuntime := false - for _, path := range runtime.config.RuntimePath { - stat, err := os.Stat(path) - if err != nil { - continue - } - if stat.IsDir() { - continue - } + // If runtime is an absolute path, then use it as it is. + if runtime.config.OCIRuntime[0] == '/' { foundRuntime = true - runtime.ociRuntimePath = path - break + runtime.ociRuntimePath = OCIRuntimePath{Name: filepath.Base(runtime.config.OCIRuntime), Paths: []string{runtime.config.OCIRuntime}} + } else { + // If not, look it up in the configuration. + paths := runtime.config.OCIRuntimes[runtime.config.OCIRuntime] + if paths != nil { + for _, path := range paths { + stat, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + continue + } + return errors.Wrapf(err, "cannot stat %s", path) + } + if !stat.Mode().IsRegular() { + continue + } + foundRuntime = true + runtime.ociRuntimePath = OCIRuntimePath{Name: runtime.config.OCIRuntime, Paths: []string{path}} + break + } + } } if !foundRuntime { return errors.Wrapf(ErrInvalidArg, "could not find a working binary (configured options: %v)", - runtime.config.RuntimePath) + runtime.config.OCIRuntimes) } // Find a working conmon binary @@ -619,7 +644,7 @@ func makeRuntime(runtime *Runtime) (err error) { } // Make an OCI runtime to perform container operations - ociRuntime, err := newOCIRuntime("runc", runtime.ociRuntimePath, + ociRuntime, err := newOCIRuntime(runtime.ociRuntimePath, runtime.conmonPath, runtime.config.ConmonEnvVars, runtime.config.CgroupManager, runtime.config.TmpDir, runtime.config.MaxLogSize, runtime.config.NoPivotRoot, diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index ab79fe5fb..68599fe6d 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -62,6 +62,8 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.config.StopTimeout = CtrRemoveTimeout + ctr.config.OCIRuntime = r.config.OCIRuntime + // Set namespace based on current runtime namespace // Do so before options run so they can override it if r.config.Namespace != "" { diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 1d28ff68d..279a03d3f 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -70,9 +70,12 @@ get_cmd_line_args (pid_t pid) if (allocated == used) { allocated += 512; - buffer = realloc (buffer, allocated); - if (buffer == NULL) - return NULL; + char *tmp = realloc (buffer, allocated); + if (buffer == NULL) { + free(buffer); + return NULL; + } + buffer=tmp; } } close (fd); |