summaryrefslogtreecommitdiff
path: root/pkg/varlinkapi
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-05-16 12:38:17 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-05-21 19:26:56 +0000
commit82feafecdda8040432c008d9b79e4f973009adfc (patch)
tree8edffbe531bcf47c40b34cd003e4063142fbc84f /pkg/varlinkapi
parent687b165a737742e1f1930cd9782002d857e07aaf (diff)
downloadpodman-82feafecdda8040432c008d9b79e4f973009adfc.tar.gz
podman-82feafecdda8040432c008d9b79e4f973009adfc.tar.bz2
podman-82feafecdda8040432c008d9b79e4f973009adfc.zip
podman create, start, getattachsocket
First pass at implement API endpoints for create and start. Signed-off-by: baude <bbaude@redhat.com> Closes: #805 Approved by: baude
Diffstat (limited to 'pkg/varlinkapi')
-rw-r--r--pkg/varlinkapi/containers.go45
-rw-r--r--pkg/varlinkapi/containers_create.go243
2 files changed, 281 insertions, 7 deletions
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 9468719fc..43ab3c995 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -67,11 +67,6 @@ func (i *LibpodAPI) GetContainer(call ioprojectatomicpodman.VarlinkCall, name st
return call.ReplyGetContainer(makeListContainer(ctr.ID(), batchInfo))
}
-// CreateContainer ...
-func (i *LibpodAPI) CreateContainer(call ioprojectatomicpodman.VarlinkCall) error {
- return call.ReplyMethodNotImplemented("CreateContainer")
-}
-
// InspectContainer ...
func (i *LibpodAPI) InspectContainer(call ioprojectatomicpodman.VarlinkCall, name string) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
@@ -264,8 +259,26 @@ func (i *LibpodAPI) ResizeContainerTty(call ioprojectatomicpodman.VarlinkCall) e
}
// StartContainer ...
-func (i *LibpodAPI) StartContainer(call ioprojectatomicpodman.VarlinkCall) error {
- return call.ReplyMethodNotImplemented("StartContainer")
+func (i *LibpodAPI) StartContainer(call ioprojectatomicpodman.VarlinkCall, name string) error {
+ runtime, err := libpodruntime.GetRuntime(i.Cli)
+ if err != nil {
+ return call.ReplyRuntimeError(err.Error())
+ }
+ ctr, err := runtime.LookupContainer(name)
+ if err != nil {
+ return call.ReplyContainerNotFound(name)
+ }
+ state, err := ctr.State()
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ if state == libpod.ContainerStateRunning || state == libpod.ContainerStatePaused {
+ return call.ReplyErrorOccurred("container is alrady running or paused")
+ }
+ if err := ctr.Start(getContext()); err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyStartContainer(ctr.ID())
}
// StopContainer ...
@@ -429,3 +442,21 @@ func (i *LibpodAPI) DeleteStoppedContainers(call ioprojectatomicpodman.VarlinkCa
}
return call.ReplyDeleteStoppedContainers(deletedContainers)
}
+
+// GetAttachSockets ...
+func (i *LibpodAPI) GetAttachSockets(call ioprojectatomicpodman.VarlinkCall, name string) error {
+ runtime, err := libpodruntime.GetRuntime(i.Cli)
+ if err != nil {
+ return call.ReplyRuntimeError(err.Error())
+ }
+ ctr, err := runtime.LookupContainer(name)
+ if err != nil {
+ return call.ReplyContainerNotFound(name)
+ }
+ s := ioprojectatomicpodman.Sockets{
+ Container_id: ctr.ID(),
+ Io_socket: ctr.AttachSocketPath(),
+ Control_socket: ctr.ControlSocketPath(),
+ }
+ return call.ReplyGetAttachSockets(s)
+}
diff --git a/pkg/varlinkapi/containers_create.go b/pkg/varlinkapi/containers_create.go
new file mode 100644
index 000000000..77799cb8d
--- /dev/null
+++ b/pkg/varlinkapi/containers_create.go
@@ -0,0 +1,243 @@
+package varlinkapi
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "os"
+ "strings"
+ "syscall"
+
+ "github.com/docker/docker/api/types/container"
+ "github.com/docker/docker/pkg/signal"
+ "github.com/projectatomic/libpod/cmd/podman/libpodruntime"
+ "github.com/projectatomic/libpod/cmd/podman/varlink"
+ "github.com/projectatomic/libpod/libpod"
+ "github.com/projectatomic/libpod/libpod/image"
+ "github.com/projectatomic/libpod/pkg/inspect"
+ cc "github.com/projectatomic/libpod/pkg/spec"
+ "github.com/projectatomic/libpod/pkg/util"
+ "github.com/sirupsen/logrus"
+)
+
+// CreateContainer ...
+func (i *LibpodAPI) CreateContainer(call ioprojectatomicpodman.VarlinkCall, config ioprojectatomicpodman.Create) error {
+ //mappings, err := util.ParseIDMapping(config.Uidmap, config.Gidmap, config.Subuidmap, config.Subgidmap)
+ //if err != nil {
+ // return err
+ //}
+ //storageOpts := storage.DefaultStoreOptions
+ //storageOpts.UIDMap = mappings.UIDMap
+ //storageOpts.GIDMap = mappings.GIDMap
+
+ runtime, err := libpodruntime.GetRuntime(i.Cli)
+ if err != nil {
+ return call.ReplyRuntimeError(err.Error())
+ }
+ defer runtime.Shutdown(false)
+
+ rtc := runtime.GetConfig()
+ ctx := getContext()
+
+ newImage, err := runtime.ImageRuntime().New(ctx, config.Image, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{}, false, false)
+ if err != nil {
+ return err
+ }
+ data, err := newImage.Inspect(ctx)
+
+ createConfig, err := varlinkCreateToCreateConfig(ctx, config, runtime, config.Image, data)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ useImageVolumes := createConfig.ImageVolumeType == "bind"
+
+ runtimeSpec, err := cc.CreateConfigToOCISpec(createConfig)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ options, err := createConfig.GetContainerCreateOptions()
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ // Gather up the options for NewContainer which consist of With... funcs
+ options = append(options, libpod.WithRootFSFromImage(createConfig.ImageID, createConfig.Image, useImageVolumes))
+ options = append(options, libpod.WithSELinuxLabels(createConfig.ProcessLabel, createConfig.MountLabel))
+ options = append(options, libpod.WithConmonPidFile(createConfig.ConmonPidFile))
+ options = append(options, libpod.WithLabels(createConfig.Labels))
+ options = append(options, libpod.WithUser(createConfig.User))
+ options = append(options, libpod.WithShmDir(createConfig.ShmDir))
+ options = append(options, libpod.WithShmSize(createConfig.Resources.ShmSize))
+ options = append(options, libpod.WithGroups(createConfig.GroupAdd))
+ options = append(options, libpod.WithIDMappings(*createConfig.IDMappings))
+ ctr, err := runtime.NewContainer(ctx, runtimeSpec, options...)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ createConfigJSON, err := json.Marshal(createConfig)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ if err := ctr.AddArtifact("create-config", createConfigJSON); err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
+ logrus.Debug("new container created ", ctr.ID())
+
+ return call.ReplyCreateContainer(ctr.ID())
+}
+
+// varlinkCreateToCreateConfig takes the varlink input struct and maps it to a pointer
+// of a CreateConfig, which eventually can be used to create the OCI spec.
+func varlinkCreateToCreateConfig(ctx context.Context, create ioprojectatomicpodman.Create, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) {
+ var (
+ inputCommand, command []string
+ memoryLimit, memoryReservation, memorySwap, memoryKernel int64
+ blkioWeight uint16
+ )
+
+ idmappings, err := util.ParseIDMapping(create.Uidmap, create.Gidmap, create.Subuidname, create.Subgidname)
+ if err != nil {
+ return nil, err
+ }
+ inputCommand = create.Command
+ entrypoint := create.Entrypoint
+
+ // ENTRYPOINT
+ // User input entrypoint takes priority over image entrypoint
+ if len(entrypoint) == 0 {
+ entrypoint = data.ContainerConfig.Entrypoint
+ }
+ // if entrypoint=, we need to clear the entrypoint
+ if len(entrypoint) == 1 && strings.Join(create.Entrypoint, "") == "" {
+ entrypoint = []string{}
+ }
+ // Build the command
+ // If we have an entry point, it goes first
+ if len(entrypoint) > 0 {
+ command = entrypoint
+ }
+ if len(inputCommand) > 0 {
+ // User command overrides data CMD
+ command = append(command, inputCommand...)
+ } else if len(data.ContainerConfig.Cmd) > 0 && len(create.Entrypoint) > 0 {
+ // If not user command, add CMD
+ command = append(command, data.ContainerConfig.Cmd...)
+ }
+
+ if create.Resources.Blkio_weight != 0 {
+ blkioWeight = uint16(create.Resources.Blkio_weight)
+ }
+
+ stopSignal := syscall.SIGTERM
+ if create.Stop_signal > 0 {
+ stopSignal, err = signal.ParseSignal(fmt.Sprintf("%d", create.Stop_signal))
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ user := create.User
+ if user == "" {
+ user = data.ContainerConfig.User
+ }
+
+ // EXPOSED PORTS
+ portBindings, err := cc.ExposedPorts(create.Exposed_ports, create.Publish, create.Publish_all, data.ContainerConfig.ExposedPorts)
+ if err != nil {
+ return nil, err
+ }
+
+ // NETWORK MODE
+ networkMode := create.Net_mode
+ if networkMode == "" {
+ networkMode = "bridge"
+ }
+
+ // WORKING DIR
+ workDir := create.Work_dir
+ if workDir == "" {
+ workDir = "/"
+ }
+
+ imageID := data.ID
+ config := &cc.CreateConfig{
+ Runtime: runtime,
+ BuiltinImgVolumes: data.ContainerConfig.Volumes,
+ ConmonPidFile: create.Conmon_pidfile,
+ ImageVolumeType: create.Image_volume_type,
+ CapAdd: create.Cap_add,
+ CapDrop: create.Cap_drop,
+ CgroupParent: create.Cgroup_parent,
+ Command: command,
+ Detach: create.Detach,
+ Devices: create.Devices,
+ DNSOpt: create.Dns_opt,
+ DNSSearch: create.Dns_search,
+ DNSServers: create.Dns_servers,
+ Entrypoint: create.Entrypoint,
+ Env: create.Env,
+ GroupAdd: create.Group_add,
+ Hostname: create.Hostname,
+ HostAdd: create.Host_add,
+ IDMappings: idmappings,
+ Image: imageName,
+ ImageID: imageID,
+ Interactive: create.Interactive,
+ Labels: create.Labels,
+ LogDriver: create.Log_driver,
+ LogDriverOpt: create.Log_driver_opt,
+ Name: create.Name,
+ Network: networkMode,
+ IpcMode: container.IpcMode(create.Ipc_mode),
+ NetMode: container.NetworkMode(networkMode),
+ UtsMode: container.UTSMode(create.Uts_mode),
+ PidMode: container.PidMode(create.Pid_mode),
+ Pod: create.Pod,
+ Privileged: create.Privileged,
+ Publish: create.Publish,
+ PublishAll: create.Publish_all,
+ PortBindings: portBindings,
+ Quiet: create.Quiet,
+ ReadOnlyRootfs: create.Readonly_rootfs,
+ Resources: cc.CreateResourceConfig{
+ BlkioWeight: blkioWeight,
+ BlkioWeightDevice: create.Resources.Blkio_weight_device,
+ CPUShares: uint64(create.Resources.Cpu_shares),
+ CPUPeriod: uint64(create.Resources.Cpu_period),
+ CPUsetCPUs: create.Resources.Cpuset_cpus,
+ CPUsetMems: create.Resources.Cpuset_mems,
+ CPUQuota: create.Resources.Cpu_quota,
+ CPURtPeriod: uint64(create.Resources.Cpu_rt_period),
+ CPURtRuntime: create.Resources.Cpu_rt_runtime,
+ CPUs: create.Resources.Cpus,
+ DeviceReadBps: create.Resources.Device_read_bps,
+ DeviceReadIOps: create.Resources.Device_write_bps,
+ DeviceWriteBps: create.Resources.Device_read_iops,
+ DeviceWriteIOps: create.Resources.Device_write_iops,
+ DisableOomKiller: create.Resources.Disable_oomkiller,
+ ShmSize: create.Resources.Shm_size,
+ Memory: memoryLimit,
+ MemoryReservation: memoryReservation,
+ MemorySwap: memorySwap,
+ MemorySwappiness: int(create.Resources.Memory_swappiness),
+ KernelMemory: memoryKernel,
+ OomScoreAdj: int(create.Resources.Oom_score_adj),
+ PidsLimit: create.Resources.Pids_limit,
+ Ulimit: create.Resources.Ulimit,
+ },
+ Rm: create.Rm,
+ ShmDir: create.Shm_dir,
+ StopSignal: stopSignal,
+ StopTimeout: uint(create.Stop_timeout),
+ Sysctl: create.Sys_ctl,
+ Tmpfs: create.Tmpfs,
+ Tty: create.Tty,
+ User: user,
+ UsernsMode: container.UsernsMode(create.Userns_mode),
+ Volumes: create.Volumes,
+ WorkDir: workDir,
+ }
+
+ return config, nil
+}