diff options
-rw-r--r-- | cmd/podman/system/version.go | 21 | ||||
-rw-r--r-- | cni/87-podman-bridge.conflist | 1 | ||||
-rw-r--r-- | docs/source/markdown/podman-info.1.md | 294 | ||||
-rw-r--r-- | docs/source/markdown/podman-version.1.md | 13 | ||||
-rw-r--r-- | libpod/define/version.go | 27 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 1 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 209 | ||||
-rw-r--r-- | pkg/bindings/images/images.go | 107 | ||||
-rw-r--r-- | pkg/bindings/system/system.go | 12 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 29 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 11 | ||||
-rw-r--r-- | pkg/network/netconflist.go | 9 | ||||
-rw-r--r-- | pkg/varlinkapi/system.go | 2 | ||||
-rw-r--r-- | test/e2e/images_test.go | 1 | ||||
-rw-r--r-- | test/e2e/pause_test.go | 1 | ||||
-rw-r--r-- | test/e2e/rm_test.go | 1 | ||||
-rw-r--r-- | test/e2e/start_test.go | 11 | ||||
-rw-r--r-- | test/e2e/stop_test.go | 1 | ||||
-rw-r--r-- | test/system/001-basic.bats | 2 | ||||
-rw-r--r-- | version/version.go | 4 |
20 files changed, 594 insertions, 163 deletions
diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go index 50bd81368..92a3225b6 100644 --- a/cmd/podman/system/version.go +++ b/cmd/podman/system/version.go @@ -6,8 +6,8 @@ import ( "os" "strings" "text/tabwriter" - "time" + "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/cmd/podman/validate" "github.com/containers/libpod/libpod/define" @@ -52,6 +52,17 @@ func version(cmd *cobra.Command, args []string) error { if !strings.HasSuffix(versionFormat, "\n") { versionFormat += "\n" } + out := formats.StdoutTemplate{Output: versions, Template: versionFormat} + err := out.Out() + if err != nil { + // On Failure, assume user is using older version of podman version --format and check client + versionFormat = strings.Replace(versionFormat, ".Server.", ".", 1) + out = formats.StdoutTemplate{Output: versions.Client, Template: versionFormat} + if err1 := out.Out(); err1 != nil { + return err + } + } + return nil } w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -74,15 +85,11 @@ func version(cmd *cobra.Command, args []string) error { func formatVersion(writer io.Writer, version *define.Version) { fmt.Fprintf(writer, "Version:\t%s\n", version.Version) - fmt.Fprintf(writer, "RemoteAPI Version:\t%d\n", version.RemoteAPIVersion) + fmt.Fprintf(writer, "API Version:\t%d\n", version.APIVersion) fmt.Fprintf(writer, "Go Version:\t%s\n", version.GoVersion) if version.GitCommit != "" { fmt.Fprintf(writer, "Git Commit:\t%s\n", version.GitCommit) } - // Prints out the build time in readable format - if version.Built != 0 { - fmt.Fprintf(writer, "Built:\t%s\n", time.Unix(version.Built, 0).Format(time.ANSIC)) - } - + fmt.Fprintf(writer, "Built:\t%s\n", version.BuiltTime) fmt.Fprintf(writer, "OS/Arch:\t%s\n", version.OsArch) } diff --git a/cni/87-podman-bridge.conflist b/cni/87-podman-bridge.conflist index 13b09a5b5..ef760a61b 100644 --- a/cni/87-podman-bridge.conflist +++ b/cni/87-podman-bridge.conflist @@ -7,6 +7,7 @@ "bridge": "cni-podman0", "isGateway": true, "ipMasq": true, + "hairpinMode": true, "ipam": { "type": "host-local", "routes": [{ "dst": "0.0.0.0/0" }], diff --git a/docs/source/markdown/podman-info.1.md b/docs/source/markdown/podman-info.1.md index d9da4c3f8..24ab97c91 100644 --- a/docs/source/markdown/podman-info.1.md +++ b/docs/source/markdown/podman-info.1.md @@ -30,128 +30,212 @@ Run podman info with plain text response: ``` $ podman info host: - BuildahVersion: 1.4-dev - Conmon: - package: Unknown - path: /usr/libexec/podman/conmon - version: 'conmon version 1.12.0-dev, commit: d724f3d54ad2d95b6de741085d4990190ebfd7ff' - Distribution: - distribution: fedora - version: "28" - MemFree: 1271083008 - MemTotal: 33074233344 - OCIRuntime: - package: runc-1.0.0-51.dev.gitfdd8055.fc28.x86_64 - path: /usr/bin/runc - version: 'runc version spec: 1.0.0' - SwapFree: 34309664768 - SwapTotal: 34359734272 arch: amd64 + buildahVersion: 1.15.0 + cgroupVersion: v1 + conmon: + package: conmon-2.0.16-2.fc32.x86_64 + path: /usr/bin/conmon + version: 'conmon version 2.0.16, commit: 1044176f7dd177c100779d1c63931d6022e419bd' cpus: 8 + distribution: + distribution: fedora + version: "32" + eventLogger: file hostname: localhost.localdomain - kernel: 4.18.7-200.fc28.x86_64 + idMappings: + gidmap: + - container_id: 0 + host_id: 3267 + size: 1 + - container_id: 1 + host_id: 100000 + size: 65536 + uidmap: + - container_id: 0 + host_id: 3267 + size: 1 + - container_id: 1 + host_id: 100000 + size: 65536 + kernel: 5.6.11-300.fc32.x86_64 + linkmode: dynamic + memFree: 1401929728 + memTotal: 16416161792 + ociRuntime: + name: runc + package: containerd.io-1.2.10-3.2.fc31.x86_64 + path: /usr/bin/runc + version: |- + runc version 1.0.0-rc8+dev + commit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 + spec: 1.0.1-dev os: linux - uptime: 218h 49m 33.66s (Approximately 9.08 days) + rootless: true + slirp4netns: + executable: /bin/slirp4netns + package: slirp4netns-1.0.0-1.fc32.x86_64 + version: |- + slirp4netns version 1.0.0 + commit: a3be729152a33e692cd28b52f664defbf2e7810a + libslirp: 4.2.0 + swapFree: 8291610624 + swapTotal: 8296329216 + uptime: 52h 29m 39.78s (Approximately 2.17 days) registries: - docker.io: - Blocked: true - Insecure: true - Location: docker.io - MirrorByDigestOnly: false - Mirrors: - - Insecure: true - Location: example2.io/example/ubi8-minimal - Prefix: docker.io - redhat.com: - Blocked: false - Insecure: false - Location: registry.access.redhat.com/ubi8 - MirrorByDigestOnly: true - Mirrors: - - Insecure: false - Location: example.io/example/ubi8-minimal - - Insecure: true - Location: example3.io/example/ubi8-minimal - Prefix: redhat.com + search: + - registry.fedoraproject.org + - registry.access.redhat.com + - registry.centos.org + - docker.io store: - ConfigFile: /etc/containers/storage.conf - ContainerStore: - number: 37 - GraphDriverName: overlay - GraphOptions: - - overlay.mountopt=nodev - - overlay.override_kernel_check=true - GraphRoot: /var/lib/containers/storage - GraphStatus: + configFile: /home/dwalsh/.config/containers/storage.conf + containerStore: + number: 2 + paused: 0 + running: 0 + stopped: 2 + graphDriverName: overlay + graphOptions: + overlay.mount_program: + Executable: /home/dwalsh/bin/fuse-overlayfs + Package: Unknown + Version: |- + fusermount3 version: 3.9.1 + fuse-overlayfs: version 0.7.2 + FUSE library version 3.9.1 + using FUSE kernel interface version 7.31 + graphRoot: /home/dwalsh/.local/share/containers/storage + graphStatus: Backing Filesystem: extfs - Native Overlay Diff: "true" + Native Overlay Diff: "false" Supports d_type: "true" - ImageStore: - number: 17 - RunRoot: /var/run/containers/storage - + Using metacopy: "false" + imageStore: + number: 7 + runRoot: /run/user/3267/containers + volumePath: /home/dwalsh/.local/share/containers/storage/volumes +version: + Built: 1589899246 + BuiltTime: Tue May 19 10:40:46 2020 + GitCommit: c3678ce3289f4195f3f16802411e795c6a587c9f-dirty + GoVersion: go1.14.2 + OsArch: linux/amd64 + APIVersion: 1 + Version: 2.0.0 ``` Run podman info with JSON formatted response: ``` { - "host": { - "BuildahVersion": "1.4-dev", - "Conmon": { - "package": "Unknown", - "path": "/usr/libexec/podman/conmon", - "version": "conmon version 1.12.0-dev, commit: d724f3d54ad2d95b6de741085d4990190ebfd7ff" - }, - "Distribution": { - "distribution": "fedora", - "version": "28" + "host": { + "arch": "amd64", + "buildahVersion": "1.15.0", + "cgroupVersion": "v1", + "conmon": { + "package": "conmon-2.0.16-2.fc32.x86_64", + "path": "/usr/bin/conmon", + "version": "conmon version 2.0.16, commit: 1044176f7dd177c100779d1c63931d6022e419bd" + }, + "cpus": 8, + "distribution": { + "distribution": "fedora", + "version": "32" + }, + "eventLogger": "file", + "hostname": "localhost.localdomain", + "idMappings": { + "gidmap": [ + { + "container_id": 0, + "host_id": 3267, + "size": 1 }, - "MemFree": 1204109312, - "MemTotal": 33074233344, - "OCIRuntime": { - "package": "runc-1.0.0-51.dev.gitfdd8055.fc28.x86_64", - "path": "/usr/bin/runc", - "version": "runc version spec: 1.0.0" + { + "container_id": 1, + "host_id": 100000, + "size": 65536 + } + ], + "uidmap": [ + { + "container_id": 0, + "host_id": 3267, + "size": 1 }, - "SwapFree": 34309664768, - "SwapTotal": 34359734272, - "arch": "amd64", - "cpus": 8, - "hostname": "localhost.localdomain", - "kernel": "4.18.7-200.fc28.x86_64", - "os": "linux", - "uptime": "218h 50m 35.02s (Approximately 9.08 days)" + { + "container_id": 1, + "host_id": 100000, + "size": 65536 + } + ] }, - "insecure registries": { - "registries": [] + "kernel": "5.6.11-300.fc32.x86_64", + "memFree": 1380356096, + "memTotal": 16416161792, + "ociRuntime": { + "name": "runc", + "package": "containerd.io-1.2.10-3.2.fc31.x86_64", + "path": "/usr/bin/runc", + "version": "runc version 1.0.0-rc8+dev\ncommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657\nspec: 1.0.1-dev" }, - "registries": { - "registries": [ - "quay.io", - "registry.fedoraproject.org", - "docker.io", - "registry.access.redhat.com" - ] + "os": "linux", + "rootless": true, + "slirp4netns": { + "executable": "/bin/slirp4netns", + "package": "slirp4netns-1.0.0-1.fc32.x86_64", + "version": "slirp4netns version 1.0.0\ncommit: a3be729152a33e692cd28b52f664defbf2e7810a\nlibslirp: 4.2.0" }, - "store": { - "ContainerStore": { - "number": 37 - }, - "GraphDriverName": "overlay", - "GraphOptions": [ - "overlay.mountopt=nodev", - "overlay.override_kernel_check=true" - ], - "GraphRoot": "/var/lib/containers/storage", - "GraphStatus": { - "Backing Filesystem": "extfs", - "Native Overlay Diff": "true", - "Supports d_type": "true" - }, - "ImageStore": { - "number": 17 - }, - "RunRoot": "/var/run/containers/storage" - } + "swapFree": 8291610624, + "swapTotal": 8296329216, + "uptime": "52h 27m 39.38s (Approximately 2.17 days)", + "linkmode": "dynamic" + }, + "store": { + "configFile": "/home/dwalsh/.config/containers/storage.conf", + "containerStore": { + "number": 2, + "paused": 0, + "running": 0, + "stopped": 2 + }, + "graphDriverName": "overlay", + "graphOptions": { + "overlay.mount_program": { + "Executable": "/home/dwalsh/bin/fuse-overlayfs", + "Package": "Unknown", + "Version": "fusermount3 version: 3.9.1\nfuse-overlayfs: version 0.7.2\nFUSE library version 3.9.1\nusing FUSE kernel interface version 7.31" +} + }, + "graphRoot": "/home/dwalsh/.local/share/containers/storage", + "graphStatus": { + "Backing Filesystem": "extfs", + "Native Overlay Diff": "false", + "Supports d_type": "true", + "Using metacopy": "false" + }, + "imageStore": { + "number": 7 + }, + "runRoot": "/run/user/3267/containers", + "volumePath": "/home/dwalsh/.local/share/containers/storage/volumes" + }, + "registries": { + "search": [ + "registry.fedoraproject.org", + "registry.access.redhat.com", + "registry.centos.org", + "docker.io" +] + }, + "version": { + "APIVersion": 1, + "Version": "2.0.0", + "GoVersion": "go1.14.2", + "GitCommit": "c3678ce3289f4195f3f16802411e795c6a587c9f-dirty", + "BuiltTime": "Tue May 19 10:40:46 2020", + "Built": 1589899246, + "OsArch": "linux/amd64" + } } ``` Run podman info and only get the registries information. diff --git a/docs/source/markdown/podman-version.1.md b/docs/source/markdown/podman-version.1.md index 86c270e02..185e8e296 100644 --- a/docs/source/markdown/podman-version.1.md +++ b/docs/source/markdown/podman-version.1.md @@ -25,17 +25,18 @@ Change output format to "json" or a Go template. A sample output of the `version` command: ``` $ podman version -Version: 0.11.1 -Go Version: go1.11 -Git Commit: "8967a1d691ed44896b81ad48c863033f23c65eb0-dirty" -Built: Thu Nov 8 22:35:40 2018 -OS/Arch: linux/amd64 +Version: 2.0.0 +API Version: 1 +Go Version: go1.14.2 +Git Commit: 4520664f63c3a7f9a80227715359e20069d95542 +Built: Tue May 19 10:48:59 2020 +OS/Arch: linux/amd64 ``` Filtering out only the version: ``` $ podman version --format '{{.Client.Version}}' -1.6.3 +2.0.0 ``` ## SEE ALSO diff --git a/libpod/define/version.go b/libpod/define/version.go index 954cd00f1..3eb016264 100644 --- a/libpod/define/version.go +++ b/libpod/define/version.go @@ -3,6 +3,7 @@ package define import ( "runtime" "strconv" + "time" podmanVersion "github.com/containers/libpod/version" ) @@ -19,12 +20,13 @@ var ( // Version is an output struct for varlink type Version struct { - RemoteAPIVersion int64 - Version string - GoVersion string - GitCommit string - Built int64 - OsArch string + APIVersion int64 + Version string + GoVersion string + GitCommit string + BuiltTime string + Built int64 + OsArch string } // GetVersion returns a VersionOutput struct for varlink and podman @@ -40,11 +42,12 @@ func GetVersion() (Version, error) { } } return Version{ - RemoteAPIVersion: podmanVersion.RemoteAPIVersion, - Version: podmanVersion.Version, - GoVersion: runtime.Version(), - GitCommit: gitCommit, - Built: buildTime, - OsArch: runtime.GOOS + "/" + runtime.GOARCH, + APIVersion: podmanVersion.APIVersion, + Version: podmanVersion.Version, + GoVersion: runtime.Version(), + GitCommit: gitCommit, + BuiltTime: time.Unix(buildTime, 0).Format(time.ANSIC), + Built: buildTime, + OsArch: runtime.GOOS + "/" + runtime.GOARCH, }, nil } diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index e208e6ddc..e9d8fd719 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -226,6 +226,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { id, _, err := runtime.Build(r.Context(), buildOptions, query.Dockerfile) if err != nil { utils.InternalServerError(w, err) + return } // Find image ID that was built... diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 01854b9c4..c885dc81a 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1188,5 +1188,214 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/images/{name}/changes"), s.APIHandler(compat.Changes)).Methods(http.MethodGet) + // swagger:operation POST /libpod/build libpod libpodBuildImage + // --- + // tags: + // - images + // summary: Create image + // description: Build an image from the given Dockerfile(s) + // parameters: + // - in: query + // name: dockerfile + // type: string + // default: Dockerfile + // description: | + // Path within the build context to the `Dockerfile`. + // This is ignored if remote is specified and points to an external `Dockerfile`. + // - in: query + // name: t + // type: string + // default: latest + // description: A name and optional tag to apply to the image in the `name:tag` format. + // - in: query + // name: extrahosts + // type: string + // default: + // description: | + // TBD Extra hosts to add to /etc/hosts + // (As of version 1.xx) + // - in: query + // name: remote + // type: string + // default: + // description: | + // A Git repository URI or HTTP/HTTPS context URI. + // If the URI points to a single text file, the file’s contents are placed + // into a file called Dockerfile and the image is built from that file. If + // the URI points to a tarball, the file is downloaded by the daemon and the + // contents therein used as the context for the build. If the URI points to a + // tarball and the dockerfile parameter is also specified, there must be a file + // with the corresponding path inside the tarball. + // (As of version 1.xx) + // - in: query + // name: q + // type: boolean + // default: false + // description: | + // Suppress verbose build output + // - in: query + // name: nocache + // type: boolean + // default: false + // description: | + // Do not use the cache when building the image + // (As of version 1.xx) + // - in: query + // name: cachefrom + // type: string + // default: + // description: | + // JSON array of images used to build cache resolution + // (As of version 1.xx) + // - in: query + // name: pull + // type: boolean + // default: false + // description: | + // Attempt to pull the image even if an older image exists locally + // (As of version 1.xx) + // - in: query + // name: rm + // type: boolean + // default: true + // description: | + // Remove intermediate containers after a successful build + // (As of version 1.xx) + // - in: query + // name: forcerm + // type: boolean + // default: false + // description: | + // Always remove intermediate containers, even upon failure + // (As of version 1.xx) + // - in: query + // name: memory + // type: integer + // description: | + // Memory is the upper limit (in bytes) on how much memory running containers can use + // (As of version 1.xx) + // - in: query + // name: memswap + // type: integer + // description: | + // MemorySwap limits the amount of memory and swap together + // (As of version 1.xx) + // - in: query + // name: cpushares + // type: integer + // description: | + // CPUShares (relative weight + // (As of version 1.xx) + // - in: query + // name: cpusetcpus + // type: string + // description: | + // CPUSetCPUs in which to allow execution (0-3, 0,1) + // (As of version 1.xx) + // - in: query + // name: cpuperiod + // type: integer + // description: | + // CPUPeriod limits the CPU CFS (Completely Fair Scheduler) period + // (As of version 1.xx) + // - in: query + // name: cpuquota + // type: integer + // description: | + // CPUQuota limits the CPU CFS (Completely Fair Scheduler) quota + // (As of version 1.xx) + // - in: query + // name: buildargs + // type: string + // default: + // description: | + // JSON map of string pairs denoting build-time variables. + // For example, the build argument `Foo` with the value of `bar` would be encoded in JSON as `["Foo":"bar"]`. + // + // For example, buildargs={"Foo":"bar"}. + // + // Note(s): + // * This should not be used to pass secrets. + // * The value of buildargs should be URI component encoded before being passed to the API. + // + // (As of version 1.xx) + // - in: query + // name: shmsize + // type: integer + // default: 67108864 + // description: | + // ShmSize is the "size" value to use when mounting an shmfs on the container's /dev/shm directory. + // Default is 64MB + // (As of version 1.xx) + // - in: query + // name: squash + // type: boolean + // default: false + // description: | + // Silently ignored. + // Squash the resulting images layers into a single layer + // (As of version 1.xx) + // - in: query + // name: labels + // type: string + // default: + // description: | + // JSON map of key, value pairs to set as labels on the new image + // (As of version 1.xx) + // - in: query + // name: networkmode + // type: string + // default: bridge + // description: | + // Sets the networking mode for the run commands during build. + // Supported standard values are: + // * `bridge` limited to containers within a single host, port mapping required for external access + // * `host` no isolation between host and containers on this network + // * `none` disable all networking for this container + // * container:<nameOrID> share networking with given container + // ---All other values are assumed to be a custom network's name + // (As of version 1.xx) + // - in: query + // name: platform + // type: string + // default: + // description: | + // Platform format os[/arch[/variant]] + // (As of version 1.xx) + // - in: query + // name: target + // type: string + // default: + // description: | + // Target build stage + // (As of version 1.xx) + // - in: query + // name: outputs + // type: string + // default: + // description: | + // output configuration TBD + // (As of version 1.xx) + // produces: + // - application/json + // responses: + // 200: + // description: OK (As of version 1.xx) + // schema: + // type: object + // required: + // - stream + // properties: + // stream: + // type: string + // description: output from build process + // example: | + // (build details...) + // Successfully built 8ba084515c724cbf90d447a63600c0a6 + // 400: + // $ref: "#/responses/BadParamError" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/build"), s.APIHandler(compat.BuildImage)).Methods(http.MethodPost) return nil } diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index 69b9e9bbf..f9c02d199 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -1,6 +1,7 @@ package images import ( + "bytes" "context" "fmt" "io" @@ -8,10 +9,13 @@ import ( "net/url" "strconv" + "github.com/containers/buildah" "github.com/containers/image/v5/types" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/domain/entities" + "github.com/docker/go-units" + jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" ) @@ -209,7 +213,108 @@ func Untag(ctx context.Context, nameOrID, tag, repo string) error { return response.Process(nil) } -func Build(nameOrId string) {} +// Build creates an image using a containerfile reference +func Build(ctx context.Context, containerFiles []string, options entities.BuildOptions, tarfile io.Reader) (*entities.BuildReport, error) { + var ( + platform string + report entities.BuildReport + ) + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + params := url.Values{} + params.Set("dockerfile", containerFiles[0]) + if t := options.Output; len(t) > 0 { + params.Set("t", t) + } + // TODO Remote, Quiet + if options.NoCache { + params.Set("nocache", "1") + } + // TODO cachefrom + if options.PullPolicy == buildah.PullAlways { + params.Set("pull", "1") + } + if options.RemoveIntermediateCtrs { + params.Set("rm", "1") + } + if options.ForceRmIntermediateCtrs { + params.Set("forcerm", "1") + } + if mem := options.CommonBuildOpts.Memory; mem > 0 { + params.Set("memory", strconv.Itoa(int(mem))) + } + if memSwap := options.CommonBuildOpts.MemorySwap; memSwap > 0 { + params.Set("memswap", strconv.Itoa(int(memSwap))) + } + if cpuShares := options.CommonBuildOpts.CPUShares; cpuShares > 0 { + params.Set("cpushares", strconv.Itoa(int(cpuShares))) + } + if cpuSetCpus := options.CommonBuildOpts.CPUSetCPUs; len(cpuSetCpus) > 0 { + params.Set("cpusetcpues", cpuSetCpus) + } + if cpuPeriod := options.CommonBuildOpts.CPUPeriod; cpuPeriod > 0 { + params.Set("cpuperiod", strconv.Itoa(int(cpuPeriod))) + } + if cpuQuota := options.CommonBuildOpts.CPUQuota; cpuQuota > 0 { + params.Set("cpuquota", strconv.Itoa(int(cpuQuota))) + } + if buildArgs := options.Args; len(buildArgs) > 0 { + bArgs, err := jsoniter.MarshalToString(buildArgs) + if err != nil { + return nil, err + } + params.Set("buildargs", bArgs) + } + if shmSize := options.CommonBuildOpts.ShmSize; len(shmSize) > 0 { + shmBytes, err := units.RAMInBytes(shmSize) + if err != nil { + return nil, err + } + params.Set("shmsize", strconv.Itoa(int(shmBytes))) + } + if options.Squash { + params.Set("squash", "1") + } + if labels := options.Labels; len(labels) > 0 { + l, err := jsoniter.MarshalToString(labels) + if err != nil { + return nil, err + } + params.Set("labels", l) + } + + // TODO network? + if OS := options.OS; len(OS) > 0 { + platform += OS + } + if arch := options.Architecture; len(arch) > 0 { + platform += "/" + arch + } + if len(platform) > 0 { + params.Set("platform", platform) + } + // TODO outputs? + + response, err := conn.DoRequest(tarfile, http.MethodPost, "/build", params) + if err != nil { + return nil, err + } + var streamReponse []byte + bb := bytes.NewBuffer(streamReponse) + if _, err = io.Copy(bb, response.Body); err != nil { + return nil, err + } + var s struct { + Stream string `json:"stream"` + } + if err := jsoniter.UnmarshalFromString(bb.String(), &s); err != nil { + return nil, err + } + fmt.Print(s.Stream) + return &report, nil +} // Imports adds the given image to the local image store. This can be done by file and the given reader // or via the url parameter. Additional metadata can be associated with the image by using the changes and diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go index e567e7a86..ed960b8e0 100644 --- a/pkg/bindings/system/system.go +++ b/pkg/bindings/system/system.go @@ -112,12 +112,12 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) { f, _ := strconv.ParseFloat(component.APIVersion, 64) b, _ := time.Parse(time.RFC3339, component.BuildTime) report.Server = &define.Version{ - RemoteAPIVersion: int64(f), - Version: component.Version.Version, - GoVersion: component.GoVersion, - GitCommit: component.GitCommit, - Built: b.Unix(), - OsArch: fmt.Sprintf("%s/%s", component.Os, component.Arch), + APIVersion: int64(f), + Version: component.Version.Version, + GoVersion: component.GoVersion, + GitCommit: component.GitCommit, + Built: b.Unix(), + OsArch: fmt.Sprintf("%s/%s", component.Os, component.Arch), } return &report, err } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index d02c54e76..30c4a8359 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -87,10 +87,25 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin } for _, c := range ctrs { report := entities.StopReport{Id: c.ID} - report.Err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout) - // TODO we need to associate errors returned by http with common - // define.errors so that we can equity tests. this will allow output - // to be the same as the native client + if err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout); err != nil { + // These first two are considered non-fatal under the right conditions + if errors.Cause(err).Error() == define.ErrCtrStopped.Error() { + logrus.Debugf("Container %s is already stopped", c.ID) + reports = append(reports, &report) + continue + } else if options.All && errors.Cause(err).Error() == define.ErrCtrStateInvalid.Error() { + logrus.Debugf("Container %s is not running, could not stop", c.ID) + reports = append(reports, &report) + continue + } + + // TODO we need to associate errors returned by http with common + // define.errors so that we can equity tests. this will allow output + // to be the same as the native client + report.Err = err + reports = append(reports, &report) + continue + } reports = append(reports, &report) } return reports, nil @@ -357,7 +372,11 @@ func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { var reports []*entities.ContainerStartReport for _, name := range namesOrIds { - report := entities.ContainerStartReport{Id: name} + report := entities.ContainerStartReport{ + Id: name, + RawInput: name, + ExitCode: 125, + } if options.Attach { report.Err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr) if report.Err == nil { diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 3d5626c45..c300e74d0 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -4,6 +4,7 @@ import ( "context" "io/ioutil" "os" + "path" "strings" "github.com/containers/common/pkg/config" @@ -13,6 +14,7 @@ import ( "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/domain/utils" utils2 "github.com/containers/libpod/utils" + "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" ) @@ -265,7 +267,14 @@ func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { } func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts entities.BuildOptions) (*entities.BuildReport, error) { - return nil, errors.New("not implemented yet") + if len(containerFiles) > 1 { + return nil, errors.New("something") + } + tarfile, err := archive.Tar(path.Base(containerFiles[0]), 0) + if err != nil { + return nil, err + } + return images.Build(ir.ClientCxt, containerFiles, opts, tarfile) } func (ir *ImageEngine) Tree(ctx context.Context, nameOrId string, opts entities.ImageTreeOptions) (*entities.ImageTreeReport, error) { diff --git a/pkg/network/netconflist.go b/pkg/network/netconflist.go index 34ff00024..4271d3f54 100644 --- a/pkg/network/netconflist.go +++ b/pkg/network/netconflist.go @@ -21,10 +21,11 @@ func NewNcList(name, version string) NcList { // NewHostLocalBridge creates a new LocalBridge for host-local func NewHostLocalBridge(name string, isGateWay, isDefaultGW, ipMasq bool, ipamConf IPAMHostLocalConf) *HostLocalBridge { hostLocalBridge := HostLocalBridge{ - PluginType: "bridge", - BrName: name, - IPMasq: ipMasq, - IPAM: ipamConf, + PluginType: "bridge", + BrName: name, + IPMasq: ipMasq, + HairpinMode: true, + IPAM: ipamConf, } if isGateWay { hostLocalBridge.IsGW = true diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go index 82efe9b5d..308f02274 100644 --- a/pkg/varlinkapi/system.go +++ b/pkg/varlinkapi/system.go @@ -28,7 +28,7 @@ func (i *VarlinkAPI) GetVersion(call iopodman.VarlinkCall) error { versionInfo.GitCommit, time.Unix(versionInfo.Built, 0).Format(time.RFC3339), versionInfo.OsArch, - versionInfo.RemoteAPIVersion, + versionInfo.APIVersion, ) } diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index 1715cf8c1..1b23aba36 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -131,7 +131,6 @@ var _ = Describe("Podman images", func() { }) It("podman images filter by image name", func() { - Skip(v2remotefail) podmanTest.RestoreAllArtifacts() session := podmanTest.PodmanNoCache([]string{"images", "-q", ALPINE}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 2faa4bc3f..149a2e28a 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -297,7 +297,6 @@ var _ = Describe("Podman pause", func() { }) It("Unpause a bunch of running containers", func() { - Skip(v2remotefail) for i := 0; i < 3; i++ { name := fmt.Sprintf("test%d", i) run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx}) diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index 552683d8c..87e3de922 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -43,7 +43,6 @@ var _ = Describe("Podman rm", func() { }) It("podman rm refuse to remove a running container", func() { - Skip(v2remotefail) session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index a7a9e7fdb..b8198a3a9 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -40,7 +40,6 @@ var _ = Describe("Podman start", func() { }) It("podman start single container by id", func() { - Skip(v2remotefail) session := podmanTest.Podman([]string{"create", "-d", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -51,7 +50,6 @@ var _ = Describe("Podman start", func() { }) It("podman container start single container by id", func() { - Skip(v2remotefail) session := podmanTest.Podman([]string{"container", "create", "-d", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -63,7 +61,6 @@ var _ = Describe("Podman start", func() { }) It("podman container start single container by short id", func() { - Skip(v2remotefail) session := podmanTest.Podman([]string{"container", "create", "-d", ALPINE, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -123,12 +120,11 @@ var _ = Describe("Podman start", func() { }) It("podman failed to start with --rm should delete the container", func() { - SkipIfRemote() - session := podmanTest.Podman([]string{"create", "-it", "--rm", ALPINE, "foo"}) + session := podmanTest.Podman([]string{"create", "--name", "test1", "-it", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - start := podmanTest.Podman([]string{"start", "-l"}) + start := podmanTest.Podman([]string{"start", "test1"}) start.WaitWithDefaultTimeout() Expect(start).To(ExitWithError()) @@ -136,12 +132,11 @@ var _ = Describe("Podman start", func() { }) It("podman failed to start without --rm should NOT delete the container", func() { - SkipIfRemote() session := podmanTest.Podman([]string{"create", "-it", ALPINE, "foo"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - start := podmanTest.Podman([]string{"start", "-l"}) + start := podmanTest.Podman([]string{"start", session.OutputToString()}) start.WaitWithDefaultTimeout() Expect(start).To(ExitWithError()) diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 8e49e3bd0..cd78a54e1 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -217,7 +217,6 @@ var _ = Describe("Podman stop", func() { }) It("podman stop all containers with one created", func() { - Skip(v2remotefail) session := podmanTest.RunTopContainer("test1") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index 5fc07acfb..71595f419 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -23,7 +23,7 @@ function setup() { is "${lines[0]}" "Version:[ ]\+[1-9][0-9.]\+" "Version line 1" is "$output" ".*Go Version: \+" "'Go Version' in output" - is "$output" ".*RemoteAPI Version: \+" "API version in output" + is "$output" ".*API Version: \+" "API version in output" } diff --git a/version/version.go b/version/version.go index fe602d8e1..4c7202e77 100644 --- a/version/version.go +++ b/version/version.go @@ -6,7 +6,7 @@ package version // bumped. const Version = "2.0.0-dev" -// RemoteAPIVersion is the version for the remote +// APIVersion is the version for the remote // client API. It is used to determine compatibility // between a remote podman client and its backend -const RemoteAPIVersion = 1 +const APIVersion = 1 |