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/images_search.go20
-rw-r--r--pkg/api/handlers/libpod/images.go8
-rw-r--r--pkg/api/server/server.go24
-rw-r--r--pkg/domain/infra/abi/terminal/sigproxy_linux.go5
-rw-r--r--pkg/specgen/generate/namespaces.go2
-rw-r--r--pkg/specgen/generate/oci.go2
7 files changed, 63 insertions, 235 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/images_search.go b/pkg/api/handlers/compat/images_search.go
index 131fab69f..b3ceae3ee 100644
--- a/pkg/api/handlers/compat/images_search.go
+++ b/pkg/api/handlers/compat/images_search.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/auth"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -14,9 +15,10 @@ import (
func SearchImages(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Term string `json:"term"`
- Limit int `json:"limit"`
- Filters map[string][]string `json:"filters"`
+ Term string `json:"term"`
+ Limit int `json:"limit"`
+ Filters map[string][]string `json:"filters"`
+ TLSVerify bool `json:"tlsVerify"`
}{
// This is where you can override the golang default value for one of fields
}
@@ -58,6 +60,18 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
Limit: query.Limit,
}
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ options.InsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ }
+
+ _, authfile, key, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+ options.Authfile = authfile
+
results, err := image.SearchImages(query.Term, options)
if err != nil {
utils.BadRequest(w, "term", query.Term, err)
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index 1292090fb..3fb5d23c8 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -636,6 +636,14 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
options.Filter = *filter
}
+ _, authfile, key, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+ options.Authfile = authfile
+
searchResults, err := image.SearchImages(query.Term, options)
if err != nil {
utils.BadRequest(w, "term", query.Term, err)
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 355a46fb7..64008767b 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -7,7 +7,6 @@ import (
"net"
"net/http"
"os"
- "os/signal"
goRuntime "runtime"
"strings"
"sync"
@@ -15,6 +14,7 @@ import (
"time"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/server/idle"
"github.com/coreos/go-systemd/v22/activation"
@@ -180,8 +180,17 @@ func setupSystemd() {
// Serve starts responding to HTTP requests.
func (s *APIServer) Serve() error {
setupSystemd()
- sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
+
+ // Start the shutdown signal handler.
+ if err := shutdown.Start(); err != nil {
+ return err
+ }
+ if err := shutdown.Register("server", func(sig os.Signal) error {
+ return s.Shutdown()
+ }); err != nil {
+ return err
+ }
+
errChan := make(chan error, 1)
go func() {
@@ -217,14 +226,7 @@ func (s *APIServer) Serve() error {
errChan <- nil
}()
- select {
- case err := <-errChan:
- return err
- case sig := <-sigChan:
- logrus.Infof("APIServer terminated by signal %v", sig)
- }
-
- return nil
+ return <-errChan
}
// Shutdown is a clean shutdown waiting on existing clients
diff --git a/pkg/domain/infra/abi/terminal/sigproxy_linux.go b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
index f484e926c..0c586cf5c 100644
--- a/pkg/domain/infra/abi/terminal/sigproxy_linux.go
+++ b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
@@ -5,12 +5,17 @@ import (
"syscall"
"github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/signal"
"github.com/sirupsen/logrus"
)
// ProxySignals ...
func ProxySignals(ctr *libpod.Container) {
+ // Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going
+ // to the container now.
+ shutdown.Stop()
+
sigBuffer := make(chan os.Signal, 128)
signal.CatchAll(sigBuffer)
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index 7adb8be6a..7e4f09dc4 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -342,7 +342,7 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt
return errors.Wrapf(err, "error looking up container to share uts namespace with")
}
hostname = utsCtr.Hostname()
- case s.NetNS.NSMode == specgen.Host || s.UtsNS.NSMode == specgen.Host:
+ case (s.NetNS.NSMode == specgen.Host && hostname == "") || s.UtsNS.NSMode == specgen.Host:
tmpHostname, err := os.Hostname()
if err != nil {
return errors.Wrap(err, "unable to retrieve hostname of the host")
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