mirror of
https://github.com/containers/podman.git
synced 2025-05-20 00:27:03 +08:00

vendor in c/common config pkg for containers.conf Signed-off-by: Qi Wang qiwan@redhat.com Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
222 lines
6.9 KiB
Go
222 lines
6.9 KiB
Go
package compat
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/containers/common/pkg/config"
|
|
"github.com/containers/libpod/libpod"
|
|
image2 "github.com/containers/libpod/libpod/image"
|
|
"github.com/containers/libpod/pkg/api/handlers"
|
|
"github.com/containers/libpod/pkg/api/handlers/utils"
|
|
"github.com/containers/libpod/pkg/namespaces"
|
|
"github.com/containers/libpod/pkg/signal"
|
|
createconfig "github.com/containers/libpod/pkg/spec"
|
|
"github.com/containers/storage"
|
|
"github.com/gorilla/schema"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
|
input := handlers.CreateContainerConfig{}
|
|
query := struct {
|
|
Name string `schema:"name"`
|
|
}{
|
|
// override any golang type defaults
|
|
}
|
|
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
|
|
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
|
|
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
|
|
return
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
|
|
return
|
|
}
|
|
if len(input.HostConfig.Links) > 0 {
|
|
utils.Error(w, utils.ErrLinkNotSupport.Error(), http.StatusBadRequest, errors.Wrapf(utils.ErrLinkNotSupport, "bad parameter"))
|
|
}
|
|
newImage, err := runtime.ImageRuntime().NewFromLocal(input.Image)
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()"))
|
|
return
|
|
}
|
|
defaultContainerConfig, err := runtime.GetConfig()
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "GetConfig()"))
|
|
return
|
|
}
|
|
cc, err := makeCreateConfig(defaultContainerConfig, input, newImage)
|
|
if err != nil {
|
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "makeCreatConfig()"))
|
|
return
|
|
}
|
|
cc.Name = query.Name
|
|
utils.CreateContainer(r.Context(), w, runtime, &cc)
|
|
}
|
|
|
|
func makeCreateConfig(defaultContainerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) {
|
|
var (
|
|
err error
|
|
init bool
|
|
tmpfs []string
|
|
volumes []string
|
|
)
|
|
env := make(map[string]string)
|
|
stopSignal := unix.SIGTERM
|
|
if len(input.StopSignal) > 0 {
|
|
stopSignal, err = signal.ParseSignal(input.StopSignal)
|
|
if err != nil {
|
|
return createconfig.CreateConfig{}, err
|
|
}
|
|
}
|
|
|
|
workDir := "/"
|
|
if len(input.WorkingDir) > 0 {
|
|
workDir = input.WorkingDir
|
|
}
|
|
|
|
stopTimeout := defaultContainerConfig.Engine.StopTimeout
|
|
if input.StopTimeout != nil {
|
|
stopTimeout = uint(*input.StopTimeout)
|
|
}
|
|
c := createconfig.CgroupConfig{
|
|
Cgroups: "", // podman
|
|
Cgroupns: "", // podman
|
|
CgroupParent: "", // podman
|
|
CgroupMode: "", // podman
|
|
}
|
|
security := createconfig.SecurityConfig{
|
|
CapAdd: input.HostConfig.CapAdd,
|
|
CapDrop: input.HostConfig.CapDrop,
|
|
LabelOpts: nil, // podman
|
|
NoNewPrivs: false, // podman
|
|
ApparmorProfile: "", // podman
|
|
SeccompProfilePath: "",
|
|
SecurityOpts: input.HostConfig.SecurityOpt,
|
|
Privileged: input.HostConfig.Privileged,
|
|
ReadOnlyRootfs: input.HostConfig.ReadonlyRootfs,
|
|
ReadOnlyTmpfs: false, // podman-only
|
|
Sysctl: input.HostConfig.Sysctls,
|
|
}
|
|
|
|
network := createconfig.NetworkConfig{
|
|
DNSOpt: input.HostConfig.DNSOptions,
|
|
DNSSearch: input.HostConfig.DNSSearch,
|
|
DNSServers: input.HostConfig.DNS,
|
|
ExposedPorts: input.ExposedPorts,
|
|
HTTPProxy: false, // podman
|
|
IP6Address: "",
|
|
IPAddress: "",
|
|
LinkLocalIP: nil, // docker-only
|
|
MacAddress: input.MacAddress,
|
|
// NetMode: nil,
|
|
Network: input.HostConfig.NetworkMode.NetworkName(),
|
|
NetworkAlias: nil, // docker-only now
|
|
PortBindings: input.HostConfig.PortBindings,
|
|
Publish: nil, // podmanseccompPath
|
|
PublishAll: input.HostConfig.PublishAllPorts,
|
|
}
|
|
|
|
uts := createconfig.UtsConfig{
|
|
UtsMode: namespaces.UTSMode(input.HostConfig.UTSMode),
|
|
NoHosts: false, //podman
|
|
HostAdd: input.HostConfig.ExtraHosts,
|
|
Hostname: input.Hostname,
|
|
}
|
|
|
|
z := createconfig.UserConfig{
|
|
GroupAdd: input.HostConfig.GroupAdd,
|
|
IDMappings: &storage.IDMappingOptions{}, // podman //TODO <--- fix this,
|
|
UsernsMode: namespaces.UsernsMode(input.HostConfig.UsernsMode),
|
|
User: input.User,
|
|
}
|
|
pidConfig := createconfig.PidConfig{PidMode: namespaces.PidMode(input.HostConfig.PidMode)}
|
|
for k := range input.Volumes {
|
|
volumes = append(volumes, k)
|
|
}
|
|
|
|
// Docker is more flexible about its input where podman throws
|
|
// away incorrectly formatted variables so we cannot reuse the
|
|
// parsing of the env input
|
|
// [Foo Other=one Blank=]
|
|
for _, e := range input.Env {
|
|
splitEnv := strings.Split(e, "=")
|
|
switch len(splitEnv) {
|
|
case 0:
|
|
continue
|
|
case 1:
|
|
env[splitEnv[0]] = ""
|
|
default:
|
|
env[splitEnv[0]] = strings.Join(splitEnv[1:], "=")
|
|
}
|
|
}
|
|
|
|
// format the tmpfs mounts into a []string from map
|
|
for k, v := range input.HostConfig.Tmpfs {
|
|
tmpfs = append(tmpfs, fmt.Sprintf("%s:%s", k, v))
|
|
}
|
|
|
|
if input.HostConfig.Init != nil && *input.HostConfig.Init {
|
|
init = true
|
|
}
|
|
|
|
m := createconfig.CreateConfig{
|
|
Annotations: nil, // podman
|
|
Args: nil,
|
|
Cgroup: c,
|
|
CidFile: "",
|
|
ConmonPidFile: "", // podman
|
|
Command: input.Cmd,
|
|
UserCommand: input.Cmd, // podman
|
|
Detach: false, //
|
|
// Devices: input.HostConfig.Devices,
|
|
Entrypoint: input.Entrypoint,
|
|
Env: env,
|
|
HealthCheck: nil, //
|
|
Init: init,
|
|
InitPath: "", // tbd
|
|
Image: input.Image,
|
|
ImageID: newImage.ID(),
|
|
BuiltinImgVolumes: nil, // podman
|
|
ImageVolumeType: "", // podman
|
|
Interactive: false,
|
|
// IpcMode: input.HostConfig.IpcMode,
|
|
Labels: input.Labels,
|
|
LogDriver: input.HostConfig.LogConfig.Type, // is this correct
|
|
// LogDriverOpt: input.HostConfig.LogConfig.Config,
|
|
Name: input.Name,
|
|
Network: network,
|
|
Pod: "", // podman
|
|
PodmanPath: "", // podman
|
|
Quiet: false, // front-end only
|
|
Resources: createconfig.CreateResourceConfig{},
|
|
RestartPolicy: input.HostConfig.RestartPolicy.Name,
|
|
Rm: input.HostConfig.AutoRemove,
|
|
StopSignal: stopSignal,
|
|
StopTimeout: stopTimeout,
|
|
Systemd: false, // podman
|
|
Tmpfs: tmpfs,
|
|
User: z,
|
|
Uts: uts,
|
|
Tty: input.Tty,
|
|
Mounts: nil, // we populate
|
|
// MountsFlag: input.HostConfig.Mounts,
|
|
NamedVolumes: nil, // we populate
|
|
Volumes: volumes,
|
|
VolumesFrom: input.HostConfig.VolumesFrom,
|
|
WorkDir: workDir,
|
|
Rootfs: "", // podman
|
|
Security: security,
|
|
Syslog: false, // podman
|
|
|
|
Pid: pidConfig,
|
|
}
|
|
return m, nil
|
|
}
|