summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers_create.go237
-rw-r--r--pkg/api/handlers/compat/containers_logs.go6
-rw-r--r--pkg/api/handlers/compat/networks.go3
-rw-r--r--pkg/spec/security.go2
-rw-r--r--pkg/spec/storage.go6
-rw-r--r--pkg/specgen/generate/oci.go2
-rw-r--r--pkg/util/utils.go4
7 files changed, 34 insertions, 226 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 8a0b3c922..87c95a24c 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -1,27 +1,19 @@
package compat
import (
- "context"
"encoding/json"
- "fmt"
"net/http"
- "strings"
- "github.com/containers/common/pkg/config"
+ "github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
- image2 "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
- "github.com/containers/podman/v2/pkg/namespaces"
- "github.com/containers/podman/v2/pkg/rootless"
- "github.com/containers/podman/v2/pkg/signal"
- createconfig "github.com/containers/podman/v2/pkg/spec"
+ "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
"github.com/containers/podman/v2/pkg/specgen"
- "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) {
@@ -56,220 +48,27 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "NewFromLocal()"))
return
}
- containerConfig, err := runtime.GetConfig()
+
+ // Take input structure and convert to cliopts
+ cliOpts, args, err := common.ContainerCreateToContainerCLIOpts(input)
if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "GetConfig()"))
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()"))
return
}
- cc, err := makeCreateConfig(r.Context(), containerConfig, input, newImage)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "makeCreatConfig()"))
+ sg := specgen.NewSpecGenerator(newImage.ID(), cliOpts.RootFS)
+ if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
return
}
- cc.Name = query.Name
- utils.CreateContainer(r.Context(), w, runtime, &cc)
-}
-
-func makeCreateConfig(ctx context.Context, containerConfig *config.Config, input handlers.CreateContainerConfig, newImage *image2.Image) (createconfig.CreateConfig, error) {
- var (
- err error
- init bool
- )
- 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, err := newImage.WorkingDir(ctx)
+ ic := abi.ContainerEngine{Libpod: runtime}
+ report, err := ic.ContainerCreate(r.Context(), sg)
if err != nil {
- return createconfig.CreateConfig{}, err
- }
- if workDir == "" {
- workDir = "/"
- }
- if len(input.WorkingDir) > 0 {
- workDir = input.WorkingDir
- }
-
- // Only use image's Cmd when the user does not set the entrypoint
- if input.Entrypoint == nil && len(input.Cmd) == 0 {
- cmdSlice, err := newImage.Cmd(ctx)
- if err != nil {
- return createconfig.CreateConfig{}, err
- }
- input.Cmd = cmdSlice
- }
-
- if input.Entrypoint == nil {
- entrypointSlice, err := newImage.Entrypoint(ctx)
- if err != nil {
- return createconfig.CreateConfig{}, err
- }
- input.Entrypoint = entrypointSlice
- }
-
- stopTimeout := containerConfig.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,
- }
-
- var netmode namespaces.NetworkMode
- if rootless.IsRootless() {
- netmode = namespaces.NetworkMode(specgen.Slirp)
- }
-
- 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: netmode,
- 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)}
- // TODO: We should check that these binds are all listed in the `Volumes`
- // key since it doesn't make sense to define a `Binds` element for a
- // container path which isn't defined as a volume
- volumes := input.HostConfig.Binds
-
- // 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=]
- imgEnv, err := newImage.Env(ctx)
- if err != nil {
- return createconfig.CreateConfig{}, err
- }
- input.Env = append(imgEnv, input.Env...)
- 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
- tmpfs := make([]string, 0, len(input.HostConfig.Tmpfs))
- 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: input.OpenStdin,
- // 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{MemorySwappiness: -1},
- 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,
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "container create"))
+ return
}
-
- fullCmd := append(input.Entrypoint, input.Cmd...)
- if len(fullCmd) > 0 {
- m.PodmanPath = fullCmd[0]
- if len(fullCmd) == 1 {
- m.Args = fullCmd
- } else {
- m.Args = fullCmd[1:]
- }
+ createResponse := entities.ContainerCreateResponse{
+ ID: report.Id,
+ Warnings: []string{},
}
-
- return m, nil
+ utils.WriteResponse(w, http.StatusCreated, createResponse)
}
diff --git a/pkg/api/handlers/compat/containers_logs.go b/pkg/api/handlers/compat/containers_logs.go
index faab66fe7..38a6329b9 100644
--- a/pkg/api/handlers/compat/containers_logs.go
+++ b/pkg/api/handlers/compat/containers_logs.go
@@ -148,7 +148,13 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
frame.WriteString(line.Time.Format(time.RFC3339))
frame.WriteString(" ")
}
+
frame.WriteString(line.Msg)
+ // Log lines in the compat layer require adding EOL
+ // https://github.com/containers/podman/issues/8058
+ if !utils.IsLibpodRequest(r) {
+ frame.WriteString("\n")
+ }
if writeHeader {
binary.BigEndian.PutUint32(header[4:], uint32(frame.Len()))
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index a46784a6c..629ca565e 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -231,6 +231,9 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
if len(networkCreate.Name) > 0 {
name = networkCreate.Name
}
+ if len(networkCreate.Driver) < 1 {
+ networkCreate.Driver = network.DefaultNetworkDriver
+ }
// At present I think we should just support the bridge driver
// and allow demand to make us consider more
if networkCreate.Driver != network.DefaultNetworkDriver {
diff --git a/pkg/spec/security.go b/pkg/spec/security.go
index e152e3495..5f7db7edb 100644
--- a/pkg/spec/security.go
+++ b/pkg/spec/security.go
@@ -178,7 +178,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon
for _, opt := range c.SecurityOpts {
// Split on both : and =
- splitOpt := strings.Split(opt, "=")
+ splitOpt := strings.SplitN(opt, "=", 2)
if len(splitOpt) == 1 {
splitOpt = strings.Split(opt, ":")
}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index 5e2f04e50..ebf5ec196 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -394,7 +394,7 @@ func getBindMount(args []string) (spec.Mount, error) {
var setSource, setDest, setRORW, setSuid, setDev, setExec, setRelabel bool
for _, val := range args {
- kv := strings.Split(val, "=")
+ kv := strings.SplitN(val, "=", 2)
switch kv[0] {
case "bind-nonrecursive":
newMount.Options = append(newMount.Options, "bind")
@@ -517,7 +517,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
var setDest, setRORW, setSuid, setDev, setExec, setTmpcopyup bool
for _, val := range args {
- kv := strings.Split(val, "=")
+ kv := strings.SplitN(val, "=", 2)
switch kv[0] {
case "tmpcopyup", "notmpcopyup":
if setTmpcopyup {
@@ -591,7 +591,7 @@ func getNamedVolume(args []string) (*libpod.ContainerNamedVolume, error) {
var setSource, setDest, setRORW, setSuid, setDev, setExec bool
for _, val := range args {
- kv := strings.Split(val, "=")
+ kv := strings.SplitN(val, "=", 2)
switch kv[0] {
case "ro", "rw":
if setRORW {
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index f02432f5b..8454458a8 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -110,7 +110,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
// Only use image command if the user did not manually set an
// entrypoint.
command := s.Command
- if command == nil && img != nil && s.Entrypoint == nil {
+ if (command == nil || len(command) == 0) && img != nil && (s.Entrypoint == nil || len(s.Entrypoint) == 0) {
newCmd, err := img.Cmd(ctx)
if err != nil {
return nil, err
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index c3a70e2fb..91aba9fa7 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -474,8 +474,8 @@ func getTomlStorage(storeOptions *storage.StoreOptions) *tomlConfig {
config.Storage.RunRoot = storeOptions.RunRoot
config.Storage.GraphRoot = storeOptions.GraphRoot
for _, i := range storeOptions.GraphDriverOptions {
- s := strings.Split(i, "=")
- if s[0] == "overlay.mount_program" {
+ s := strings.SplitN(i, "=", 2)
+ if s[0] == "overlay.mount_program" && len(s) == 2 {
config.Storage.Options.MountProgram = s[1]
}
}