summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2021-12-06 23:43:25 +0000
committerGitHub <noreply@github.com>2021-12-06 23:43:25 +0000
commit49f589d7c36b6d52105a94493baf1664a3ada79c (patch)
treea8007cc755dc588312474bf27a1e996381731a9b /pkg
parent1aeb61cf5cfb0155ebcff3b449c5ea4bf8f15dc1 (diff)
parent014bbdb40a8a91ea59b8e4953c843ad4c4a69156 (diff)
downloadpodman-49f589d7c36b6d52105a94493baf1664a3ada79c.tar.gz
podman-49f589d7c36b6d52105a94493baf1664a3ada79c.tar.bz2
podman-49f589d7c36b6d52105a94493baf1664a3ada79c.zip
Merge pull request #12525 from mheon/bump_343
Backports for and bump to v3.4.3
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers_archive.go4
-rw-r--r--pkg/api/handlers/compat/containers_create.go4
-rw-r--r--pkg/api/handlers/compat/images.go12
-rw-r--r--pkg/api/handlers/compat/images_build.go21
-rw-r--r--pkg/api/server/register_images.go7
-rw-r--r--pkg/bindings/images/build.go5
-rw-r--r--pkg/domain/infra/abi/generate.go20
-rw-r--r--pkg/domain/infra/tunnel/images.go5
-rw-r--r--pkg/machine/ignition.go2
-rw-r--r--pkg/machine/qemu/options_darwin_arm64.go2
-rw-r--r--pkg/rootless/rootless_linux.c304
-rw-r--r--pkg/specgen/generate/container_create.go4
-rw-r--r--pkg/specgen/generate/pod_create.go11
-rw-r--r--pkg/specgen/specgen.go5
-rw-r--r--pkg/specgenutil/specgen.go5
15 files changed, 227 insertions, 184 deletions
diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go
index cda23a399..54cbe01e9 100644
--- a/pkg/api/handlers/compat/containers_archive.go
+++ b/pkg/api/handlers/compat/containers_archive.go
@@ -133,8 +133,10 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
return
}
- w.WriteHeader(http.StatusOK)
if err := copyFunc(); err != nil {
logrus.Error(err.Error())
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
+ return
}
+ w.WriteHeader(http.StatusOK)
}
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 94d20a04a..d5abb6e44 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -55,7 +55,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
newImage, resolvedName, err := runtime.LibimageRuntime().LookupImage(body.Config.Image, nil)
if err != nil {
if errors.Cause(err) == storage.ErrImageUnknown {
- utils.Error(w, "No such image", http.StatusNotFound, err)
+ utils.Error(w, "No such image", http.StatusNotFound, errors.Wrap(err, "No such image"))
return
}
@@ -86,6 +86,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
return
}
+ // moby always create the working directory
+ sg.CreateWorkingDir = true
ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.ContainerCreate(r.Context(), sg)
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 0b7ba8bee..5c73cb0bd 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -393,14 +393,20 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images"))
return
}
- var summaries = make([]*entities.ImageSummary, len(images))
- for j, img := range images {
+
+ summaries := make([]*entities.ImageSummary, 0, len(images))
+ for _, img := range images {
+ // If the image is a manifest list, extract as much as we can.
+ if isML, _ := img.IsManifestList(r.Context()); isML {
+ continue
+ }
+
is, err := handlers.ImageToImageSummary(img)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed transform image summaries"))
return
}
- summaries[j] = is
+ summaries = append(summaries, is)
}
utils.WriteResponse(w, http.StatusOK, summaries)
}
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index 6152f1c02..ac5934c13 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -24,6 +24,7 @@ import (
"github.com/containers/podman/v3/pkg/auth"
"github.com/containers/podman/v3/pkg/channel"
"github.com/containers/storage/pkg/archive"
+ "github.com/docker/docker/pkg/jsonmessage"
"github.com/gorilla/schema"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -134,6 +135,15 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
return
}
+ // if layers field not set assume its not from a valid podman-client
+ // could be a docker client, set `layers=true` since that is the default
+ // expected behviour
+ if !utils.IsLibpodRequest(r) {
+ if _, found := r.URL.Query()["layers"]; !found {
+ query.Layers = true
+ }
+ }
+
// convert addcaps formats
var addCaps = []string{}
if _, found := r.URL.Query()["addcaps"]; found {
@@ -537,8 +547,10 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
for {
m := struct {
- Stream string `json:"stream,omitempty"`
- Error string `json:"error,omitempty"`
+ Stream string `json:"stream,omitempty"`
+ Error *jsonmessage.JSONError `json:"errorDetail,omitempty"`
+ // NOTE: `error` is being deprecated check https://github.com/moby/moby/blob/master/pkg/jsonmessage/jsonmessage.go#L148
+ ErrorMessage string `json:"error,omitempty"` // deprecate this slowly
}{}
select {
@@ -561,7 +573,10 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
}
flush()
case e := <-stderr.Chan():
- m.Error = string(e)
+ m.ErrorMessage = string(e)
+ m.Error = &jsonmessage.JSONError{
+ Message: m.ErrorMessage,
+ }
if err := enc.Encode(m); err != nil {
logrus.Warnf("Failed to json encode error %v", err)
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index f66669256..bc7ea72c9 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -1500,6 +1500,13 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// JSON map of key, value pairs to set as labels on the new image
// (As of version 1.xx)
// - in: query
+ // name: layers
+ // type: boolean
+ // default: true
+ // description: |
+ // Cache intermediate layers during build.
+ // (As of version 1.xx)
+ // - in: query
// name: networkmode
// type: string
// default: bridge
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index 4c3c83837..63cc508dc 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -345,6 +345,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
}
c = tmpFile.Name()
}
+ cfDir := filepath.Dir(c)
+ if absDir, err := filepath.EvalSymlinks(cfDir); err == nil {
+ name := filepath.ToSlash(strings.TrimPrefix(c, cfDir+string(filepath.Separator)))
+ c = filepath.Join(absDir, name)
+ }
containerfile, err := filepath.Abs(c)
if err != nil {
logrus.Errorf("cannot find absolute path of %v: %v", c, err)
diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go
index a4d6bcf86..68bb351bf 100644
--- a/pkg/domain/infra/abi/generate.go
+++ b/pkg/domain/infra/abi/generate.go
@@ -124,6 +124,14 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
if err != nil {
return nil, err
}
+ if len(po.Spec.Volumes) != 0 {
+ warning := `
+# NOTE: If you generated this yaml from an unprivileged and rootless podman container on an SELinux
+# enabled system, check the podman generate kube man page for steps to follow to ensure that your pod/container
+# has the right permissions to access the volumes added.
+`
+ content = append(content, []byte(warning))
+ }
b, err := generateKubeYAML(libpod.ConvertV1PodToYAMLPod(po))
if err != nil {
return nil, err
@@ -131,7 +139,11 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
podContent = append(podContent, b)
if options.Service {
- b, err := generateKubeYAML(libpod.GenerateKubeServiceFromV1Pod(po, []k8sAPI.ServicePort{}))
+ svc, err := libpod.GenerateKubeServiceFromV1Pod(po, []k8sAPI.ServicePort{})
+ if err != nil {
+ return nil, err
+ }
+ b, err := generateKubeYAML(svc)
if err != nil {
return nil, err
}
@@ -169,7 +181,11 @@ func getKubePods(ctx context.Context, pods []*libpod.Pod, getService bool) ([][]
pos = append(pos, b)
if getService {
- b, err := generateKubeYAML(libpod.GenerateKubeServiceFromV1Pod(po, sp))
+ svc, err := libpod.GenerateKubeServiceFromV1Pod(po, sp)
+ if err != nil {
+ return nil, nil, err
+ }
+ b, err := generateKubeYAML(svc)
if err != nil {
return nil, nil, err
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index ab2a93c75..14dc5b92c 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -264,7 +264,10 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string,
defer func() { _ = os.Remove(f.Name()) }()
}
default:
- f, err = os.Create(opts.Output)
+ // This code was added to allow for opening stdout replacing
+ // os.Create(opts.Output) which was attempting to open the file
+ // for read/write which fails on Darwin platforms
+ f, err = os.OpenFile(opts.Output, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
}
if err != nil {
return err
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index ef6c741cd..5c465d37d 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -81,7 +81,7 @@ func NewIgnitionFile(ign DynamicIgnition) error {
// so a listening host knows it can being interacting with it
ready := `[Unit]
Requires=dev-virtio\\x2dports-%s.device
-After=remove-moby.service
+After=remove-moby.service sshd.socket sshd.service
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go
index 43cd3d69d..727a275d2 100644
--- a/pkg/machine/qemu/options_darwin_arm64.go
+++ b/pkg/machine/qemu/options_darwin_arm64.go
@@ -24,7 +24,7 @@ func (v *MachineVM) addArchOptions() []string {
func (v *MachineVM) prepare() error {
ovmfDir := getOvmfDir(v.ImagePath, v.Name)
- cmd := []string{"dd", "if=/dev/zero", "conv=sync", "bs=1m", "count=64", "of=" + ovmfDir}
+ cmd := []string{"/bin/dd", "if=/dev/zero", "conv=sync", "bs=1m", "count=64", "of=" + ovmfDir}
return exec.Command(cmd[0], cmd[1:]...).Run()
}
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 6ce4b1e29..73da93195 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -19,6 +19,33 @@
#include <sys/select.h>
#include <stdio.h>
+#define cleanup_free __attribute__ ((cleanup (cleanup_freep)))
+#define cleanup_close __attribute__ ((cleanup (cleanup_closep)))
+#define cleanup_dir __attribute__ ((cleanup (cleanup_dirp)))
+
+static inline void
+cleanup_freep (void *p)
+{
+ void **pp = (void **) p;
+ free (*pp);
+}
+
+static inline void
+cleanup_closep (void *p)
+{
+ int *pp = p;
+ if (*pp >= 0)
+ TEMP_FAILURE_RETRY (close (*pp));
+}
+
+static inline void
+cleanup_dirp (DIR **p)
+{
+ DIR *dir = *p;
+ if (dir)
+ closedir (dir);
+}
+
int rename_noreplace (int olddirfd, const char *oldpath, int newdirfd, const char *newpath)
{
int ret;
@@ -114,8 +141,8 @@ do_pause ()
static char **
get_cmd_line_args ()
{
- int fd;
- char *buffer;
+ cleanup_free char *buffer = NULL;
+ cleanup_close int fd = -1;
size_t allocated;
size_t used = 0;
int ret;
@@ -134,10 +161,7 @@ get_cmd_line_args ()
{
ret = TEMP_FAILURE_RETRY (read (fd, buffer + used, allocated - used));
if (ret < 0)
- {
- free (buffer);
- return NULL;
- }
+ return NULL;
if (ret == 0)
break;
@@ -148,30 +172,21 @@ get_cmd_line_args ()
allocated += 512;
char *tmp = realloc (buffer, allocated);
if (tmp == NULL)
- {
- free (buffer);
- return NULL;
- }
+ return NULL;
buffer = tmp;
}
}
- close (fd);
for (i = 0; i < used; i++)
if (buffer[i] == '\0')
argc++;
if (argc == 0)
- {
- free (buffer);
- return NULL;
- }
+ return NULL;
argv = malloc (sizeof (char *) * (argc + 1));
if (argv == NULL)
- {
- free (buffer);
- return NULL;
- }
+ return NULL;
+
argc = 0;
argv[argc++] = buffer;
@@ -181,15 +196,19 @@ get_cmd_line_args ()
argv[argc] = NULL;
+ /* Move ownership. */
+ buffer = NULL;
+
return argv;
}
static bool
can_use_shortcut ()
{
- int argc;
- char **argv;
+ cleanup_free char **argv = NULL;
+ cleanup_free char *argv0 = NULL;
bool ret = true;
+ int argc;
#ifdef DISABLE_JOIN_SHORTCUT
return false;
@@ -199,12 +218,10 @@ can_use_shortcut ()
if (argv == NULL)
return false;
+ argv0 = argv[0];
+
if (strstr (argv[0], "podman") == NULL)
- {
- free (argv[0]);
- free (argv);
- return false;
- }
+ return false;
for (argc = 0; argv[argc]; argc++)
{
@@ -229,11 +246,25 @@ can_use_shortcut ()
}
}
- free (argv[0]);
- free (argv);
return ret;
}
+static int
+open_namespace (int pid_to_join, const char *ns_file)
+{
+ char ns_path[PATH_MAX];
+ int ret;
+
+ ret = snprintf (ns_path, PATH_MAX, "/proc/%d/ns/%s", pid_to_join, ns_file);
+ if (ret == PATH_MAX)
+ {
+ fprintf (stderr, "internal error: namespace path too long\n");
+ return -1;
+ }
+
+ return open (ns_path, O_CLOEXEC | O_RDONLY);
+}
+
int
is_fd_inherited(int fd)
{
@@ -250,8 +281,7 @@ static void __attribute__((constructor)) init()
const char *listen_pid;
const char *listen_fds;
const char *listen_fdnames;
-
- DIR *d;
+ cleanup_dir DIR *d = NULL;
pause = getenv ("_PODMAN_PAUSE");
if (pause && pause[0])
@@ -299,7 +329,6 @@ static void __attribute__((constructor)) init()
FD_SET (fd % FD_SETSIZE, &(open_files_set[fd / FD_SETSIZE]));
}
- closedir (d);
}
listen_pid = getenv("LISTEN_PID");
@@ -317,7 +346,7 @@ static void __attribute__((constructor)) init()
if (saved_systemd_listen_pid == NULL
|| saved_systemd_listen_fds == NULL)
{
- fprintf (stderr, "save socket listen environments error: %s\n", strerror (errno));
+ fprintf (stderr, "save socket listen environments error: %m\n");
_exit (EXIT_FAILURE);
}
}
@@ -327,73 +356,70 @@ static void __attribute__((constructor)) init()
xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
if (geteuid () != 0 && xdg_runtime_dir && xdg_runtime_dir[0] && can_use_shortcut ())
{
- int r;
- int fd;
+ cleanup_free char *cwd = NULL;
+ cleanup_close int userns_fd = -1;
+ cleanup_close int mntns_fd = -1;
+ cleanup_close int fd = -1;
long pid;
char buf[12];
uid_t uid;
gid_t gid;
char path[PATH_MAX];
const char *const suffix = "/libpod/tmp/pause.pid";
- char *cwd = getcwd (NULL, 0);
char uid_fmt[16];
char gid_fmt[16];
size_t len;
+ int r;
+ cwd = getcwd (NULL, 0);
if (cwd == NULL)
{
- fprintf (stderr, "error getting current working directory: %s\n", strerror (errno));
+ fprintf (stderr, "error getting current working directory: %m\n");
_exit (EXIT_FAILURE);
}
len = snprintf (path, PATH_MAX, "%s%s", xdg_runtime_dir, suffix);
if (len >= PATH_MAX)
{
- fprintf (stderr, "invalid value for XDG_RUNTIME_DIR: %s", strerror (ENAMETOOLONG));
+ errno = ENAMETOOLONG;
+ fprintf (stderr, "invalid value for XDG_RUNTIME_DIR: %m");
exit (EXIT_FAILURE);
}
fd = open (path, O_RDONLY);
if (fd < 0)
- {
- free (cwd);
- return;
- }
+ return;
r = TEMP_FAILURE_RETRY (read (fd, buf, sizeof (buf) - 1));
- close (fd);
+
if (r < 0)
- {
- free (cwd);
- return;
- }
+ return;
buf[r] = '\0';
pid = strtol (buf, NULL, 10);
if (pid == LONG_MAX)
- {
- free (cwd);
- return;
- }
+ return;
uid = geteuid ();
gid = getegid ();
- sprintf (path, "/proc/%ld/ns/user", pid);
- fd = open (path, O_RDONLY);
- if (fd < 0 || setns (fd, 0) < 0)
- {
- free (cwd);
- return;
- }
- close (fd);
+ userns_fd = open_namespace (pid, "user");
+ if (userns_fd < 0)
+ return;
- /* Errors here cannot be ignored as we already joined a ns. */
- sprintf (path, "/proc/%ld/ns/mnt", pid);
- fd = open (path, O_RDONLY);
- if (fd < 0)
+ mntns_fd = open_namespace (pid, "mnt");
+ if (mntns_fd < 0)
+ return;
+
+ if (setns (userns_fd, 0) < 0)
+ return;
+
+ /* The user namespace was joined, after this point errors are
+ not recoverable anymore. */
+
+ if (setns (mntns_fd, 0) < 0)
{
- fprintf (stderr, "cannot open %s: %s", path, strerror (errno));
+ fprintf (stderr, "cannot join mount namespace for %ld: %m", pid);
exit (EXIT_FAILURE);
}
@@ -404,33 +430,24 @@ static void __attribute__((constructor)) init()
setenv ("_CONTAINERS_ROOTLESS_UID", uid_fmt, 1);
setenv ("_CONTAINERS_ROOTLESS_GID", gid_fmt, 1);
- r = setns (fd, 0);
- if (r < 0)
- {
- fprintf (stderr, "cannot join mount namespace for %ld: %s", pid, strerror (errno));
- exit (EXIT_FAILURE);
- }
- close (fd);
-
if (syscall_setresgid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresgid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresgid: %m\n");
_exit (EXIT_FAILURE);
}
if (syscall_setresuid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresuid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresuid: %m\n");
_exit (EXIT_FAILURE);
}
if (chdir (cwd) < 0)
{
- fprintf (stderr, "cannot chdir to %s: %s\n", cwd, strerror (errno));
+ fprintf (stderr, "cannot chdir to %s: %m\n", cwd);
_exit (EXIT_FAILURE);
}
- free (cwd);
rootless_uid_init = uid;
rootless_gid_init = gid;
}
@@ -529,7 +546,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
fd = mkstemp (tmp_file_path);
if (fd < 0)
{
- fprintf (stderr, "error creating temporary file: %s\n", strerror (errno));
+ fprintf (stderr, "error creating temporary file: %m\n");
kill (pid, SIGKILL);
_exit (EXIT_FAILURE);
}
@@ -537,7 +554,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
r = TEMP_FAILURE_RETRY (write (fd, pid_str, strlen (pid_str)));
if (r < 0)
{
- fprintf (stderr, "cannot write to file descriptor: %s\n", strerror (errno));
+ fprintf (stderr, "cannot write to file descriptor: %m\n");
kill (pid, SIGKILL);
_exit (EXIT_FAILURE);
}
@@ -555,7 +572,7 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
r = TEMP_FAILURE_RETRY (write (p[1], "0", 1));
if (r < 0)
{
- fprintf (stderr, "cannot write to pipe: %s\n", strerror (errno));
+ fprintf (stderr, "cannot write to pipe: %m\n");
_exit (EXIT_FAILURE);
}
close (p[1]);
@@ -590,22 +607,6 @@ create_pause_process (const char *pause_pid_file_path, char **argv)
}
}
-static int
-open_namespace (int pid_to_join, const char *ns_file)
-{
- char ns_path[PATH_MAX];
- int ret;
-
- ret = snprintf (ns_path, PATH_MAX, "/proc/%d/ns/%s", pid_to_join, ns_file);
- if (ret == PATH_MAX)
- {
- fprintf (stderr, "internal error: namespace path too long\n");
- return -1;
- }
-
- return open (ns_path, O_CLOEXEC | O_RDONLY);
-}
-
static void
join_namespace_or_die (const char *name, int ns_fd)
{
@@ -619,18 +620,20 @@ join_namespace_or_die (const char *name, int ns_fd)
int
reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
{
+ cleanup_close int userns_fd = -1;
+ cleanup_close int mntns_fd = -1;
+ cleanup_free char *cwd = NULL;
char uid[16];
char gid[16];
- char **argv;
+ cleanup_free char *argv0 = NULL;
+ cleanup_free char **argv = NULL;
int pid;
- int mnt_ns = -1;
- int user_ns = -1;
- char *cwd = getcwd (NULL, 0);
sigset_t sigset, oldsigset;
+ cwd = getcwd (NULL, 0);
if (cwd == NULL)
{
- fprintf (stderr, "error getting current working directory: %s\n", strerror (errno));
+ fprintf (stderr, "error getting current working directory: %m\n");
_exit (EXIT_FAILURE);
}
@@ -640,32 +643,27 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
argv = get_cmd_line_args ();
if (argv == NULL)
{
- fprintf (stderr, "cannot read argv: %s\n", strerror (errno));
+ fprintf (stderr, "cannot read argv: %m\n");
_exit (EXIT_FAILURE);
}
- user_ns = open_namespace (pid_to_join, "user");
- if (user_ns < 0)
- return user_ns;
- mnt_ns = open_namespace (pid_to_join, "mnt");
- if (mnt_ns < 0)
- {
- close (user_ns);
- return mnt_ns;
- }
+ argv0 = argv[0];
+
+ userns_fd = open_namespace (pid_to_join, "user");
+ if (userns_fd < 0)
+ return userns_fd;
+ mntns_fd = open_namespace (pid_to_join, "mnt");
+ if (mntns_fd < 0)
+ return mntns_fd;
pid = fork ();
if (pid < 0)
- fprintf (stderr, "cannot fork: %s\n", strerror (errno));
+ fprintf (stderr, "cannot fork: %m\n");
if (pid)
{
int f;
- /* We passed down these fds, close them. */
- close (user_ns);
- close (mnt_ns);
-
for (f = 3; f <= open_files_max_fd; f++)
if (is_fd_inherited (f))
close (f);
@@ -681,22 +679,22 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
if (sigfillset (&sigset) < 0)
{
- fprintf (stderr, "cannot fill sigset: %s\n", strerror (errno));
+ fprintf (stderr, "cannot fill sigset: %m\n");
_exit (EXIT_FAILURE);
}
if (sigdelset (&sigset, SIGCHLD) < 0)
{
- fprintf (stderr, "cannot sigdelset(SIGCHLD): %s\n", strerror (errno));
+ fprintf (stderr, "cannot sigdelset(SIGCHLD): %m\n");
_exit (EXIT_FAILURE);
}
if (sigdelset (&sigset, SIGTERM) < 0)
{
- fprintf (stderr, "cannot sigdelset(SIGTERM): %s\n", strerror (errno));
+ fprintf (stderr, "cannot sigdelset(SIGTERM): %m\n");
_exit (EXIT_FAILURE);
}
if (sigprocmask (SIG_BLOCK, &sigset, &oldsigset) < 0)
{
- fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ fprintf (stderr, "cannot block signals: %m\n");
_exit (EXIT_FAILURE);
}
@@ -717,33 +715,30 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
if (prctl (PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0) < 0)
{
- fprintf (stderr, "cannot prctl(PR_SET_PDEATHSIG): %s\n", strerror (errno));
+ fprintf (stderr, "cannot prctl(PR_SET_PDEATHSIG): %m\n");
_exit (EXIT_FAILURE);
}
- join_namespace_or_die ("user", user_ns);
- join_namespace_or_die ("mnt", mnt_ns);
- close (user_ns);
- close (mnt_ns);
+ join_namespace_or_die ("user", userns_fd);
+ join_namespace_or_die ("mnt", mntns_fd);
if (syscall_setresgid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresgid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresgid: %m\n");
_exit (EXIT_FAILURE);
}
if (syscall_setresuid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresuid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresuid: %m\n");
_exit (EXIT_FAILURE);
}
if (chdir (cwd) < 0)
{
- fprintf (stderr, "cannot chdir to %s: %s\n", cwd, strerror (errno));
+ fprintf (stderr, "cannot chdir to %s: %m\n", cwd);
_exit (EXIT_FAILURE);
}
- free (cwd);
if (pause_pid_file_path && pause_pid_file_path[0] != '\0')
{
@@ -752,7 +747,7 @@ reexec_userns_join (int pid_to_join, char *pause_pid_file_path)
}
if (sigprocmask (SIG_SETMASK, &oldsigset, NULL) < 0)
{
- fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ fprintf (stderr, "cannot block signals: %m\n");
_exit (EXIT_FAILURE);
}
@@ -784,7 +779,7 @@ static int
copy_file_to_fd (const char *file_to_read, int outfd)
{
char buf[512];
- int fd;
+ cleanup_close int fd = -1;
fd = open (file_to_read, O_RDONLY);
if (fd < 0)
@@ -796,10 +791,7 @@ copy_file_to_fd (const char *file_to_read, int outfd)
r = TEMP_FAILURE_RETRY (read (fd, buf, sizeof buf));
if (r < 0)
- {
- close (fd);
- return r;
- }
+ return r;
if (r == 0)
break;
@@ -808,43 +800,40 @@ copy_file_to_fd (const char *file_to_read, int outfd)
{
w = TEMP_FAILURE_RETRY (write (outfd, &buf[t], r - t));
if (w < 0)
- {
- close (fd);
- return w;
- }
+ return w;
t += w;
}
}
- close (fd);
return 0;
}
int
reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_read, int outputfd)
{
+ cleanup_free char **argv = NULL;
+ cleanup_free char *argv0 = NULL;
+ cleanup_free char *cwd = NULL;
+ sigset_t sigset, oldsigset;
int ret;
pid_t pid;
char b;
- char **argv;
char uid[16];
char gid[16];
- char *cwd = getcwd (NULL, 0);
- sigset_t sigset, oldsigset;
+ cwd = getcwd (NULL, 0);
if (cwd == NULL)
{
- fprintf (stderr, "error getting current working directory: %s\n", strerror (errno));
+ fprintf (stderr, "error getting current working directory: %m\n");
_exit (EXIT_FAILURE);
}
-
sprintf (uid, "%d", geteuid ());
sprintf (gid, "%d", getegid ());
pid = syscall_clone (CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL);
if (pid < 0)
{
- fprintf (stderr, "cannot clone: %s\n", strerror (errno));
+ fprintf (stderr, "cannot clone: %m\n");
check_proc_sys_userns_file (_max_user_namespaces);
check_proc_sys_userns_file (_unprivileged_user_namespaces);
}
@@ -872,32 +861,34 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
if (sigfillset (&sigset) < 0)
{
- fprintf (stderr, "cannot fill sigset: %s\n", strerror (errno));
+ fprintf (stderr, "cannot fill sigset: %m\n");
_exit (EXIT_FAILURE);
}
if (sigdelset (&sigset, SIGCHLD) < 0)
{
- fprintf (stderr, "cannot sigdelset(SIGCHLD): %s\n", strerror (errno));
+ fprintf (stderr, "cannot sigdelset(SIGCHLD): %m\n");
_exit (EXIT_FAILURE);
}
if (sigdelset (&sigset, SIGTERM) < 0)
{
- fprintf (stderr, "cannot sigdelset(SIGTERM): %s\n", strerror (errno));
+ fprintf (stderr, "cannot sigdelset(SIGTERM): %m\n");
_exit (EXIT_FAILURE);
}
if (sigprocmask (SIG_BLOCK, &sigset, &oldsigset) < 0)
{
- fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ fprintf (stderr, "cannot block signals: %m\n");
_exit (EXIT_FAILURE);
}
argv = get_cmd_line_args ();
if (argv == NULL)
{
- fprintf (stderr, "cannot read argv: %s\n", strerror (errno));
+ fprintf (stderr, "cannot read argv: %m\n");
_exit (EXIT_FAILURE);
}
+ argv0 = argv[0];
+
if (do_socket_activation)
{
char s[32];
@@ -916,7 +907,7 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
ret = TEMP_FAILURE_RETRY (read (ready, &b, 1));
if (ret < 0)
{
- fprintf (stderr, "cannot read from sync pipe: %s\n", strerror (errno));
+ fprintf (stderr, "cannot read from sync pipe: %m\n");
_exit (EXIT_FAILURE);
}
if (ret != 1 || b != '0')
@@ -924,25 +915,24 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
if (syscall_setresgid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresgid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresgid: %m\n");
TEMP_FAILURE_RETRY (write (ready, "1", 1));
_exit (EXIT_FAILURE);
}
if (syscall_setresuid (0, 0, 0) < 0)
{
- fprintf (stderr, "cannot setresuid: %s\n", strerror (errno));
+ fprintf (stderr, "cannot setresuid: %m\n");
TEMP_FAILURE_RETRY (write (ready, "1", 1));
_exit (EXIT_FAILURE);
}
if (chdir (cwd) < 0)
{
- fprintf (stderr, "cannot chdir to %s: %s\n", cwd, strerror (errno));
+ fprintf (stderr, "cannot chdir to %s: %m\n", cwd);
TEMP_FAILURE_RETRY (write (ready, "1", 1));
_exit (EXIT_FAILURE);
}
- free (cwd);
if (pause_pid_file_path && pause_pid_file_path[0] != '\0')
{
@@ -956,14 +946,14 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
ret = TEMP_FAILURE_RETRY (write (ready, "0", 1));
if (ret < 0)
{
- fprintf (stderr, "cannot write to ready pipe: %s\n", strerror (errno));
- _exit (EXIT_FAILURE);
+ fprintf (stderr, "cannot write to ready pipe: %m\n");
+ _exit (EXIT_FAILURE);
}
close (ready);
if (sigprocmask (SIG_SETMASK, &oldsigset, NULL) < 0)
{
- fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
+ fprintf (stderr, "cannot block signals: %m\n");
_exit (EXIT_FAILURE);
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index f82b2a3c6..4003567e9 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -333,6 +333,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.WorkDir == "" {
s.WorkDir = "/"
}
+ if s.CreateWorkingDir {
+ options = append(options, libpod.WithCreateWorkingDir())
+ }
if s.StopSignal != nil {
options = append(options, libpod.WithStopSignal(*s.StopSignal))
}
@@ -426,6 +429,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
UID: s.UID,
GID: s.GID,
Mode: s.Mode,
+ Target: s.Target,
})
}
options = append(options, libpod.WithSecrets(secrs))
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index e523aef42..c33c366bd 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -8,7 +8,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -115,15 +114,6 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
logrus.Debugf("No networking because the infra container is missing")
break
}
- if rootless.IsRootless() {
- logrus.Debugf("Pod will use slirp4netns")
- if p.InfraContainerSpec.NetNS.NSMode != "host" {
- p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
- p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
- }
- } else {
- logrus.Debugf("Pod using bridge network mode")
- }
case specgen.Bridge:
p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge
logrus.Debugf("Pod using bridge network mode")
@@ -157,7 +147,6 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
- libpod.WithPodCgroups()
if len(p.InfraCommand) > 0 {
p.InfraContainerSpec.Entrypoint = p.InfraCommand
}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 0c30c498a..70518c073 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -264,6 +264,10 @@ type ContainerStorageConfig struct {
// If unset, the default, /, will be used.
// Optional.
WorkDir string `json:"work_dir,omitempty"`
+ // Create the working directory if it doesn't exist.
+ // If unset, it doesn't create it.
+ // Optional.
+ CreateWorkingDir bool `json:"create_working_dir,omitempty"`
// RootfsPropagation is the rootfs propagation mode for the container.
// If not set, the default of rslave will be used.
// Optional.
@@ -509,6 +513,7 @@ type SpecGenerator struct {
type Secret struct {
Source string
+ Target string
UID uint32
GID uint32
Mode uint32
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 8007e5d8e..eba173a81 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -861,6 +861,7 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
if len(split) == 1 {
mountSecret := specgen.Secret{
Source: val,
+ Target: target,
UID: uid,
GID: gid,
Mode: mode,
@@ -926,11 +927,9 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
return nil, nil, errors.Wrapf(secretParseError, "no source found %s", val)
}
if secretType == "mount" {
- if target != "" {
- return nil, nil, errors.Wrapf(secretParseError, "target option is invalid for mounted secrets")
- }
mountSecret := specgen.Secret{
Source: source,
+ Target: target,
UID: uid,
GID: gid,
Mode: mode,