mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00

iFix builtin volumes to work with podman volume Currently builtin volumes are not recored in podman volumes when they are created automatically. This patch fixes this. Remove container volumes when requested Currently the --volume option on podman remove does nothing. This will implement the changes needed to remove the volumes if the user requests it. When removing a volume make sure that no container uses the volume. Signed-off-by: Daniel J Walsh dwalsh@redhat.com Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
218 lines
7.1 KiB
Go
218 lines
7.1 KiB
Go
package varlinkapi
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/containers/libpod/cmd/podman/varlink"
|
|
"github.com/containers/libpod/libpod"
|
|
"github.com/containers/libpod/libpod/image"
|
|
"github.com/containers/libpod/pkg/inspect"
|
|
"github.com/containers/libpod/pkg/namespaces"
|
|
"github.com/containers/libpod/pkg/rootless"
|
|
cc "github.com/containers/libpod/pkg/spec"
|
|
"github.com/containers/libpod/pkg/util"
|
|
"github.com/docker/docker/pkg/signal"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// CreateContainer ...
|
|
func (i *LibpodAPI) CreateContainer(call iopodman.VarlinkCall, config iopodman.Create) error {
|
|
rtc := i.Runtime.GetConfig()
|
|
ctx := getContext()
|
|
|
|
newImage, err := i.Runtime.ImageRuntime().New(ctx, config.Image, rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{}, false, nil)
|
|
if err != nil {
|
|
return call.ReplyErrorOccurred(err.Error())
|
|
}
|
|
data, err := newImage.Inspect(ctx)
|
|
|
|
createConfig, err := varlinkCreateToCreateConfig(ctx, config, i.Runtime, config.Image, data)
|
|
if err != nil {
|
|
return call.ReplyErrorOccurred(err.Error())
|
|
}
|
|
|
|
runtimeSpec, err := cc.CreateConfigToOCISpec(createConfig)
|
|
if err != nil {
|
|
return call.ReplyErrorOccurred(err.Error())
|
|
}
|
|
|
|
// TODO fix when doing remote client and dealing with the ability to create a container
|
|
// within a non-existing pod (i.e. --pod new:foobar)
|
|
options, err := createConfig.GetContainerCreateOptions(i.Runtime, nil)
|
|
if err != nil {
|
|
return call.ReplyErrorOccurred(err.Error())
|
|
}
|
|
|
|
ctr, err := i.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 iopodman.Create, runtime *libpod.Runtime, imageName string, data *inspect.ImageData) (*cc.CreateConfig, error) {
|
|
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.Config.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
|
|
command := entrypoint
|
|
if len(inputCommand) > 0 {
|
|
// User command overrides data CMD
|
|
command = append(command, inputCommand...)
|
|
} else if len(data.Config.Cmd) > 0 && len(command) == 0 {
|
|
// If not user command, add CMD
|
|
command = append(command, data.Config.Cmd...)
|
|
}
|
|
|
|
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.Config.User
|
|
}
|
|
|
|
// EXPOSED PORTS
|
|
portBindings, err := cc.ExposedPorts(create.Exposed_ports, create.Publish, create.Publish_all, data.Config.ExposedPorts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// NETWORK MODE
|
|
networkMode := create.Net_mode
|
|
if networkMode == "" {
|
|
if rootless.IsRootless() {
|
|
networkMode = "slirp4netns"
|
|
} else {
|
|
networkMode = "bridge"
|
|
}
|
|
}
|
|
|
|
// WORKING DIR
|
|
workDir := create.Work_dir
|
|
if workDir == "" {
|
|
workDir = "/"
|
|
}
|
|
|
|
imageID := data.ID
|
|
var ImageVolumes map[string]struct{}
|
|
if data != nil && create.Image_volume_type != "ignore" {
|
|
ImageVolumes = data.Config.Volumes
|
|
}
|
|
|
|
config := &cc.CreateConfig{
|
|
Runtime: runtime,
|
|
BuiltinImgVolumes: ImageVolumes,
|
|
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: namespaces.IpcMode(create.Ipc_mode),
|
|
NetMode: namespaces.NetworkMode(networkMode),
|
|
UtsMode: namespaces.UTSMode(create.Uts_mode),
|
|
PidMode: namespaces.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: uint16(create.Resources.Blkio_weight),
|
|
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: create.Resources.Memory,
|
|
MemoryReservation: create.Resources.Memory_reservation,
|
|
MemorySwap: create.Resources.Memory_swap,
|
|
MemorySwappiness: int(create.Resources.Memory_swappiness),
|
|
KernelMemory: create.Resources.Kernel_memory,
|
|
OomScoreAdj: int(create.Resources.Oom_score_adj),
|
|
PidsLimit: create.Resources.Pids_limit,
|
|
Ulimit: create.Resources.Ulimit,
|
|
},
|
|
Rm: create.Rm,
|
|
StopSignal: stopSignal,
|
|
StopTimeout: uint(create.Stop_timeout),
|
|
Sysctl: create.Sys_ctl,
|
|
Tmpfs: create.Tmpfs,
|
|
Tty: create.Tty,
|
|
User: user,
|
|
UsernsMode: namespaces.UsernsMode(create.Userns_mode),
|
|
Volumes: create.Volumes,
|
|
WorkDir: workDir,
|
|
}
|
|
|
|
return config, nil
|
|
}
|