diff options
45 files changed, 979 insertions, 195 deletions
diff --git a/cmd/podman/build.go b/cmd/podman/build.go index b8b315c68..acd402fdd 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -342,6 +342,7 @@ func buildCmd(c *cliconfig.BuildValues) error { } options := imagebuildah.BuildOptions{ + Architecture: c.Arch, CommonBuildOpts: &buildOpts, AdditionalTags: tags, Annotations: c.Annotation, @@ -359,6 +360,7 @@ func buildCmd(c *cliconfig.BuildValues) error { Layers: layers, NamespaceOptions: nsValues, NoCache: c.NoCache, + OS: c.OS, Out: stdout, Output: output, OutputFormat: format, diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index 2bcfdb954..27b40bbb6 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -25,6 +25,7 @@ Use the name of the container for the start, stop, and description in the unit f **--new** Create a new container via podman-run instead of starting an existing one. This option relies on container configuration files, which may not map directly to podman CLI flags; please review the generated output carefully before placing in production. +Since we use systemd `Type=forking` service, using this option will force the container run with the detached param `-d` **--timeout**, **-t**=*value* @@ -9,8 +9,8 @@ require ( github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921 github.com/containernetworking/plugins v0.8.5 - github.com/containers/buildah v1.14.2 - github.com/containers/common v0.4.2 + github.com/containers/buildah v1.14.3-0.20200313154200-d26f437b2a46 + github.com/containers/common v0.5.0 github.com/containers/conmon v2.0.10+incompatible github.com/containers/image/v5 v5.2.1 github.com/containers/psgo v1.4.0 @@ -25,7 +25,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 github.com/etcd-io/bbolt v1.3.3 - github.com/fsnotify/fsnotify v1.4.7 + github.com/fsnotify/fsnotify v1.4.9 github.com/ghodss/yaml v1.0.0 github.com/godbus/dbus/v5 v5.0.3 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf @@ -67,8 +67,14 @@ github.com/containernetworking/plugins v0.8.5 h1:pCvEMrFf7yzJI8+/D/7jkvE96KD52b7 github.com/containernetworking/plugins v0.8.5/go.mod h1:UZ2539umj8djuRQmBxuazHeJbYrLV8BSBejkk+she6o= github.com/containers/buildah v1.14.2 h1:rzrOVqWL3C3xA3MBmkDgWntRsBgkI3FGKODluBO+svU= github.com/containers/buildah v1.14.2/go.mod h1:HZ6MuZfHYq6ZMeoV9o3k9GwoCk1p3RWZOYbBXZtR7wE= +github.com/containers/buildah v1.14.3-0.20200313093807-c0e60d444696 h1:TCJsENYevaCqpQ8PBp5Y5QYACXWK2IiYYhk1UtLoPBw= +github.com/containers/buildah v1.14.3-0.20200313093807-c0e60d444696/go.mod h1:OCorIy7yUrQ2hIZY5z/LhJuPiH8bT8GUwC+9CarZK5o= +github.com/containers/buildah v1.14.3-0.20200313154200-d26f437b2a46 h1:Zw8xYI3HATHra5Csm1k5GOXNCietwGR6D2kQVP5zw2w= +github.com/containers/buildah v1.14.3-0.20200313154200-d26f437b2a46/go.mod h1:OCorIy7yUrQ2hIZY5z/LhJuPiH8bT8GUwC+9CarZK5o= github.com/containers/common v0.4.2 h1:O5d1gj/xdpQdZi0MEivRQ/7AeRaVeHdbSP/bvShw458= github.com/containers/common v0.4.2/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= +github.com/containers/common v0.5.0 h1:ZAef7h3oO46PcbTyfooZf8XLHrYad+GkhSu3EhH6P24= +github.com/containers/common v0.5.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/conmon v2.0.10+incompatible h1:EiwL41r5vx8SxG+dyUmbJ3baV9GUWjijPOdCkzM6gWU= github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v5 v5.2.1 h1:rQR6QSUneWBoW1bTFpP9EJJTevQFv27YsKYQVJIzg+s= @@ -150,6 +156,8 @@ github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.6.3 h1:VS/I3mxieZVIeaWXd57JKvSjheELafUJYtblGg75RIQ= github.com/fsouza/go-dockerclient v1.6.3/go.mod h1:OiSy/IhZIF+zheikZkXK7LVpGzxWchJPJKGWhBqOK4M= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= @@ -549,6 +557,7 @@ golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/libpod/reset.go b/libpod/reset.go index a35b476a4..ae0a0cde9 100644 --- a/libpod/reset.go +++ b/libpod/reset.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -87,12 +88,22 @@ func (r *Runtime) Reset(ctx context.Context) error { } prevError = err } - if err := os.RemoveAll(r.config.TmpDir); err != nil { + + runtimeDir, err := util.GetRuntimeDir() + if err != nil { + return err + } + tempDir := r.config.TmpDir + if r.config.TmpDir == runtimeDir { + tempDir = filepath.Join(r.config.TmpDir, "containers") + } + if err := os.RemoveAll(tempDir); err != nil { if prevError != nil { logrus.Error(prevError) } prevError = err } + if rootless.IsRootless() { configPath := filepath.Join(os.Getenv("HOME"), ".config/containers") if err := os.RemoveAll(configPath); err != nil { diff --git a/pkg/adapter/sigproxy_linux.go b/pkg/adapter/sigproxy_linux.go index 8295e4250..5695d0e42 100644 --- a/pkg/adapter/sigproxy_linux.go +++ b/pkg/adapter/sigproxy_linux.go @@ -20,7 +20,10 @@ func ProxySignals(ctr *libpod.Container) { for s := range sigBuffer { // Ignore SIGCHLD and SIGPIPE - these are mostly likely // intended for the podman command itself. - if s == syscall.SIGCHLD || s == syscall.SIGPIPE { + // SIGURG was added because of golang 1.14 and its preemptive changes + // causing more signals to "show up". + // https://github.com/containers/libpod/issues/5483 + if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG { continue } diff --git a/pkg/api/handlers/libpod/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go index 6c74500b9..6eb2ab0e3 100644 --- a/pkg/api/handlers/libpod/healthcheck.go +++ b/pkg/api/handlers/libpod/healthcheck.go @@ -14,8 +14,30 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) { if err != nil { if status == libpod.HealthCheckContainerNotFound { utils.ContainerNotFound(w, name, err) + return } + if status == libpod.HealthCheckNotDefined { + utils.Error(w, "no healthcheck defined", http.StatusConflict, err) + return + } + if status == libpod.HealthCheckContainerStopped { + utils.Error(w, "container not running", http.StatusConflict, err) + return + } + utils.InternalServerError(w, err) + return + } + ctr, err := runtime.LookupContainer(name) + if err != nil { utils.InternalServerError(w, err) + return } - utils.WriteResponse(w, http.StatusOK, status) + + hcLog, err := ctr.GetHealthCheckLog() + if err != nil { + utils.InternalServerError(w, err) + return + } + + utils.WriteResponse(w, http.StatusOK, hcLog) } diff --git a/pkg/api/server/register_healthcheck.go b/pkg/api/server/register_healthcheck.go index 5466e2905..69aa5bbfb 100644 --- a/pkg/api/server/register_healthcheck.go +++ b/pkg/api/server/register_healthcheck.go @@ -8,6 +8,29 @@ import ( ) func (s *APIServer) registerHealthCheckHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/libpod/containers/{name}/runhealthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet) + // swagger:operation GET /libpod/containers/{name:.*}/healthcheck libpod libpodRunHealthCheck + // --- + // tags: + // - containers + // summary: Run a container's healthcheck + // description: Execute the defined healthcheck and return information about the results + // parameters: + // - in: path + // name: name:.* + // type: string + // required: true + // description: the name or ID of the container + // produces: + // - application/json + // responses: + // 200: + // $ref: "#/responses/HealthcheckRun" + // 404: + // $ref: "#/responses/NoSuchContainer" + // 409: + // description: container has no healthcheck or is not running + // 500: + // $ref: '#/responses/InternalError' + r.Handle(VersionedPath("/libpod/containers/{name:.*}/healthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 011196e5a..e3c991d6d 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -156,3 +156,12 @@ type swagVolumeListResponse struct { // in:body Body []libpod.Volume } + +// Healthcheck +// swagger:response HealthcheckRun +type swagHealthCheckRunResponse struct { + // in:body + Body struct { + libpod.HealthCheckResults + } +} diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go index 3f94fad01..85cc2814c 100644 --- a/pkg/bindings/containers/healthcheck.go +++ b/pkg/bindings/containers/healthcheck.go @@ -10,15 +10,15 @@ import ( // RunHealthCheck executes the container's healthcheck and returns the health status of the // container. -func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckStatus, error) { +func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckResults, error) { conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } var ( - status libpod.HealthCheckStatus + status libpod.HealthCheckResults ) - response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/runhealthcheck", nil, nameOrID) + response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nameOrID) if err != nil { return nil, err } diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go index e7ef620d4..34a9c3136 100644 --- a/pkg/bindings/test/containers_test.go +++ b/pkg/bindings/test/containers_test.go @@ -312,4 +312,49 @@ var _ = Describe("Podman containers ", func() { Expect(exitCode).To(BeNumerically("==", -1)) }) + It("run healthcheck", func() { + bt.runPodman([]string{"run", "-d", "--name", "hc", "--health-interval", "disable", "--health-retries", "2", "--health-cmd", "ls / || exit 1", alpine.name, "top"}) + + // bogus name should result in 404 + _, err := containers.RunHealthCheck(bt.conn, "foobar") + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusNotFound)) + + // a container that has no healthcheck should be a 409 + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + _, err = containers.RunHealthCheck(bt.conn, name) + Expect(err).ToNot(BeNil()) + code, _ = bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusConflict)) + + // TODO for the life of me, i cannot get this to work. maybe another set + // of eyes will + // successful healthcheck + //status := "healthy" + //for i:=0; i < 10; i++ { + // result, err := containers.RunHealthCheck(connText, "hc") + // Expect(err).To(BeNil()) + // if result.Status != "healthy" { + // fmt.Println("Healthcheck container still starting, retrying in 1 second") + // time.Sleep(1 * time.Second) + // continue + // } + // status = result.Status + // break + //} + //Expect(status).To(Equal("healthy")) + + // TODO enable this when wait is working + // healthcheck on a stopped container should be a 409 + //err = containers.Stop(connText, "hc", nil) + //Expect(err).To(BeNil()) + //_, err = containers.Wait(connText, "hc") + //Expect(err).To(BeNil()) + //_, err = containers.RunHealthCheck(connText, "hc") + //code, _ = bindings.CheckResponseCode(err) + //Expect(code).To(BeNumerically("==", http.StatusConflict)) + }) + }) diff --git a/pkg/systemd/generate/systemdgen.go b/pkg/systemd/generate/systemdgen.go index 4410e1395..4cd7745c0 100644 --- a/pkg/systemd/generate/systemdgen.go +++ b/pkg/systemd/generate/systemdgen.go @@ -164,6 +164,26 @@ func CreateContainerSystemdUnit(info *ContainerInfo, opts Options) (string, erro "--cidfile", "%t/%n-cid", "--cgroups=no-conmon", } + + // Enforce detaching + // + // since we use systemd `Type=forking` service + // @see https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= + // when we generated systemd service file with the --new param, + // `ExecStart` will have `/usr/bin/podman run ...` + // if `info.CreateCommand` has no `-d` or `--detach` param, + // podman will run the container in default attached mode, + // as a result, `systemd start` will wait the `podman run` command exit until failed with timeout error. + hasDetachParam := false + for _, p := range info.CreateCommand[index:] { + if p == "--detach" || p == "-d" { + hasDetachParam = true + } + } + if !hasDetachParam { + command = append(command, "-d") + } + command = append(command, info.CreateCommand[index:]...) info.RunCommand = strings.Join(command, " ") info.New = true diff --git a/pkg/systemd/generate/systemdgen_test.go b/pkg/systemd/generate/systemdgen_test.go index 3749d89ce..bbdccdcf8 100644 --- a/pkg/systemd/generate/systemdgen_test.go +++ b/pkg/systemd/generate/systemdgen_test.go @@ -132,7 +132,7 @@ After=network-online.target [Service] Restart=always ExecStartPre=/usr/bin/rm -f %t/%n-pid %t/%n-cid -ExecStart=/usr/bin/podman run --conmon-pidfile %t/%n-pid --cidfile %t/%n-cid --cgroups=no-conmon --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStart=/usr/bin/podman run --conmon-pidfile %t/%n-pid --cidfile %t/%n-cid --cgroups=no-conmon -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN ExecStop=/usr/bin/podman stop --ignore --cidfile %t/%n-cid -t 42 ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/%n-cid PIDFile=%t/%n-pid @@ -142,6 +142,50 @@ Type=forking [Install] WantedBy=multi-user.target default.target` + goodNameNewDetach := `# jadda-jadda.service +# autogenerated by Podman CI + +[Unit] +Description=Podman jadda-jadda.service +Documentation=man:podman-generate-systemd(1) +Wants=network.target +After=network-online.target + +[Service] +Restart=always +ExecStartPre=/usr/bin/rm -f %t/%n-pid %t/%n-cid +ExecStart=/usr/bin/podman run --conmon-pidfile %t/%n-pid --cidfile %t/%n-cid --cgroups=no-conmon --detach --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStop=/usr/bin/podman stop --ignore --cidfile %t/%n-cid -t 42 +ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/%n-cid +PIDFile=%t/%n-pid +KillMode=none +Type=forking + +[Install] +WantedBy=multi-user.target default.target` + + goodIdNew := `# container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service +# autogenerated by Podman CI + +[Unit] +Description=Podman container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.service +Documentation=man:podman-generate-systemd(1) +Wants=network.target +After=network-online.target + +[Service] +Restart=always +ExecStartPre=/usr/bin/rm -f %t/%n-pid %t/%n-cid +ExecStart=/usr/bin/podman run --conmon-pidfile %t/%n-pid --cidfile %t/%n-cid --cgroups=no-conmon -d awesome-image:latest +ExecStop=/usr/bin/podman stop --ignore --cidfile %t/%n-cid -t 10 +ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/%n-cid +PIDFile=%t/%n-pid +KillMode=none +Type=forking + +[Install] +WantedBy=multi-user.target default.target` + tests := []struct { name string info ContainerInfo @@ -230,6 +274,51 @@ WantedBy=multi-user.target default.target` goodNameNew, false, }, + {"good with explicit short detach param", + ContainerInfo{ + Executable: "/usr/bin/podman", + ServiceName: "jadda-jadda", + ContainerName: "jadda-jadda", + RestartPolicy: "always", + PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 42, + PodmanVersion: "CI", + New: true, + CreateCommand: []string{"I'll get stripped", "container", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, + }, + goodNameNew, + false, + }, + {"good with explicit full detach param", + ContainerInfo{ + Executable: "/usr/bin/podman", + ServiceName: "jadda-jadda", + ContainerName: "jadda-jadda", + RestartPolicy: "always", + PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 42, + PodmanVersion: "CI", + New: true, + CreateCommand: []string{"I'll get stripped", "container", "run", "--detach", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, + }, + goodNameNewDetach, + false, + }, + {"good with id and no param", + ContainerInfo{ + Executable: "/usr/bin/podman", + ServiceName: "container-639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", + ContainerName: "639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401", + RestartPolicy: "always", + PIDFile: "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid", + StopTimeout: 10, + PodmanVersion: "CI", + New: true, + CreateCommand: []string{"I'll get stripped", "container", "run", "awesome-image:latest"}, + }, + goodIdNew, + false, + }, } for _, tt := range tests { test := tt diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index b4e400549..240ef1627 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" . "github.com/containers/libpod/test/utils" @@ -43,6 +44,15 @@ var _ = Describe("Podman build", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + iid := session.OutputToStringArray()[len(session.OutputToStringArray())-1] + + // Verify that OS and Arch are being set + inspect := podmanTest.PodmanNoCache([]string{"inspect", iid}) + inspect.WaitWithDefaultTimeout() + data := inspect.InspectImageJSON() + Expect(data[0].Os).To(Equal(runtime.GOOS)) + Expect(data[0].Architecture).To(Equal(runtime.GOARCH)) + session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 31131a68b..e5ab0b854 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -195,6 +195,34 @@ var _ = Describe("Podman generate systemd", func() { Expect(found).To(BeTrue()) }) + It("podman generate systemd --new without explicit detaching param", func() { + n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("--cgroups=no-conmon -d") + Expect(found).To(BeTrue()) + }) + + It("podman generate systemd --new with explicit detaching param in middle", func() { + n := podmanTest.Podman([]string{"create", "--name", "foo", "-d", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("--name foo -d alpine top") + Expect(found).To(BeTrue()) + }) + It("podman generate systemd --new pod", func() { n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"}) n.WaitWithDefaultTimeout() diff --git a/test/system/030-run.bats b/test/system/030-run.bats index b89c76981..98c65f788 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -136,21 +136,26 @@ echo $rand | 0 | $rand run_podman rmi busybox } -# 'run --rmi' deletes the image in the end unless it's used by another container. -@test "podman run --rmi - remove image" { - skip_if_remote "podman-remote does not emit 'Trying to pull' msgs" - run_podman 0 run --rmi --rm redis /bin/true - run_podman 1 image exists redis -} - - -@test "podman run --rmi - not remove image" { - skip_if_remote "podman-remote does not emit 'Trying to pull' msgs" - run_podman run redis /bin/true - run_podman images | grep redis - run_podman run --rmi --rm redis /bin/true - run_podman images | grep redis - run_podman 0 rm -a +# 'run --rmi' deletes the image in the end unless it's used by another container +@test "podman run --rmi" { + skip_if_remote + + # Name of a nonlocal image. It should be pulled in by the first 'run' + NONLOCAL_IMAGE=busybox + run_podman 1 image exists $NONLOCAL_IMAGE + + # Run a container, without --rm; this should block subsequent --rmi + run_podman run --name keepme $NONLOCAL_IMAGE /bin/true + run_podman image exists $NONLOCAL_IMAGE + + # Now try running with --rmi : it should succeed, but not remove the image + run_podman run --rmi --rm $NONLOCAL_IMAGE /bin/true + run_podman image exists $NONLOCAL_IMAGE + + # Remove the stray container, and run one more time with --rmi. + run_podman rm keepme + run_podman run --rmi --rm $NONLOCAL_IMAGE /bin/true + run_podman 1 image exists $NONLOCAL_IMAGE } # vim: filetype=sh diff --git a/troubleshooting.md b/troubleshooting.md index 0f9440799..010d33f81 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -390,7 +390,7 @@ Choose one of the following: * Complete the build operation as a privileged user. * Install and configure fuse-overlayfs. * Install the fuse-overlayfs package for your Linux Distribution. - * Add `mount_program = "/usr/bin/fuse-overlayfs` under `[storage.options]` in your `~/.config/containers/storage.conf` file. + * Add `mount_program = "/usr/bin/fuse-overlayfs"` under `[storage.options]` in your `~/.config/containers/storage.conf` file. ### 16) rhel7-init based images don't work with cgroups v2 diff --git a/vendor/github.com/containers/buildah/CONTRIBUTING.md b/vendor/github.com/containers/buildah/CONTRIBUTING.md index 0178a517c..553cb15dc 100644 --- a/vendor/github.com/containers/buildah/CONTRIBUTING.md +++ b/vendor/github.com/containers/buildah/CONTRIBUTING.md @@ -178,7 +178,7 @@ that has been setup. #### Buildah Mailing List -You can join the Buildah mailing list by sending an email to `buildah-join@lists.buildah.io` with the word `subscribe` in the subject. You can also go to this [page](https://lists.podman.io/admin/lists/buildah.lists.buildah.io/), then scroll down to the bottom of the page and enter your email and optionally name, then click on the "Subscribe" buton. +You can join the Buildah mailing list by sending an email to `buildah-join@lists.buildah.io` with the word `subscribe` in the subject. You can also go to this [page](https://lists.podman.io/admin/lists/buildah.lists.buildah.io/), then scroll down to the bottom of the page and enter your email and optionally name, then click on the "Subscribe" button. #### GitHub You can also use the github diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 6d1d479b1..2ece11acd 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -27,7 +27,7 @@ const ( Package = "buildah" // Version for the Package. Bump version in contrib/rpm/buildah.spec // too. - Version = "1.14.2" + Version = "1.15.0-dev" // The value we use to identify what type of information, currently a // serialized Builder structure, we are using as per-container state. // This should only be changed when we make incompatible changes to diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go index 482fef693..8dfa8aba0 100644 --- a/vendor/github.com/containers/buildah/chroot/run.go +++ b/vendor/github.com/containers/buildah/chroot/run.go @@ -656,7 +656,7 @@ func runUsingChrootExecMain() { // Set the hostname. We're already in a distinct UTS namespace and are admins in the user // namespace which created it, so we shouldn't get a permissions error, but seccomp policy // might deny our attempt to call sethostname() anyway, so log a debug message for that. - if options.Spec.Hostname != "" { + if options.Spec != nil && options.Spec.Hostname != "" { if err := unix.Sethostname([]byte(options.Spec.Hostname)); err != nil { logrus.Debugf("failed to set hostname %q for process: %v", options.Spec.Hostname, err) } diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index 72fbffe2c..97b2eeae8 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -4,9 +4,9 @@ go 1.12 require ( github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 - github.com/containers/common v0.4.2 + github.com/containers/common v0.5.0 github.com/containers/image/v5 v5.2.1 - github.com/containers/storage v1.16.1 + github.com/containers/storage v1.16.2 github.com/cyphar/filepath-securejoin v0.2.2 github.com/docker/distribution v2.7.1+incompatible github.com/docker/go-metrics v0.0.1 // indirect @@ -25,7 +25,7 @@ require ( github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runtime-spec v0.1.2-0.20190618234442-a950415649c7 github.com/opencontainers/runtime-tools v0.9.0 - github.com/opencontainers/selinux v1.3.3 + github.com/opencontainers/selinux v1.4.0 github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 github.com/openshift/imagebuilder v1.1.1 github.com/pkg/errors v0.9.1 diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index 79dc064ce..191eb1f11 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -103,6 +103,14 @@ github.com/containers/common v0.4.1 h1:Uu7f2ZDM/5xsqOkZwIEVKSjUI3YxKjvNIY5x57kja github.com/containers/common v0.4.1/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/common v0.4.2 h1:O5d1gj/xdpQdZi0MEivRQ/7AeRaVeHdbSP/bvShw458= github.com/containers/common v0.4.2/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= +github.com/containers/common v0.4.3 h1:TJ7UQxB8wf//IY4LNZobswrTjbhIjXpidrRbCA2l+kg= +github.com/containers/common v0.4.3/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= +github.com/containers/common v0.4.4 h1:oXQUPDQOIQ+XmQ2cWyLCs2TctDfISykAr1gEa3CNwlQ= +github.com/containers/common v0.4.4/go.mod h1:vMkHkvczHslJbUj8xasSQmdNrLUgZYuUxVNGJDfjRIQ= +github.com/containers/common v0.5.0 h1:ZAef7h3oO46PcbTyfooZf8XLHrYad+GkhSu3EhH6P24= +github.com/containers/common v0.5.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= +github.com/containers/common v1.0.0 h1:sZB48LzGP4bP1CmrkQIFUzdUVBysqRv3kWVk4+qbaVA= +github.com/containers/common v1.0.0/go.mod h1:m62kenckrWi5rZx32kaLje2Og0hpf6NsaTBn6+b+Oys= github.com/containers/conmon v2.0.10+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ= github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA= @@ -149,6 +157,8 @@ github.com/containers/storage v1.16.0 h1:sD+s7BmiNBh61CuHN3j8PXGCwMtV9zPVJETAlsh github.com/containers/storage v1.16.0/go.mod h1:nqN09JSi1/RSI1UAUwDYXPRiGSlq5FPbNkN/xb0TfG0= github.com/containers/storage v1.16.1 h1:gVLVqbqaoyopLJbcQ9PQdsnm8SzVy6Vw24fofwMgkE0= github.com/containers/storage v1.16.1/go.mod h1:toFp72SLn/iyJ6YbrnrZ0bW63aH2Qw3dA8JVwL4ADPo= +github.com/containers/storage v1.16.2 h1:S77Y+lmJcnGoPEZB2OOrTrRGyjT8viDCGyhVNNz78h8= +github.com/containers/storage v1.16.2/go.mod h1:/RNmsK01ajCL+VtMSi3W8kHzpBwN+Q5gLYWgfw5wlMg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -281,6 +291,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= @@ -495,6 +506,8 @@ github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmN github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.3.3 h1:RX0wAeqtvVSYQcr017X3pFXPkLEtB6V4NjRD7gVQgg4= github.com/opencontainers/selinux v1.3.3/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= +github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= +github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316 h1:enQG2QUGwug4fR1yM6hL0Fjzx6Km/exZY6RbSPwMu3o= github.com/openshift/api v0.0.0-20200106203948-7ab22a2c8316/go.mod h1:dv+J0b/HWai0QnMVb37/H0v36klkLBi2TNpPeWDxX10= github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s55wx8JIG/CKnewev892HifTBrtKzMdvgB3rm4rxC2s= diff --git a/vendor/github.com/containers/buildah/image.go b/vendor/github.com/containers/buildah/image.go index d333442b8..94e97d870 100644 --- a/vendor/github.com/containers/buildah/image.go +++ b/vendor/github.com/containers/buildah/image.go @@ -627,7 +627,7 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo, logrus.Debugf("error checking for layer %q in %q: %v", blob.Digest.String(), path, err) } } - if err != nil { + if err != nil || layerFile == nil { logrus.Debugf("error reading layer %q: %v", blob.Digest.String(), err) return nil, -1, errors.Wrapf(err, "error opening file %q to buffer layer blob", filepath.Join(i.path, blob.Digest.String())) } diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go index 6216dac97..8e49395a4 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go @@ -238,7 +238,13 @@ func (s *StageExecutor) volumeCacheRestore() error { if err := os.Chmod(archivedPath, st.Mode()); err != nil { return errors.Wrapf(err, "error restoring permissions on %q", archivedPath) } - if err := os.Chown(archivedPath, 0, 0); err != nil { + uid := 0 + gid := 0 + if st.Sys() != nil { + uid = util.UID(st) + gid = util.GID(st) + } + if err := os.Chown(archivedPath, uid, gid); err != nil { return errors.Wrapf(err, "error setting ownership on %q", archivedPath) } if err := os.Chtimes(archivedPath, st.ModTime(), st.ModTime()); err != nil { diff --git a/vendor/github.com/containers/buildah/pull.go b/vendor/github.com/containers/buildah/pull.go index 4a38abeab..cbb98cbcf 100644 --- a/vendor/github.com/containers/buildah/pull.go +++ b/vendor/github.com/containers/buildah/pull.go @@ -216,8 +216,13 @@ func Pull(ctx context.Context, imageName string, options PullOptions) (imageID s } else { imageID = img.ID } + if errs == nil { + err = nil + } else { + err = errs.ErrorOrNil() + } - return imageID, errs.ErrorOrNil() + return imageID, err } func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageReference, options PullOptions, sc *types.SystemContext) (types.ImageReference, error) { diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index 6df6ef41a..6e4d31d78 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -702,7 +702,9 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b return 1, errors.Wrapf(err, "error creating pipe for notifying to stop stdio") } finishedCopy := make(chan struct{}) + var pargs []string if spec.Process != nil { + pargs = spec.Process.Args if spec.Process.Terminal { copyConsole = true // Create a listening socket for accepting the container's terminal's PTY master. @@ -773,7 +775,7 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b logrus.Debugf("Running %q", create.Args) err = create.Run() if err != nil { - return 1, errors.Wrapf(err, "error creating container for %v: %s", spec.Process.Args, runCollectOutput(errorFds, closeBeforeReadingErrorFds)) + return 1, errors.Wrapf(err, "error creating container for %v: %s", pargs, runCollectOutput(errorFds, closeBeforeReadingErrorFds)) } defer func() { err2 := del.Run() @@ -808,7 +810,7 @@ func runUsingRuntime(isolation Isolation, options RunOptions, configureNetwork b }() if configureNetwork { - teardown, err := runConfigureNetwork(isolation, options, configureNetworks, pid, containerName, spec.Process.Args) + teardown, err := runConfigureNetwork(isolation, options, configureNetworks, pid, containerName, pargs) if teardown != nil { defer teardown() } @@ -1044,6 +1046,9 @@ func runConfigureNetwork(isolation Isolation, options RunOptions, configureNetwo } continue } + if nc.Network == nil { + continue + } cl, err := libcni.ConfListFromConf(nc) if err != nil { return nil, errors.Wrapf(err, "error converting networking configuration from file %q for %v", file, command) @@ -1450,8 +1455,13 @@ func runUsingRuntimeMain() { if err := setChildProcess(); err != nil { os.Exit(1) } + var ospec *specs.Spec + if options.Spec != nil { + ospec = options.Spec + } + // Run the container, start to finish. - status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, options.Spec, options.BundlePath, options.ContainerName) + status, err := runUsingRuntime(options.Isolation, options.Options, options.ConfigureNetwork, options.ConfigureNetworks, options.MoreCreateArgs, ospec, options.BundlePath, options.ContainerName) if err != nil { fmt.Fprintf(os.Stderr, "error running container: %v\n", err) os.Exit(1) diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index 05d661b58..a358b7c54 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -365,7 +365,7 @@ func GetHostIDs(uidmap, gidmap []specs.LinuxIDMapping, uid, gid uint32) (uint32, // GetHostRootIDs uses ID mappings in spec to compute the host-level IDs that will // correspond to UID/GID 0/0 in the container. func GetHostRootIDs(spec *specs.Spec) (uint32, uint32, error) { - if spec.Linux == nil { + if spec == nil || spec.Linux == nil { return 0, 0, nil } return GetHostIDs(spec.Linux.UIDMappings, spec.Linux.GIDMappings, 0, 0) @@ -455,7 +455,7 @@ func FindLocalRuntime(runtime string) string { logrus.Debugf("Error loading container config when searching for local runtime.") return localRuntime } - for _, val := range conf.Libpod.OCIRuntimes[runtime] { + for _, val := range conf.Engine.OCIRuntimes[runtime] { if fileExistsAndNotADir(val) { localRuntime = val break diff --git a/vendor/github.com/containers/buildah/util/util_linux.go b/vendor/github.com/containers/buildah/util/util_linux.go index cca1f9e7e..1a13699df 100644 --- a/vendor/github.com/containers/buildah/util/util_linux.go +++ b/vendor/github.com/containers/buildah/util/util_linux.go @@ -1,6 +1,7 @@ package util import ( + "os" "syscall" "golang.org/x/sys/unix" @@ -18,3 +19,11 @@ func IsCgroup2UnifiedMode() (bool, error) { }) return isUnified, isUnifiedErr } + +func UID(st os.FileInfo) int { + return int(st.Sys().(*syscall.Stat_t).Uid) +} + +func GID(st os.FileInfo) int { + return int(st.Sys().(*syscall.Stat_t).Gid) +} diff --git a/vendor/github.com/containers/buildah/util/util_unsupported.go b/vendor/github.com/containers/buildah/util/util_unsupported.go index 05a68f60b..8810536a6 100644 --- a/vendor/github.com/containers/buildah/util/util_unsupported.go +++ b/vendor/github.com/containers/buildah/util/util_unsupported.go @@ -2,7 +2,19 @@ package util +import ( + "os" +) + // IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode. func IsCgroup2UnifiedMode() (bool, error) { return false, nil } + +func UID(st os.FileInfo) int { + return 0 +} + +func GID(st os.FileInfo) int { + return 0 +} diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 4b536b3a5..0a09d994e 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -12,7 +12,6 @@ import ( "github.com/BurntSushi/toml" "github.com/containers/common/pkg/capabilities" "github.com/containers/common/pkg/unshare" - "github.com/containers/storage" units "github.com/docker/go-units" selinux "github.com/opencontainers/selinux/go-selinux" "github.com/pkg/errors" @@ -29,14 +28,14 @@ const ( ) // RuntimeStateStore is a constant indicating which state store implementation -// should be used by libpod +// should be used by engine type RuntimeStateStore int const ( // InvalidStateStore is an invalid state store InvalidStateStore RuntimeStateStore = iota // InMemoryStateStore is an in-memory state that will not persist data - // on containers and pods between libpod instances or after system + // on containers and pods between engine instances or after system // reboot InMemoryStateStore RuntimeStateStore = iota // SQLiteStateStore is a state backed by a SQLite database @@ -46,12 +45,24 @@ const ( BoltDBStateStore RuntimeStateStore = iota ) +// PullPolicy whether to pull new image +type PullPolicy int + +const ( + // PullImageAlways always try to pull new image when create or run + PullImageAlways PullPolicy = iota + // PullImageMissing pulls image if it is not locally + PullImageMissing + // PullImageNever will never pull new image + PullImageNever +) + // Config contains configuration options for container tools type Config struct { // Containers specify settings that configure how containers will run ont the system Containers ContainersConfig `toml:"containers"` - // Libpod specifies how the container engine based on Libpod will run - Libpod LibpodConfig `toml:"libpod"` + // Engine specifies how the container engine based on Engine will run + Engine EngineConfig `toml:"engine"` // Network section defines the configuration of CNI Plugins Network NetworkConfig `toml:"network"` } @@ -164,8 +175,12 @@ type ContainersConfig struct { UserNSSize int `toml:"userns_size"` } -// LibpodConfig contains configuration options used to set up a libpod runtime -type LibpodConfig struct { +// EngineConfig contains configuration options used to set up a engine runtime +type EngineConfig struct { + // CgroupCheck indicates the configuration has been rewritten after an + // upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2. + CgroupCheck bool `toml:"cgroup_check,omitempty"` + // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs" // and "systemd". CgroupManager string `toml:"cgroup_manager"` @@ -183,7 +198,7 @@ type LibpodConfig struct { //DetachKeys is the sequence of keys used to detach a container. DetachKeys string `toml:"detach_keys"` - // EnablePortReservation determines whether libpod will reserve ports on the + // EnablePortReservation determines whether engine will reserve ports on the // host when they are forwarded to containers. When enabled, when ports are // forwarded to containers, they are held open by conmon as long as the // container is running, ensuring that they cannot be reused by other @@ -220,9 +235,9 @@ type LibpodConfig struct { // LockType is the type of locking to use. LockType string `toml:"lock_type,omitempty"` - // Namespace is the libpod namespace to use. Namespaces are used to create + // Namespace is the engine namespace to use. Namespaces are used to create // scopes to separate containers and pods in the state. When namespace is - // set, libpod will only view containers and pods in the same namespace. All + // set, engine will only view containers and pods in the same namespace. All // containers and pods created will default to the namespace set here. A // namespace of "", the empty string, is equivalent to no namespace, and all // containers and pods will be visible. The default namespace is "". @@ -244,6 +259,15 @@ type LibpodConfig struct { // OCIRuntimes are the set of configured OCI runtimes (default is runc). OCIRuntimes map[string][]string `toml:"runtimes"` + // PullPolicy determines whether to pull image before creating or running a container + // default is "missing" + PullPolicy string `toml:"pull_policy"` + // RuntimePath is the path to OCI runtime binary for launching containers. + // The first path pointing to a valid file will be used This is used only + // when there are no OCIRuntime/OCIRuntimes defined. It is used only to be + // backward compatible with older versions of Podman. + RuntimePath []string `toml:"runtime_path,omitempty"` + // RuntimeSupportsJSON is the list of the OCI runtimes that support // --format=json. RuntimeSupportsJSON []string `toml:"runtime_supports_json"` @@ -253,7 +277,7 @@ type LibpodConfig struct { RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups"` // SetOptions contains a subset of config options. It's used to indicate if - // a given option has either been set by the user or by a parsed libpod + // a given option has either been set by the user or by the parsed // configuration file. If not, the corresponding option might be // overwritten by values from the database. This behavior guarantees // backwards compat with older version of libpod and Podman. @@ -278,11 +302,6 @@ type LibpodConfig struct { // before sending kill signal. StopTimeout uint `toml:"stop_timeout"` - // StorageConfig is the configuration used by containers/storage Not - // included in the on-disk config, use the dedicated containers/storage - // configuration file instead. - StorageConfig storage.StoreOptions `toml:"-"` - // TmpDir is the path to a temporary directory to store per-boot container // files. Must be stored in a tmpfs. TmpDir string `toml:"tmp_dir"` @@ -294,7 +313,7 @@ type LibpodConfig struct { } // SetOptions contains a subset of options in a Config. It's used to indicate if -// a given option has either been set by the user or by a parsed libpod +// a given option has either been set by the user or by a parsed engine // configuration file. If not, the corresponding option might be overwritten by // values from the database. This behavior guarantees backwards compat with // older version of libpod and Podman. @@ -364,16 +383,9 @@ func NewConfig(userConfigPath string) (*Config, error) { return nil, err } - // If the caller specified a config path to use, then we read this - // rather then using the system defaults. - if userConfigPath != "" { - var err error - // readConfigFromFile reads in container config in the specified - // file and then merge changes with the current default. - config, err = readConfigFromFile(userConfigPath, config) - if err != nil { - return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath) - } + // read libpod.conf and convert the config to *Config + if err = newLibpodConfig(config); err != nil && !os.IsNotExist(err) { + logrus.Errorf("error reading libpod.conf: %v", err) } // Now, gather the system configs and merge them as needed. @@ -392,7 +404,18 @@ func NewConfig(userConfigPath string) (*Config, error) { logrus.Debugf("Merged system config %q: %v", path, config) } - config.checkCgroupsAndAdjustConfig() + // If the caller specified a config path to use, then we read it to + // override the system defaults. + if userConfigPath != "" { + var err error + // readConfigFromFile reads in container config in the specified + // file and then merge changes with the current default. + config, err = readConfigFromFile(userConfigPath, config) + if err != nil { + return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath) + } + logrus.Debugf("Merged user config %q: %v", userConfigPath, config) + } config.addCAPPrefix() if err := config.Validate(); err != nil { @@ -412,14 +435,14 @@ func readConfigFromFile(path string, config *Config) (*Config, error) { if err != nil { return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err) } - if config.Libpod.VolumePath != "" { - config.Libpod.VolumePathSet = true + if config.Engine.VolumePath != "" { + config.Engine.VolumePathSet = true } - if config.Libpod.StaticDir != "" { - config.Libpod.StaticDirSet = true + if config.Engine.StaticDir != "" { + config.Engine.StaticDirSet = true } - if config.Libpod.TmpDir != "" { - config.Libpod.TmpDirSet = true + if config.Engine.TmpDir != "" { + config.Engine.TmpDirSet = true } return config, err @@ -455,11 +478,11 @@ func systemConfigs() ([]string, error) { return configs, nil } -// checkCgroupsAndAdjustConfig checks if we're running rootless with the systemd +// CheckCgroupsAndAdjustConfig checks if we're running rootless with the systemd // cgroup manager. In case the user session isn't available, we're switching the // cgroup manager to cgroupfs. Note, this only applies to rootless. -func (c *Config) checkCgroupsAndAdjustConfig() { - if !unshare.IsRootless() || c.Libpod.CgroupManager != SystemdCgroupsManager { +func (c *Config) CheckCgroupsAndAdjustConfig() { + if !unshare.IsRootless() || c.Engine.CgroupManager != SystemdCgroupsManager { return } @@ -475,7 +498,7 @@ func (c *Config) checkCgroupsAndAdjustConfig() { logrus.Warningf("For using systemd, you may need to login using an user session") logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID()) logrus.Warningf("Falling back to --cgroup-manager=cgroupfs") - c.Libpod.CgroupManager = CgroupfsCgroupsManager + c.Engine.CgroupManager = CgroupfsCgroupsManager } } @@ -495,32 +518,47 @@ func (c *Config) addCAPPrefix() { func (c *Config) Validate() error { if err := c.Containers.Validate(); err != nil { - return errors.Wrapf(err, "containers config") + return errors.Wrapf(err, " error validating containers config") } if !c.Containers.EnableLabeling { selinux.SetDisabled() } + if err := c.Engine.Validate(); err != nil { + return errors.Wrapf(err, "error validating engine configs") + } + + if err := c.Network.Validate(); err != nil { + return errors.Wrapf(err, "error validating network configs") + } + return nil } -// Validate is the main entry point for Libpod configuration validation +// Validate is the main entry point for Engine configuration validation // It returns an `error` on validation failure, otherwise // `nil`. -func (c *LibpodConfig) Validate() error { +func (c *EngineConfig) Validate() error { // Relative paths can cause nasty bugs, because core paths we use could // shift between runs (or even parts of the program - the OCI runtime // uses a different working directory than we do, for example. - if !filepath.IsAbs(c.StaticDir) { + if c.StaticDir != "" && !filepath.IsAbs(c.StaticDir) { return fmt.Errorf("static directory must be an absolute path - instead got %q", c.StaticDir) } - if !filepath.IsAbs(c.TmpDir) { + if c.TmpDir != "" && !filepath.IsAbs(c.TmpDir) { return fmt.Errorf("temporary directory must be an absolute path - instead got %q", c.TmpDir) } - if !filepath.IsAbs(c.VolumePath) { + if c.VolumePath != "" && !filepath.IsAbs(c.VolumePath) { return fmt.Errorf("volume path must be an absolute path - instead got %q", c.VolumePath) } + + // Check if the pullPolicy from containers.conf is valid + // if it is invalid returns the error + pullPolicy := strings.ToLower(c.PullPolicy) + if _, err := ValidatePullPolicy(pullPolicy); err != nil { + return errors.Wrapf(err, "invalid pull type from containers.conf %q", c.PullPolicy) + } return nil } @@ -583,69 +621,21 @@ func (c *NetworkConfig) Validate() error { return errors.Errorf("invalid cni_plugin_dirs: %s", strings.Join(c.CNIPluginDirs, ",")) } -// DBConfig is a set of Libpod runtime configuration settings that are saved in -// a State when it is first created, and can subsequently be retrieved. -type DBConfig struct { - LibpodRoot string - LibpodTmp string - StorageRoot string - StorageTmp string - GraphDriver string - VolumePath string -} - -// MergeDBConfig merges the configuration from the database. -func (c *Config) MergeDBConfig(dbConfig *DBConfig) error { - - if !c.Libpod.StorageConfigRunRootSet && dbConfig.StorageTmp != "" { - if c.Libpod.StorageConfig.RunRoot != dbConfig.StorageTmp && - c.Libpod.StorageConfig.RunRoot != "" { - logrus.Debugf("Overriding run root %q with %q from database", - c.Libpod.StorageConfig.RunRoot, dbConfig.StorageTmp) - } - c.Libpod.StorageConfig.RunRoot = dbConfig.StorageTmp - } - - if !c.Libpod.StorageConfigGraphRootSet && dbConfig.StorageRoot != "" { - if c.Libpod.StorageConfig.GraphRoot != dbConfig.StorageRoot && - c.Libpod.StorageConfig.GraphRoot != "" { - logrus.Debugf("Overriding graph root %q with %q from database", - c.Libpod.StorageConfig.GraphRoot, dbConfig.StorageRoot) - } - c.Libpod.StorageConfig.GraphRoot = dbConfig.StorageRoot - } - - if !c.Libpod.StorageConfigGraphDriverNameSet && dbConfig.GraphDriver != "" { - if c.Libpod.StorageConfig.GraphDriverName != dbConfig.GraphDriver && - c.Libpod.StorageConfig.GraphDriverName != "" { - logrus.Errorf("User-selected graph driver %q overwritten by graph driver %q from database - delete libpod local files to resolve", - c.Libpod.StorageConfig.GraphDriverName, dbConfig.GraphDriver) - } - c.Libpod.StorageConfig.GraphDriverName = dbConfig.GraphDriver - } - - if !c.Libpod.StaticDirSet && dbConfig.LibpodRoot != "" { - if c.Libpod.StaticDir != dbConfig.LibpodRoot && c.Libpod.StaticDir != "" { - logrus.Debugf("Overriding static dir %q with %q from database", c.Libpod.StaticDir, dbConfig.LibpodRoot) - } - c.Libpod.StaticDir = dbConfig.LibpodRoot - } - - if !c.Libpod.TmpDirSet && dbConfig.LibpodTmp != "" { - if c.Libpod.TmpDir != dbConfig.LibpodTmp && c.Libpod.TmpDir != "" { - logrus.Debugf("Overriding tmp dir %q with %q from database", c.Libpod.TmpDir, dbConfig.LibpodTmp) - } - c.Libpod.TmpDir = dbConfig.LibpodTmp - c.Libpod.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log") - } - - if !c.Libpod.VolumePathSet && dbConfig.VolumePath != "" { - if c.Libpod.VolumePath != dbConfig.VolumePath && c.Libpod.VolumePath != "" { - logrus.Debugf("Overriding volume path %q with %q from database", c.Libpod.VolumePath, dbConfig.VolumePath) - } - c.Libpod.VolumePath = dbConfig.VolumePath +// ValidatePullPolicy check if the pullPolicy from CLI is valid and returns the valid enum type +// if the value from CLI or containers.conf is invalid returns the error +func ValidatePullPolicy(pullPolicy string) (PullPolicy, error) { + switch pullPolicy { + case "always": + return PullImageAlways, nil + case "missing": + return PullImageMissing, nil + case "never": + return PullImageNever, nil + case "": + return PullImageMissing, nil + default: + return PullImageMissing, errors.Errorf("invalid pull policy %q", pullPolicy) } - return nil } // FindConmon iterates over (*Config).ConmonPath and returns the path @@ -653,7 +643,7 @@ func (c *Config) MergeDBConfig(dbConfig *DBConfig) error { // to do a path lookup of "conmon". func (c *Config) FindConmon() (string, error) { foundOutdatedConmon := false - for _, path := range c.Libpod.ConmonPath { + for _, path := range c.Engine.ConmonPath { stat, err := os.Stat(path) if err != nil { continue @@ -689,7 +679,7 @@ func (c *Config) FindConmon() (string, error) { return "", errors.Wrapf(ErrInvalidArg, "could not find a working conmon binary (configured options: %v)", - c.Libpod.ConmonPath) + c.Engine.ConmonPath) } // GetDefaultEnv returns the environment variables for the container. diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 91106b576..b01db5f88 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -1,9 +1,9 @@ # The containers configuration file specifies all of the available configuration -# command-line options/flags for container runtime tools like Podman & Buildah, +# command-line options/flags for container engine tools like Podman & Buildah, # but in a TOML format that can be easily modified and versioned. # Please refer to containers.conf(5) for details of all configuration options. -# Not all container tools implement all of the options. +# Not all container engines implement all of the options. # All of the options have hard coded defaults and these options will override # the built in defaults. Users can then override these options via the command # line. Container engines will read containers.conf files in up to three @@ -30,7 +30,7 @@ # # volumes = [] -# Used to change the name of the default AppArmor profile of container engines. +# Used to change the name of the default AppArmor profile of container engine. # # apparmor_profile = "container-default" @@ -143,7 +143,8 @@ # # ipcns = "private" -# container engines use container separation using MAC(SELinux) labeling. +# Flag tells container engine to whether to use container separation using +# MAC(SELinux)labeling or not. # Flag is ignored on label disabled systems. # # label = true @@ -167,7 +168,7 @@ # # netns = "private" -# Create /etc/hosts for the container. By default, container engines manage +# Create /etc/hosts for the container. By default, container engine manage # /etc/hosts, automatically adding the container's own IP address. # # no_hosts = false @@ -228,7 +229,7 @@ # # network_config_dir = "/etc/cni/net.d/" -[libpod] +[engine] # Cgroup management implementation used for the runtime. # Valid options “systemd” or “cgroupfs” @@ -260,7 +261,7 @@ # # detach_keys = "ctrl-p,ctrl-q" -# Determines whether libpod will reserve ports on the host when they are +# Determines whether engine will reserve ports on the host when they are # forwarded to containers. When enabled, when ports are forwarded to containers, # ports are held open by as long as the container is running, ensuring that # they cannot be reused by other programs on the host. However, this can cause @@ -297,8 +298,8 @@ # # lock_type** = "shm" -# Default libpod namespace -# If libpod is joined to a namespace, it will see only containers and pods +# Default engine namespace +# If engine is joined to a namespace, it will see only containers and pods # that were created in the same namespace, and will create new containers and # pods in that namespace. # The default namespace is "", which corresponds to no namespace. When no @@ -316,7 +317,10 @@ # # num_locks = 2048 -# Directory for persistent libpod files (database, etc) +# Whether to pull new image before running a container +# pull_policy = "missing" + +# Directory for persistent engine files (database, etc) # By default, this will be configured relative to where the containers/storage # stores containers # Uncomment to change location from this default @@ -339,12 +343,12 @@ # runtime = "runc" # List of the OCI runtimes that support --format=json. When json is supported -# libpod will use it for reporting nicer errors. +# engine will use it for reporting nicer errors. # # runtime_supports_json = ["crun", "runc"] # Paths to look for a valid OCI runtime (runc, runv, etc) -[libpod.runtimes] +[engine.runtimes] # runc = [ # "/usr/bin/runc", # "/usr/sbin/runc", @@ -368,7 +372,7 @@ # Number of seconds to wait for container to exit before sending kill signal. #stop_timeout = 10 -# The [libpod.runtimes] table MUST be the last entry in this file. +# The [engine.runtimes] table MUST be the last entry in this file. # (Unless another table is added) # TOML does not provide a way to end a table other than a further table being # defined, so every key hereafter will be part of [runtimes] and not the main diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 6b83d7703..dca320d87 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -98,6 +98,8 @@ const ( // DefaultPidsLimit is the default value for maximum number of processes // allowed inside a container DefaultPidsLimit = 2048 + // DefaultPullPolicy pulls the image if it does not exist locally + DefaultPullPolicy = "missing" // DefaultRootlessSignaturePolicyPath is the default value for the // rootless policy.json file. DefaultRootlessSignaturePolicyPath = ".config/containers/policy.json" @@ -116,7 +118,7 @@ const ( // DefaultConfig defines the default values from containers.conf func DefaultConfig() (*Config, error) { - defaultLibpodConfig, err := defaultConfigFromMemory() + defaultEngineConfig, err := defaultConfigFromMemory() if err != nil { return nil, err } @@ -175,14 +177,14 @@ func DefaultConfig() (*Config, error) { NetworkConfigDir: cniConfigDir, CNIPluginDirs: cniBinDir, }, - Libpod: *defaultLibpodConfig, + Engine: *defaultEngineConfig, }, nil } -// defaultConfigFromMemory returns a default libpod configuration. Note that the +// defaultConfigFromMemory returns a default engine configuration. Note that the // config is different for root and rootless. It also parses the storage.conf. -func defaultConfigFromMemory() (*LibpodConfig, error) { - c := new(LibpodConfig) +func defaultConfigFromMemory() (*EngineConfig, error) { + c := new(EngineConfig) tmp, err := defaultTmpDir() if err != nil { return nil, err @@ -201,7 +203,6 @@ func defaultConfigFromMemory() (*LibpodConfig, error) { } c.StaticDir = filepath.Join(storeOpts.GraphRoot, "libpod") c.VolumePath = filepath.Join(storeOpts.GraphRoot, "volumes") - c.StorageConfig = storeOpts c.HooksDir = DefaultHooksDirs c.ImageDefaultTransport = _defaultTransport @@ -249,6 +250,7 @@ func defaultConfigFromMemory() (*LibpodConfig, error) { "/usr/local/sbin/conmon", "/run/current-system/sw/bin/conmon", } + c.PullPolicy = DefaultPullPolicy c.RuntimeSupportsJSON = []string{ "crun", "runc", diff --git a/vendor/github.com/containers/common/pkg/config/libpodConfig.go b/vendor/github.com/containers/common/pkg/config/libpodConfig.go new file mode 100644 index 000000000..be168208b --- /dev/null +++ b/vendor/github.com/containers/common/pkg/config/libpodConfig.go @@ -0,0 +1,382 @@ +package config + +/* libpodConfig.go contains deprecated functionality and should not be used any longer */ + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + + "github.com/BurntSushi/toml" + "github.com/containers/common/pkg/unshare" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +const ( + // _rootlessConfigPath is the path to the rootless libpod.conf in $HOME. + _rootlessConfigPath = ".config/containers/libpod.conf" + + // _rootConfigPath is the path to the libpod configuration file + // This file is loaded to replace the builtin default config before + // runtime options (e.g. WithStorageConfig) are applied. + // If it is not present, the builtin default config is used instead + // This path can be overridden when the runtime is created by using + // NewRuntimeFromConfig() instead of NewRuntime(). + _rootConfigPath = _installPrefix + "/share/containers/libpod.conf" + + // _rootOverrideConfigPath is the path to an override for the default libpod + // configuration file. If OverrideConfigPath exists, it will be used in + // place of the configuration file pointed to by ConfigPath. + _rootOverrideConfigPath = _etcDir + "/containers/libpod.conf" +) + +// ConfigFromLibpod contains configuration options used to set up a libpod runtime +type ConfigFromLibpod struct { + // NOTE: when changing this struct, make sure to update (*Config).Merge(). + + // SetOptions contains a subset of config options. It's used to indicate if + // a given option has either been set by the user or by a parsed libpod + // configuration file. If not, the corresponding option might be + // overwritten by values from the database. This behavior guarantees + // backwards compat with older version of libpod and Podman. + SetOptions + + // VolumePath is the default location that named volumes will be created + // under. This convention is followed by the default volume driver, but + // may not be by other drivers. + VolumePath string `toml:"volume_path,omitempty"` + + // ImageDefaultTransport is the default transport method used to fetch + // images. + ImageDefaultTransport string `toml:"image_default_transport,omitempty"` + + // SignaturePolicyPath is the path to a signature policy to use for + // validating images. If left empty, the containers/image default signature + // policy will be used. + SignaturePolicyPath string `toml:"signature_policy_path,omitempty"` + + // OCIRuntime is the OCI runtime to use. + OCIRuntime string `toml:"runtime,omitempty"` + + // OCIRuntimes are the set of configured OCI runtimes (default is runc). + OCIRuntimes map[string][]string `toml:"runtimes,omitempty"` + + // RuntimeSupportsJSON is the list of the OCI runtimes that support + // --format=json. + RuntimeSupportsJSON []string `toml:"runtime_supports_json,omitempty"` + + // RuntimeSupportsNoCgroups is a list of OCI runtimes that support + // running containers without CGroups. + RuntimeSupportsNoCgroups []string `toml:"runtime_supports_nocgroups,omitempty"` + + // RuntimePath is the path to OCI runtime binary for launching containers. + // The first path pointing to a valid file will be used This is used only + // when there are no OCIRuntime/OCIRuntimes defined. It is used only to be + // backward compatible with older versions of Podman. + RuntimePath []string `toml:"runtime_path,omitempty"` + + // ConmonPath is the path to the Conmon binary used for managing containers. + // The first path pointing to a valid file will be used. + ConmonPath []string `toml:"conmon_path,omitempty"` + + // ConmonEnvVars are environment variables to pass to the Conmon binary + // when it is launched. + ConmonEnvVars []string `toml:"conmon_env_vars,omitempty"` + + // CGroupManager is the CGroup Manager to use Valid values are "cgroupfs" + // and "systemd". + CgroupManager string `toml:"cgroup_manager,omitempty"` + + // InitPath is the path to the container-init binary. + InitPath string `toml:"init_path,omitempty"` + + // StaticDir is the path to a persistent directory to store container + // files. + StaticDir string `toml:"static_dir,omitempty"` + + // TmpDir is the path to a temporary directory to store per-boot container + // files. Must be stored in a tmpfs. + TmpDir string `toml:"tmp_dir,omitempty"` + + // MaxLogSize is the maximum size of container logfiles. + MaxLogSize int64 `toml:"max_log_size,omitempty"` + + // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime. + NoPivotRoot bool `toml:"no_pivot_root,omitempty"` + + // CNIConfigDir sets the directory where CNI configuration files are + // stored. + CNIConfigDir string `toml:"cni_config_dir,omitempty"` + + // CNIPluginDir sets a number of directories where the CNI network + // plugins can be located. + CNIPluginDir []string `toml:"cni_plugin_dir,omitempty"` + + // CNIDefaultNetwork is the network name of the default CNI network + // to attach pods to. + CNIDefaultNetwork string `toml:"cni_default_network,omitempty"` + + // HooksDir holds paths to the directories containing hooks + // configuration files. When the same filename is present in in + // multiple directories, the file in the directory listed last in + // this slice takes precedence. + HooksDir []string `toml:"hooks_dir,omitempty"` + + // Namespace is the libpod namespace to use. Namespaces are used to create + // scopes to separate containers and pods in the state. When namespace is + // set, libpod will only view containers and pods in the same namespace. All + // containers and pods created will default to the namespace set here. A + // namespace of "", the empty string, is equivalent to no namespace, and all + // containers and pods will be visible. The default namespace is "". + Namespace string `toml:"namespace,omitempty"` + + // InfraImage is the image a pod infra container will use to manage + // namespaces. + InfraImage string `toml:"infra_image,omitempty"` + + // InfraCommand is the command run to start up a pod infra container. + InfraCommand string `toml:"infra_command,omitempty"` + + // EnablePortReservation determines whether libpod will reserve ports on the + // host when they are forwarded to containers. When enabled, when ports are + // forwarded to containers, they are held open by conmon as long as the + // container is running, ensuring that they cannot be reused by other + // programs on the host. However, this can cause significant memory usage if + // a container has many ports forwarded to it. Disabling this can save + // memory. + EnablePortReservation bool `toml:"enable_port_reservation,omitempty"` + + // EnableLabeling indicates whether libpod will support container labeling. + EnableLabeling bool `toml:"label,omitempty"` + + // NetworkCmdPath is the path to the slirp4netns binary. + NetworkCmdPath string `toml:"network_cmd_path,omitempty"` + + // NumLocks is the number of locks to make available for containers and + // pods. + NumLocks uint32 `toml:"num_locks,omitempty"` + + // LockType is the type of locking to use. + LockType string `toml:"lock_type,omitempty"` + + // EventsLogger determines where events should be logged. + EventsLogger string `toml:"events_logger,omitempty"` + + // EventsLogFilePath is where the events log is stored. + EventsLogFilePath string `toml:"events_logfile_path,omitempty"` + + //DetachKeys is the sequence of keys used to detach a container. + DetachKeys string `toml:"detach_keys,omitempty"` + + // SDNotify tells Libpod to allow containers to notify the host systemd of + // readiness using the SD_NOTIFY mechanism. + SDNotify bool `toml:",omitempty"` + + // CgroupCheck indicates the configuration has been rewritten after an + // upgrade to Fedora 31 to change the default OCI runtime for cgroupsv2. + CgroupCheck bool `toml:"cgroup_check,omitempty"` +} + +// newLibpodConfig creates a new ConfigFromLibpod and converts it to Config. +// Depending if we're running as root or rootless, we then merge the system configuration followed +// by merging the default config (hard-coded default in memory). +// Note that the OCI runtime is hard-set to `crun` if we're running on a system +// with cgroupsv2. Other OCI runtimes are not yet supporting cgroupsv2. This +// might change in the future. +func newLibpodConfig(c *Config) error { + // Start with the default config and interatively merge + // fields in the system configs. + config := c.libpodConfig() + + // Now, check if the user can access system configs and merge them if needed. + configs, err := systemLibpodConfigs() + if err != nil { + return errors.Wrapf(err, "error finding config on system") + } + + for _, path := range configs { + config, err = readLibpodConfigFromFile(path, config) + if err != nil { + return errors.Wrapf(err, "error reading system config %q", path) + } + } + + // Since runc does not currently support cgroupV2 + // Change to default crun on first running of libpod.conf + // TODO Once runc has support for cgroups, this function should be removed. + if !config.CgroupCheck && unshare.IsRootless() { + cgroupsV2, err := isCgroup2UnifiedMode() + if err != nil { + return err + } + if cgroupsV2 { + path, err := exec.LookPath("crun") + if err != nil { + // Can't find crun path so do nothing + logrus.Warnf("Can not find crun package on the host, containers might fail to run on cgroup V2 systems without crun: %q", err) + } else { + config.CgroupCheck = true + config.OCIRuntime = path + } + } + } + + c.libpodToContainersConfig(config) + + return nil +} + +// readConfigFromFile reads the specified config file at `path` and attempts to +// unmarshal its content into a Config. The config param specifies the previous +// default config. If the path, only specifies a few fields in the Toml file +// the defaults from the config parameter will be used for all other fields. +func readLibpodConfigFromFile(path string, config *ConfigFromLibpod) (*ConfigFromLibpod, error) { + logrus.Debugf("Reading configuration file %q", path) + _, err := toml.DecodeFile(path, config) + if err != nil { + return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err) + } + + // For the sake of backwards compat we need to check if the config fields + // with *Set suffix are set in the config. Note that the storage-related + // fields are NOT set in the config here but in the storage.conf OR directly + // by the user. + if config.VolumePath != "" { + config.VolumePathSet = true + } + if config.StaticDir != "" { + config.StaticDirSet = true + } + if config.TmpDir != "" { + config.TmpDirSet = true + } + + return config, err +} + +func systemLibpodConfigs() ([]string, error) { + if unshare.IsRootless() { + path, err := rootlessLibpodConfigPath() + if err != nil { + return nil, err + } + if _, err := os.Stat(path); err == nil { + containersConfPath, err := rootlessConfigPath() + if err != nil { + containersConfPath = filepath.Join("$HOME", UserOverrideContainersConfig) + } + // TODO: Raise to Warnf, when Podman is updated to + // remove libpod.conf by default + logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", path, containersConfPath) + return []string{path}, nil + } + return nil, err + } + + configs := []string{} + if _, err := os.Stat(_rootConfigPath); err == nil { + // TODO: Raise to Warnf, when Podman is updated to + // remove libpod.conf by default + logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", _rootConfigPath, OverrideContainersConfig) + configs = append(configs, _rootConfigPath) + } + if _, err := os.Stat(_rootOverrideConfigPath); err == nil { + // TODO: Raise to Warnf, when Podman is updated to + // remove libpod.conf by default + logrus.Debugf("Found deprecated file %s, please remove. Use %s to override defaults.\n", _rootOverrideConfigPath, OverrideContainersConfig) + configs = append(configs, _rootOverrideConfigPath) + } + return configs, nil +} + +func rootlessLibpodConfigPath() (string, error) { + home, err := unshare.HomeDir() + if err != nil { + return "", err + } + + return filepath.Join(home, _rootlessConfigPath), nil +} + +func (c *Config) libpodConfig() *ConfigFromLibpod { + return &ConfigFromLibpod{ + SignaturePolicyPath: c.Containers.SignaturePolicyPath, + InitPath: c.Containers.InitPath, + MaxLogSize: c.Containers.LogSizeMax, + EnableLabeling: c.Containers.EnableLabeling, + + SetOptions: c.Engine.SetOptions, + VolumePath: c.Engine.VolumePath, + ImageDefaultTransport: c.Engine.ImageDefaultTransport, + OCIRuntime: c.Engine.OCIRuntime, + OCIRuntimes: c.Engine.OCIRuntimes, + RuntimeSupportsJSON: c.Engine.RuntimeSupportsJSON, + RuntimeSupportsNoCgroups: c.Engine.RuntimeSupportsNoCgroups, + RuntimePath: c.Engine.RuntimePath, + ConmonPath: c.Engine.ConmonPath, + ConmonEnvVars: c.Engine.ConmonEnvVars, + CgroupManager: c.Engine.CgroupManager, + StaticDir: c.Engine.StaticDir, + TmpDir: c.Engine.TmpDir, + NoPivotRoot: c.Engine.NoPivotRoot, + HooksDir: c.Engine.HooksDir, + Namespace: c.Engine.Namespace, + InfraImage: c.Engine.InfraImage, + InfraCommand: c.Engine.InfraCommand, + EnablePortReservation: c.Engine.EnablePortReservation, + NetworkCmdPath: c.Engine.NetworkCmdPath, + NumLocks: c.Engine.NumLocks, + LockType: c.Engine.LockType, + EventsLogger: c.Engine.EventsLogger, + EventsLogFilePath: c.Engine.EventsLogFilePath, + DetachKeys: c.Engine.DetachKeys, + SDNotify: c.Engine.SDNotify, + CgroupCheck: c.Engine.CgroupCheck, + + CNIConfigDir: c.Network.NetworkConfigDir, + CNIPluginDir: c.Network.CNIPluginDirs, + CNIDefaultNetwork: c.Network.DefaultNetwork, + } +} + +func (c *Config) libpodToContainersConfig(libpodConf *ConfigFromLibpod) { + + c.Containers.SignaturePolicyPath = libpodConf.SignaturePolicyPath + c.Containers.InitPath = libpodConf.InitPath + c.Containers.LogSizeMax = libpodConf.MaxLogSize + c.Containers.EnableLabeling = libpodConf.EnableLabeling + + c.Engine.SetOptions = libpodConf.SetOptions + c.Engine.VolumePath = libpodConf.VolumePath + c.Engine.ImageDefaultTransport = libpodConf.ImageDefaultTransport + c.Engine.OCIRuntime = libpodConf.OCIRuntime + c.Engine.OCIRuntimes = libpodConf.OCIRuntimes + c.Engine.RuntimeSupportsJSON = libpodConf.RuntimeSupportsJSON + c.Engine.RuntimeSupportsNoCgroups = libpodConf.RuntimeSupportsNoCgroups + c.Engine.RuntimePath = libpodConf.RuntimePath + c.Engine.ConmonPath = libpodConf.ConmonPath + c.Engine.ConmonEnvVars = libpodConf.ConmonEnvVars + c.Engine.CgroupManager = libpodConf.CgroupManager + c.Engine.StaticDir = libpodConf.StaticDir + c.Engine.TmpDir = libpodConf.TmpDir + c.Engine.NoPivotRoot = libpodConf.NoPivotRoot + c.Engine.HooksDir = libpodConf.HooksDir + c.Engine.Namespace = libpodConf.Namespace + c.Engine.InfraImage = libpodConf.InfraImage + c.Engine.InfraCommand = libpodConf.InfraCommand + c.Engine.EnablePortReservation = libpodConf.EnablePortReservation + c.Engine.NetworkCmdPath = libpodConf.NetworkCmdPath + c.Engine.NumLocks = libpodConf.NumLocks + c.Engine.LockType = libpodConf.LockType + c.Engine.EventsLogger = libpodConf.EventsLogger + c.Engine.EventsLogFilePath = libpodConf.EventsLogFilePath + c.Engine.DetachKeys = libpodConf.DetachKeys + c.Engine.SDNotify = libpodConf.SDNotify + c.Engine.CgroupCheck = libpodConf.CgroupCheck + + c.Network.NetworkConfigDir = libpodConf.CNIConfigDir + c.Network.CNIPluginDirs = libpodConf.CNIPluginDir + c.Network.DefaultNetwork = libpodConf.CNIDefaultNetwork +} diff --git a/vendor/github.com/fsnotify/fsnotify/.editorconfig b/vendor/github.com/fsnotify/fsnotify/.editorconfig index ba49e3c23..fad895851 100644 --- a/vendor/github.com/fsnotify/fsnotify/.editorconfig +++ b/vendor/github.com/fsnotify/fsnotify/.editorconfig @@ -1,5 +1,12 @@ root = true -[*] +[*.go] indent_style = tab indent_size = 4 +insert_final_newline = true + +[*.{yml,yaml}] +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/vendor/github.com/fsnotify/fsnotify/.gitattributes b/vendor/github.com/fsnotify/fsnotify/.gitattributes new file mode 100644 index 000000000..32f1001be --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/.gitattributes @@ -0,0 +1 @@ +go.sum linguist-generated diff --git a/vendor/github.com/fsnotify/fsnotify/.travis.yml b/vendor/github.com/fsnotify/fsnotify/.travis.yml index 981d1bb81..a9c30165c 100644 --- a/vendor/github.com/fsnotify/fsnotify/.travis.yml +++ b/vendor/github.com/fsnotify/fsnotify/.travis.yml @@ -2,29 +2,35 @@ sudo: false language: go go: - - 1.8.x - - 1.9.x - - tip + - "stable" + - "1.11.x" + - "1.10.x" + - "1.9.x" matrix: + include: + - go: "stable" + env: GOLINT=true allow_failures: - go: tip fast_finish: true -before_script: - - go get -u github.com/golang/lint/golint + +before_install: + - if [ ! -z "${GOLINT}" ]; then go get -u golang.org/x/lint/golint; fi script: - - go test -v --race ./... + - go test --race ./... after_script: - test -z "$(gofmt -s -l -w . | tee /dev/stderr)" - - test -z "$(golint ./... | tee /dev/stderr)" + - if [ ! -z "${GOLINT}" ]; then echo running golint; golint --set_exit_status ./...; else echo skipping golint; fi - go vet ./... os: - linux - osx + - windows notifications: email: false diff --git a/vendor/github.com/fsnotify/fsnotify/LICENSE b/vendor/github.com/fsnotify/fsnotify/LICENSE index f21e54080..e180c8fb0 100644 --- a/vendor/github.com/fsnotify/fsnotify/LICENSE +++ b/vendor/github.com/fsnotify/fsnotify/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012 fsnotify Authors. All rights reserved. +Copyright (c) 2012-2019 fsnotify Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md index 399320741..b2629e522 100644 --- a/vendor/github.com/fsnotify/fsnotify/README.md +++ b/vendor/github.com/fsnotify/fsnotify/README.md @@ -10,16 +10,16 @@ go get -u golang.org/x/sys/... Cross platform: Windows, Linux, BSD and macOS. -|Adapter |OS |Status | -|----------|----------|----------| -|inotify |Linux 2.6.27 or later, Android\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)| -|kqueue |BSD, macOS, iOS\*|Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify)| -|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)| -|FSEvents |macOS |[Planned](https://github.com/fsnotify/fsnotify/issues/11)| -|FEN |Solaris 11 |[In Progress](https://github.com/fsnotify/fsnotify/issues/12)| -|fanotify |Linux 2.6.37+ | | -|USN Journals |Windows |[Maybe](https://github.com/fsnotify/fsnotify/issues/53)| -|Polling |*All* |[Maybe](https://github.com/fsnotify/fsnotify/issues/9)| +| Adapter | OS | Status | +| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| inotify | Linux 2.6.27 or later, Android\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| kqueue | BSD, macOS, iOS\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| ReadDirectoryChangesW | Windows | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) | +| FSEvents | macOS | [Planned](https://github.com/fsnotify/fsnotify/issues/11) | +| FEN | Solaris 11 | [In Progress](https://github.com/fsnotify/fsnotify/issues/12) | +| fanotify | Linux 2.6.37+ | [Planned](https://github.com/fsnotify/fsnotify/issues/114) | +| USN Journals | Windows | [Maybe](https://github.com/fsnotify/fsnotify/issues/53) | +| Polling | *All* | [Maybe](https://github.com/fsnotify/fsnotify/issues/9) | \* Android and iOS are untested. @@ -33,6 +33,53 @@ All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based o Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`. +## Usage + +```go +package main + +import ( + "log" + + "github.com/fsnotify/fsnotify" +) + +func main() { + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + done := make(chan bool) + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + log.Println("event:", event) + if event.Op&fsnotify.Write == fsnotify.Write { + log.Println("modified file:", event.Name) + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("error:", err) + } + } + }() + + err = watcher.Add("/tmp/foo") + if err != nil { + log.Fatal(err) + } + <-done +} +``` + ## Contributing Please refer to [CONTRIBUTING][] before opening an issue or pull request. @@ -65,6 +112,10 @@ There are OS-specific limits as to how many watches can be created: * Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a "no space left on device" error. * BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error. +**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?** + +fsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications. + [#62]: https://github.com/howeyc/fsnotify/issues/62 [#18]: https://github.com/fsnotify/fsnotify/issues/18 [#11]: https://github.com/fsnotify/fsnotify/issues/11 diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go index 190bf0de5..89cab046d 100644 --- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go +++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go @@ -63,4 +63,6 @@ func (e Event) String() string { } // Common errors that can be reported by a watcher -var ErrEventOverflow = errors.New("fsnotify queue overflow") +var ( + ErrEventOverflow = errors.New("fsnotify queue overflow") +) diff --git a/vendor/github.com/fsnotify/fsnotify/go.mod b/vendor/github.com/fsnotify/fsnotify/go.mod new file mode 100644 index 000000000..ff11e13f2 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/go.mod @@ -0,0 +1,5 @@ +module github.com/fsnotify/fsnotify + +go 1.13 + +require golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 diff --git a/vendor/github.com/fsnotify/fsnotify/go.sum b/vendor/github.com/fsnotify/fsnotify/go.sum new file mode 100644 index 000000000..f60af9855 --- /dev/null +++ b/vendor/github.com/fsnotify/fsnotify/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go index cc7db4b22..b33f2b4d4 100644 --- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go +++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go @@ -40,12 +40,12 @@ func newFdPoller(fd int) (*fdPoller, error) { poller.fd = fd // Create epoll fd - poller.epfd, errno = unix.EpollCreate1(0) + poller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC) if poller.epfd == -1 { return nil, errno } // Create pipe; pipe[0] is the read end, pipe[1] the write end. - errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK) + errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC) if errno != nil { return nil, errno } diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go index 7d8de1451..2306c4620 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go @@ -8,4 +8,4 @@ package fsnotify import "golang.org/x/sys/unix" -const openMode = unix.O_NONBLOCK | unix.O_RDONLY +const openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go index 9139e1716..870c4d6d1 100644 --- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go +++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go @@ -9,4 +9,4 @@ package fsnotify import "golang.org/x/sys/unix" // note: this constant is not defined on BSD -const openMode = unix.O_EVTONLY +const openMode = unix.O_EVTONLY | unix.O_CLOEXEC diff --git a/vendor/modules.txt b/vendor/modules.txt index b47bb71ef..4ef5d4cc6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -62,7 +62,7 @@ github.com/containernetworking/plugins/pkg/ns github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator -# github.com/containers/buildah v1.14.2 +# github.com/containers/buildah v1.14.3-0.20200313154200-d26f437b2a46 github.com/containers/buildah github.com/containers/buildah/bind github.com/containers/buildah/chroot @@ -77,7 +77,7 @@ github.com/containers/buildah/pkg/parse github.com/containers/buildah/pkg/secrets github.com/containers/buildah/pkg/umask github.com/containers/buildah/util -# github.com/containers/common v0.4.2 +# github.com/containers/common v0.5.0 github.com/containers/common/pkg/capabilities github.com/containers/common/pkg/config github.com/containers/common/pkg/unshare @@ -262,7 +262,7 @@ github.com/docker/spdystream github.com/docker/spdystream/spdy # github.com/etcd-io/bbolt v1.3.3 github.com/etcd-io/bbolt -# github.com/fsnotify/fsnotify v1.4.7 +# github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify # github.com/fsouza/go-dockerclient v1.6.3 github.com/fsouza/go-dockerclient |