diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 2 | ||||
-rw-r--r-- | pkg/bindings/containers/attach.go | 4 | ||||
-rw-r--r-- | pkg/bindings/containers/logs.go | 2 | ||||
-rw-r--r-- | pkg/bindings/errors.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/build.go | 26 | ||||
-rw-r--r-- | pkg/bindings/manifests/manifests.go | 64 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 29 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images_test.go | 2 | ||||
-rw-r--r-- | pkg/k8s.io/api/core/v1/types.go | 2 | ||||
-rw-r--r-- | pkg/machine/pull.go | 2 | ||||
-rw-r--r-- | pkg/machine/qemu/machine.go | 26 | ||||
-rw-r--r-- | pkg/rootless/rootless.go | 2 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 12 | ||||
-rw-r--r-- | pkg/specgen/generate/container.go | 6 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/volume.go | 2 | ||||
-rw-r--r-- | pkg/specgen/generate/security.go | 7 | ||||
-rw-r--r-- | pkg/specgen/generate/storage.go | 2 | ||||
-rw-r--r-- | pkg/specgenutil/specgen.go | 2 | ||||
-rw-r--r-- | pkg/systemd/generate/pods.go | 4 | ||||
-rw-r--r-- | pkg/util/utils.go | 2 |
20 files changed, 134 insertions, 66 deletions
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index ad9ad88d1..b823a56b6 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -441,7 +441,7 @@ func ManifestModify(w http.ResponseWriter, r *http.Request) { case len(report.Errors) > 0 && len(report.Images) > 0: statusCode = http.StatusConflict case len(report.Errors) > 0: - statusCode = http.StatusInternalServerError + statusCode = http.StatusBadRequest } utils.WriteResponse(w, statusCode, report) } diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go index 0c6ebdd2f..80702ea98 100644 --- a/pkg/bindings/containers/attach.go +++ b/pkg/bindings/containers/attach.go @@ -242,7 +242,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri } } case fd == 3: - return fmt.Errorf("error from service from stream: %s", frame) + return fmt.Errorf("from service from stream: %s", frame) default: return fmt.Errorf("unrecognized channel '%d' in header, 0-3 supported", fd) } @@ -562,7 +562,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar } } case fd == 3: - return fmt.Errorf("error from service from stream: %s", frame) + return fmt.Errorf("from service from stream: %s", frame) default: return fmt.Errorf("unrecognized channel '%d' in header, 0-3 supported", fd) } diff --git a/pkg/bindings/containers/logs.go b/pkg/bindings/containers/logs.go index 7f7f07395..8ea8ed7fa 100644 --- a/pkg/bindings/containers/logs.go +++ b/pkg/bindings/containers/logs.go @@ -57,7 +57,7 @@ func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan, case 2: stderrChan <- string(frame) case 3: - return errors.New("error from service in stream: " + string(frame)) + return errors.New("from service in stream: " + string(frame)) default: return fmt.Errorf("unrecognized input header: %d", fd) } diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index 44973eb41..eb95764ba 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -54,6 +54,6 @@ func CheckResponseCode(inError error) (int, error) { case *errorhandling.PodConflictErrorModel: return e.Code(), nil default: - return -1, errors.New("error is not type ErrorModel") + return -1, errors.New("is not type ErrorModel") } } diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index c508cb767..e1b427742 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -241,7 +241,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO params.Add("platform", platform) } } - if contextDir, err := filepath.EvalSymlinks(options.ContextDirectory); err == nil { + var err error + var contextDir string + if contextDir, err = filepath.EvalSymlinks(options.ContextDirectory); err == nil { options.ContextDirectory = contextDir } @@ -301,7 +303,6 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO var ( headers http.Header - err error ) if options.SystemContext != nil && options.SystemContext.DockerAuthConfig != nil { headers, err = auth.MakeXRegistryAuthHeader(options.SystemContext, options.SystemContext.DockerAuthConfig.Username, options.SystemContext.DockerAuthConfig.Password) @@ -325,7 +326,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO } } - contextDir, err := filepath.Abs(options.ContextDirectory) + contextDir, err = filepath.Abs(options.ContextDirectory) if err != nil { logrus.Errorf("Cannot find absolute path of %v: %v", options.ContextDirectory, err) return nil, err @@ -556,16 +557,27 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { merr = multierror.Append(merr, err) return } - err = filepath.Walk(s, func(path string, info os.FileInfo, err error) error { if err != nil { return err } - if path == s { - return nil // skip root dir + // check if what we are given is an empty dir, if so then continue w/ it. Else return. + // if we are given a file or a symlink, we do not want to exclude it. + if info.IsDir() && s == path { + var p *os.File + p, err = os.Open(path) + if err != nil { + return err + } + defer p.Close() + _, err = p.Readdir(1) + if err != io.EOF { + return nil // non empty root dir, need to return + } else if err != nil { + logrus.Errorf("While reading directory %v: %v", path, err) + } } - name := filepath.ToSlash(strings.TrimPrefix(path, s+string(filepath.Separator))) excluded, err := pm.Matches(name) // nolint:staticcheck diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go index a8f576ecd..70b3819f5 100644 --- a/pkg/bindings/manifests/manifests.go +++ b/pkg/bindings/manifests/manifests.go @@ -2,10 +2,9 @@ package manifests import ( "context" - "errors" "fmt" + "io/ioutil" "net/http" - "net/url" "strconv" "strings" @@ -16,8 +15,11 @@ import ( "github.com/containers/podman/v4/pkg/auth" "github.com/containers/podman/v4/pkg/bindings" "github.com/containers/podman/v4/pkg/bindings/images" + "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/version" jsoniter "github.com/json-iterator/go" + "github.com/pkg/errors" ) // Create creates a manifest for the given name. Optional images to be associated with @@ -157,30 +159,8 @@ func Add(ctx context.Context, name string, options *AddOptions) (string, error) // Remove deletes a manifest entry from a manifest list. Both name and the digest to be // removed are mandatory inputs. The ID of the new manifest list is returned as a string. func Remove(ctx context.Context, name, digest string, _ *RemoveOptions) (string, error) { - if bindings.ServiceVersion(ctx).GTE(semver.MustParse("4.0.0")) { - optionsv4 := new(ModifyOptions).WithOperation("remove") - return Modify(ctx, name, []string{digest}, optionsv4) - } - - // API Version < 4.0.0 - conn, err := bindings.GetClient(ctx) - if err != nil { - return "", err - } - - headers := http.Header{} - headers.Add("API-Version", "3.4.0") - - params := url.Values{} - params.Set("digest", digest) - response, err := conn.DoRequest(ctx, nil, http.MethodDelete, "/manifests/%s", params, headers, name) - if err != nil { - return "", err - } - defer response.Body.Close() - - var idr handlers.IDResponse - return idr.ID, response.Process(&idr) + optionsv4 := new(ModifyOptions).WithOperation("remove") + return Modify(ctx, name, []string{digest}, optionsv4) } // Push takes a manifest list and pushes to a destination. If the destination is not specified, @@ -275,8 +255,36 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp } defer response.Body.Close() - var idr handlers.IDResponse - return idr.ID, response.Process(&idr) + data, err := ioutil.ReadAll(response.Body) + if err != nil { + return "", errors.Wrap(err, "unable to process API response") + } + + if response.IsSuccess() || response.IsRedirection() { + var report entities.ManifestModifyReport + if err = jsoniter.Unmarshal(data, &report); err != nil { + return "", errors.Wrap(err, "unable to decode API response") + } + + err = errorhandling.JoinErrors(report.Errors) + if err != nil { + errModel := errorhandling.ErrorModel{ + Because: (errors.Cause(err)).Error(), + Message: err.Error(), + ResponseCode: response.StatusCode, + } + return report.ID, &errModel + } + return report.ID, nil + } + + errModel := errorhandling.ErrorModel{ + ResponseCode: response.StatusCode, + } + if err = jsoniter.Unmarshal(data, &errModel); err != nil { + return "", errors.Wrap(err, "unable to decode API response") + } + return "", &errModel } // Annotate modifies the given manifest list using options and the optional list of images diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 1986228a6..f45bdeba5 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -1496,6 +1496,35 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti return nil, err } + if ctrCloneOpts.CreateOpts.Pod != "" { + pod, err := ic.Libpod.LookupPod(ctrCloneOpts.CreateOpts.Pod) + if err != nil { + return nil, err + } + + allNamespaces := []struct { + isShared bool + value *specgen.Namespace + }{ + {pod.SharesPID(), &spec.PidNS}, + {pod.SharesNet(), &spec.NetNS}, + {pod.SharesCgroup(), &spec.CgroupNS}, + {pod.SharesIPC(), &spec.IpcNS}, + {pod.SharesUTS(), &spec.UtsNS}, + } + + printWarning := false + for _, n := range allNamespaces { + if n.isShared && !n.value.IsDefault() { + *n.value = specgen.Namespace{NSMode: specgen.Default} + printWarning = true + } + } + if printWarning { + logrus.Warning("At least one namespace was reset to the default configuration") + } + } + err = specgenutil.FillOutSpecGen(spec, &ctrCloneOpts.CreateOpts, []string{}) if err != nil { return nil, err diff --git a/pkg/domain/infra/abi/images_test.go b/pkg/domain/infra/abi/images_test.go index e38b9390d..311ab3ed7 100644 --- a/pkg/domain/infra/abi/images_test.go +++ b/pkg/domain/infra/abi/images_test.go @@ -48,7 +48,7 @@ func TestToDomainHistoryLayer(t *testing.T) { // r := DirectImageRuntime{m} // err := r.Delete(context.TODO(), actual, "fedora") // if err != nil { -// t.Errorf("error should be nil, got: %v", err) +// t.Errorf("should be nil, got: %v", err) // } // m.AssertExpectations(t) // } diff --git a/pkg/k8s.io/api/core/v1/types.go b/pkg/k8s.io/api/core/v1/types.go index 833814bc6..a488e5f28 100644 --- a/pkg/k8s.io/api/core/v1/types.go +++ b/pkg/k8s.io/api/core/v1/types.go @@ -2024,7 +2024,7 @@ type TopologySpreadConstraint struct { // but giving higher precedence to topologies that would help reduce the // skew. // A constraint is considered "Unsatisfiable" for an incoming pod - // if and only if every possible node assigment for that pod would violate + // if and only if every possible node assignment for that pod would violate // "MaxSkew" on some topology. // For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same // labelSelector spread as 3/1/1: diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go index 26abedfcd..7e6f01bad 100644 --- a/pkg/machine/pull.go +++ b/pkg/machine/pull.go @@ -129,7 +129,7 @@ func DownloadVMImage(downloadURL *url2.URL, localImagePath string) error { }() if resp.StatusCode != http.StatusOK { - return fmt.Errorf("error downloading VM image %s: %s", downloadURL, resp.Status) + return fmt.Errorf("downloading VM image %s: %s", downloadURL, resp.Status) } size := resp.ContentLength urlSplit := strings.Split(downloadURL.Path, "/") diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 3b14572a6..ffc90b2a0 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -98,7 +98,7 @@ func (p *Provider) NewMachine(opts machine.InitOptions) (machine.VM, error) { return nil, err } - cmd := append([]string{execPath}) + cmd := []string{execPath} // Add memory cmd = append(cmd, []string{"-m", strconv.Itoa(int(vm.Memory))}...) // Add cpus @@ -317,7 +317,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { resize.Stdout = os.Stdout resize.Stderr = os.Stderr if err := resize.Run(); err != nil { - return false, errors.Errorf("error resizing image: %q", err) + return false, errors.Errorf("resizing image: %q", err) } } // If the user provides an ignition file, we need to @@ -430,13 +430,29 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { // Disable graphic window when not in debug mode // Done in start, so we're not suck with the debug level we used on init - if logrus.GetLevel() != logrus.DebugLevel { + if !logrus.IsLevelEnabled(logrus.DebugLevel) { cmd = append(cmd, "-display", "none") } _, err = os.StartProcess(v.CmdLine[0], cmd, attr) if err != nil { - return err + // check if qemu was not found + if !errors.Is(err, os.ErrNotExist) { + return err + } + // lookup qemu again maybe the path was changed, https://github.com/containers/podman/issues/13394 + cfg, err := config.Default() + if err != nil { + return err + } + cmd[0], err = cfg.FindHelperBinary(QemuCommand, true) + if err != nil { + return err + } + _, err = os.StartProcess(cmd[0], cmd, attr) + if err != nil { + return err + } } fmt.Println("Waiting for VM ...") socketPath, err := getRuntimeDir() @@ -1062,7 +1078,7 @@ func (v *MachineVM) isIncompatible() bool { func (v *MachineVM) getForwardSocketPath() (string, error) { path, err := machine.GetDataDir(v.Name) if err != nil { - logrus.Errorf("Error resolving data dir: %s", err.Error()) + logrus.Errorf("Resolving data dir: %s", err.Error()) return "", nil } return filepath.Join(path, "podman.sock"), nil diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index 13f8078e2..d7143f549 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -35,7 +35,7 @@ func TryJoinPauseProcess(pausePidPath string) (bool, int, error) { if os.IsNotExist(err) { return false, -1, nil } - return false, -1, fmt.Errorf("error acquiring lock on %s: %w", pausePidPath, err) + return false, -1, fmt.Errorf("acquiring lock on %s: %w", pausePidPath, err) } pidFileLock.Lock() diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 786e28093..cff6de5a3 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -146,7 +146,7 @@ func tryMappingTool(uid bool, pid int, hostID int, mappings []idtools.IDMap) err } if output, err := cmd.CombinedOutput(); err != nil { - logrus.Errorf("error running `%s`: %s", strings.Join(args, " "), output) + logrus.Errorf("running `%s`: %s", strings.Join(args, " "), output) return errors.Wrapf(err, "cannot setup namespace using %q", path) } return nil @@ -174,7 +174,7 @@ func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) { ret := C.reexec_in_user_namespace_wait(pidC, 0) if ret < 0 { - return false, -1, errors.New("error waiting for the re-exec process") + return false, -1, errors.New("waiting for the re-exec process") } return true, int(ret), nil @@ -374,7 +374,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo if fileOutput != nil { ret := C.reexec_in_user_namespace_wait(pidC, 0) if ret < 0 { - return false, -1, errors.New("error waiting for the re-exec process") + return false, -1, errors.New("waiting for the re-exec process") } return true, 0, nil @@ -391,11 +391,11 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo return joinUserAndMountNS(uint(pid), "") } } - return false, -1, errors.New("error setting up the process") + return false, -1, errors.New("setting up the process") } if b[0] != '0' { - return false, -1, errors.New("error setting up the process") + return false, -1, errors.New("setting up the process") } signals := []os.Signal{} @@ -425,7 +425,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo ret := C.reexec_in_user_namespace_wait(pidC, 0) if ret < 0 { - return false, -1, errors.New("error waiting for the re-exec process") + return false, -1, errors.New("waiting for the re-exec process") } return true, int(ret), nil diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 64669f34d..118d80e2c 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -337,9 +337,9 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error { return nil } -// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an exisiting container -func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID string) (*libpod.Container, error) { - c, err := rt.LookupContainer(contaierID) +// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an existing container +func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, containerID string) (*libpod.Container, error) { + c, err := rt.LookupContainer(containerID) if err != nil { return nil, err } diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index d57cb5685..987f11569 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -76,7 +76,7 @@ func VolumeFromHostPath(hostPath *v1.HostPathVolumeSource) (*KubeVolume, error) return nil, errors.Wrap(err, "error checking HostPathSocket") } if st.Mode()&os.ModeSocket != os.ModeSocket { - return nil, errors.Errorf("error checking HostPathSocket: path %s is not a socket", hostPath.Path) + return nil, errors.Errorf("checking HostPathSocket: path %s is not a socket", hostPath.Path) } case v1.HostPathDirectory: diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index 9c6709905..988c29832 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -146,6 +146,10 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, configSpec := g.Config configSpec.Process.Capabilities.Ambient = []string{} + + // Always unset the inheritable capabilities similarly to what the Linux kernel does + // They are used only when using capabilities with uid != 0. + configSpec.Process.Capabilities.Inheritable = []string{} configSpec.Process.Capabilities.Bounding = caplist user := strings.Split(s.User, ":")[0] @@ -153,7 +157,6 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, if (user == "" && s.UserNS.NSMode != specgen.KeepID) || user == "root" || user == "0" { configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Permitted = caplist - configSpec.Process.Capabilities.Inheritable = caplist } else { mergedCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil) if err != nil { @@ -175,12 +178,12 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } configSpec.Process.Capabilities.Effective = userCaps configSpec.Process.Capabilities.Permitted = userCaps - configSpec.Process.Capabilities.Inheritable = userCaps // Ambient capabilities were added to Linux 4.3. Set ambient // capabilities only when the kernel supports them. if supportAmbientCapabilities() { configSpec.Process.Capabilities.Ambient = userCaps + configSpec.Process.Capabilities.Inheritable = userCaps } } diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go index 6dcc1b7bf..f30fc4671 100644 --- a/pkg/specgen/generate/storage.go +++ b/pkg/specgen/generate/storage.go @@ -292,7 +292,7 @@ func getVolumesFrom(volumesFrom []string, runtime *libpod.Runtime) (map[string]s // and append them in if we can find them. spec := ctr.Spec() if spec == nil { - return nil, nil, errors.Errorf("error retrieving container %s spec for volumes-from", ctr.ID()) + return nil, nil, errors.Errorf("retrieving container %s spec for volumes-from", ctr.ID()) } for _, mnt := range spec.Mounts { if mnt.Type != define.TypeBind { diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 688cc2337..186d3862b 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -976,7 +976,7 @@ func parseThrottleIOPsDevices(iopsDevices []string) (map[string]specs.LinuxThrot } func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error) { - secretParseError := errors.New("error parsing secret") + secretParseError := errors.New("parsing secret") var mount []specgen.Secret envs := make(map[string]string) for _, val := range secrets { diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index 15b598ae8..cd1486a82 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -141,7 +141,7 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[str // Error out if the pod has no infra container, which we require to be the // main service. if !pod.HasInfraContainer() { - return nil, errors.Errorf("error generating systemd unit files: Pod %q has no infra container", pod.Name()) + return nil, errors.Errorf("generating systemd unit files: Pod %q has no infra container", pod.Name()) } podInfo, err := generatePodInfo(pod, options) @@ -160,7 +160,7 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[str return nil, err } if len(containers) == 0 { - return nil, errors.Errorf("error generating systemd unit files: Pod %q has no containers", pod.Name()) + return nil, errors.Errorf("generating systemd unit files: Pod %q has no containers", pod.Name()) } graph, err := libpod.BuildContainerGraph(containers) if err != nil { diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 1beb3b28e..334a44a88 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -656,7 +656,7 @@ func CreateCidFile(cidfile string, id string) error { if os.IsExist(err) { return errors.Errorf("container id file exists. Ensure another container is not using it or delete %s", cidfile) } - return errors.Errorf("error opening cidfile %s", cidfile) + return errors.Errorf("opening cidfile %s", cidfile) } if _, err = cidFile.WriteString(id); err != nil { logrus.Error(err) |