mirror of
https://github.com/containers/podman.git
synced 2025-06-16 22:57:06 +08:00
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
This commit is contained in:
243
pkg/varlinkapi/containers_create.go
Normal file
243
pkg/varlinkapi/containers_create.go
Normal file
@ -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
|
||||
}
|
Reference in New Issue
Block a user