summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2019-02-06 09:44:16 -0600
committerbaude <bbaude@redhat.com>2019-02-13 15:36:36 -0600
commitef85dd7950800fdce9ab58724921507cba31004b (patch)
tree2aa8d8e6485ad3ecec64f0d338536b628726fea3
parentfa3b91dc1216e6057e24a574bec566401800d780 (diff)
downloadpodman-ef85dd7950800fdce9ab58724921507cba31004b.tar.gz
podman-ef85dd7950800fdce9ab58724921507cba31004b.tar.bz2
podman-ef85dd7950800fdce9ab58724921507cba31004b.zip
podman-remote build
add the ability to build images using files local to the remote-client but over a varlink interface to a "remote" server. Signed-off-by: baude <bbaude@redhat.com>
-rwxr-xr-xAPI.md79
-rw-r--r--cmd/podman/build.go111
-rw-r--r--cmd/podman/varlink/io.podman.varlink65
-rw-r--r--libpod/adapter/runtime.go51
-rw-r--r--libpod/adapter/runtime_remote.go112
-rw-r--r--pkg/varlinkapi/images.go181
-rw-r--r--pkg/varlinkapi/transfers.go2
-rw-r--r--pkg/varlinkapi/util.go27
8 files changed, 424 insertions, 204 deletions
diff --git a/API.md b/API.md
index 54f7d0101..e44862c3f 100755
--- a/API.md
+++ b/API.md
@@ -135,6 +135,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[type BuildInfo](#BuildInfo)
+[type BuildOptions](#BuildOptions)
+
[type Container](#Container)
[type ContainerChanges](#ContainerChanges)
@@ -972,53 +974,84 @@ a [ContainerNotFound](#ContainerNotFound) error is returned.
BuildInfo is used to describe user input for building images
-dockerfile [[]string](#[]string)
+additionalTags [[]string](#[]string)
-tags [[]string](#[]string)
+annotations [[]string](#[]string)
-add_hosts [[]string](#[]string)
+buildArgs [map[string]](#map[string])
-cgroup_parent [string](https://godoc.org/builtin#string)
+buildOptions [BuildOptions](#BuildOptions)
-cpu_period [int](https://godoc.org/builtin#int)
+cniConfigDir [string](https://godoc.org/builtin#string)
-cpu_quota [int](https://godoc.org/builtin#int)
+cniPluginDir [string](https://godoc.org/builtin#string)
-cpu_shares [int](https://godoc.org/builtin#int)
+compression [string](https://godoc.org/builtin#string)
-cpuset_cpus [string](https://godoc.org/builtin#string)
+contextDir [string](https://godoc.org/builtin#string)
-cpuset_mems [string](https://godoc.org/builtin#string)
+defaultsMountFilePath [string](https://godoc.org/builtin#string)
-memory [string](https://godoc.org/builtin#string)
+dockerfiles [[]string](#[]string)
-memory_swap [string](https://godoc.org/builtin#string)
+err [string](https://godoc.org/builtin#string)
-security_opts [[]string](#[]string)
+forceRmIntermediateCtrs [bool](https://godoc.org/builtin#bool)
-shm_size [string](https://godoc.org/builtin#string)
+iidfile [string](https://godoc.org/builtin#string)
-ulimit [[]string](#[]string)
+label [[]string](#[]string)
-volume [[]string](#[]string)
+layers [bool](https://godoc.org/builtin#bool)
+
+nocache [bool](https://godoc.org/builtin#bool)
+
+out [string](https://godoc.org/builtin#string)
+
+output [string](https://godoc.org/builtin#string)
+
+outputFormat [string](https://godoc.org/builtin#string)
+
+pullPolicy [string](https://godoc.org/builtin#string)
+
+quiet [bool](https://godoc.org/builtin#bool)
+
+remoteIntermediateCtrs [bool](https://godoc.org/builtin#bool)
+
+reportWriter [string](https://godoc.org/builtin#string)
+
+runtimeArgs [[]string](#[]string)
+
+signaturePolicyPath [string](https://godoc.org/builtin#string)
squash [bool](https://godoc.org/builtin#bool)
+### <a name="BuildOptions"></a>type BuildOptions
-pull [bool](https://godoc.org/builtin#bool)
+BuildOptions are are used to describe describe physical attributes of the build
-pull_always [bool](https://godoc.org/builtin#bool)
+addHosts [[]string](#[]string)
-force_rm [bool](https://godoc.org/builtin#bool)
+cgroupParent [string](https://godoc.org/builtin#string)
-rm [bool](https://godoc.org/builtin#bool)
+cpuPeriod [int](https://godoc.org/builtin#int)
-label [[]string](#[]string)
+cpuQuota [int](https://godoc.org/builtin#int)
-annotations [[]string](#[]string)
+cpuShares [int](https://godoc.org/builtin#int)
+
+cpusetCpus [string](https://godoc.org/builtin#string)
+
+cpusetMems [string](https://godoc.org/builtin#string)
+
+memory [int](https://godoc.org/builtin#int)
-build_args [map[string]](#map[string])
+memorySwap [int](https://godoc.org/builtin#int)
-image_format [string](https://godoc.org/builtin#string)
+shmSize [string](https://godoc.org/builtin#string)
+
+ulimit [[]string](#[]string)
+
+volume [[]string](#[]string)
### <a name="Container"></a>type Container
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index fef93ac47..30a734377 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -1,7 +1,6 @@
package main
import (
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -9,10 +8,9 @@ import (
"github.com/containers/buildah"
"github.com/containers/buildah/imagebuildah"
buildahcli "github.com/containers/buildah/pkg/cli"
- "github.com/containers/buildah/pkg/parse"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
- "github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/libpod/adapter"
+ "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@@ -76,7 +74,6 @@ func getDockerfiles(files []string) []string {
func buildCmd(c *cliconfig.BuildValues) error {
// The following was taken directly from containers/buildah/cmd/bud.go
// TODO Find a away to vendor more of this in rather than copy from bud
-
output := ""
tags := []string{}
if c.Flag("tag").Changed {
@@ -86,6 +83,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
tags = tags[1:]
}
}
+
pullPolicy := imagebuildah.PullNever
if c.Pull {
pullPolicy = imagebuildah.PullIfMissing
@@ -173,16 +171,17 @@ func buildCmd(c *cliconfig.BuildValues) error {
dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile"))
}
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
+ if err != nil {
+ return errors.Wrapf(err, "could not get runtime")
+ }
+
runtimeFlags := []string{}
for _, arg := range c.RuntimeOpts {
runtimeFlags = append(runtimeFlags, "--"+arg)
}
// end from buildah
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
- if err != nil {
- return errors.Wrapf(err, "could not get runtime")
- }
defer runtime.Shutdown(false)
var stdout, stderr, reporter *os.File
@@ -201,72 +200,64 @@ func buildCmd(c *cliconfig.BuildValues) error {
reporter = f
}
- systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command)
- if err != nil {
- return errors.Wrapf(err, "error building system context")
- }
- systemContext.AuthFilePath = getAuthFile(c.Authfile)
- commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command)
- if err != nil {
- return err
+ var memoryLimit, memorySwap int64
+ if c.Flags().Changed("memory") {
+ memoryLimit, err = units.RAMInBytes(c.Memory)
+ if err != nil {
+ return err
+ }
}
- namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command)
- if err != nil {
- return errors.Wrapf(err, "error parsing namespace-related options")
- }
- usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command)
- if err != nil {
- return errors.Wrapf(err, "error parsing ID mapping options")
+ if c.Flags().Changed("memory-swap") {
+ memorySwap, err = units.RAMInBytes(c.MemorySwap)
+ if err != nil {
+ return err
+ }
}
- namespaceOptions.AddOrReplace(usernsOption...)
- ociruntime := runtime.GetOCIRuntimePath()
- if c.Flag("runtime").Changed {
- ociruntime = c.Runtime
+ buildOpts := buildah.CommonBuildOptions{
+ AddHost: c.AddHost,
+ CgroupParent: c.CgroupParent,
+ CPUPeriod: c.CPUPeriod,
+ CPUQuota: c.CPUQuota,
+ CPUShares: c.CPUShares,
+ CPUSetCPUs: c.CPUSetCPUs,
+ CPUSetMems: c.CPUSetMems,
+ Memory: memoryLimit,
+ MemorySwap: memorySwap,
+ ShmSize: c.ShmSize,
+ Ulimit: c.Ulimit,
+ Volumes: c.Volume,
}
+
options := imagebuildah.BuildOptions{
- ContextDirectory: contextDir,
- PullPolicy: pullPolicy,
- Compression: imagebuildah.Gzip,
- Quiet: c.Quiet,
- SignaturePolicyPath: c.SignaturePolicy,
- Args: args,
- Output: output,
+ CommonBuildOpts: &buildOpts,
AdditionalTags: tags,
- Out: stdout,
- Err: stderr,
- ReportWriter: reporter,
- Runtime: ociruntime,
- RuntimeArgs: runtimeFlags,
- OutputFormat: format,
- SystemContext: systemContext,
- NamespaceOptions: namespaceOptions,
- ConfigureNetwork: networkPolicy,
- CNIPluginPath: c.CNIPlugInPath,
+ Annotations: c.Annotation,
+ Args: args,
CNIConfigDir: c.CNIConfigDir,
- IDMappingOptions: idmappingOptions,
- CommonBuildOpts: commonOpts,
+ CNIPluginPath: c.CNIPlugInPath,
+ Compression: imagebuildah.Gzip,
+ ContextDirectory: contextDir,
DefaultMountsFilePath: c.GlobalFlags.DefaultMountsFile,
+ Err: stderr,
+ ForceRmIntermediateCtrs: c.ForceRm,
IIDFile: c.Iidfile,
- Squash: c.Squash,
Labels: c.Label,
- Annotations: c.Annotation,
Layers: layers,
NoCache: c.NoCache,
+ Out: stdout,
+ Output: output,
+ OutputFormat: format,
+ PullPolicy: pullPolicy,
+ Quiet: c.Quiet,
RemoveIntermediateCtrs: c.Rm,
- ForceRmIntermediateCtrs: c.ForceRm,
- }
-
- if c.Quiet {
- options.ReportWriter = ioutil.Discard
- }
-
- if rootless.IsRootless() {
- options.Isolation = buildah.IsolationOCIRootless
+ ReportWriter: reporter,
+ RuntimeArgs: runtimeFlags,
+ SignaturePolicyPath: c.SignaturePolicy,
+ Squash: c.Squash,
}
-
- return runtime.Build(getContext(), options, dockerfiles...)
+ return runtime.Build(getContext(), c, options, dockerfiles)
}
// Tail returns a string slice after the first element unless there are
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 03ea06dfc..dc6a25c44 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -311,33 +311,50 @@ type IDMap (
size: int
)
+# BuildOptions are are used to describe describe physical attributes of the build
+type BuildOptions (
+ addHosts: []string,
+ cgroupParent: string,
+ cpuPeriod: int,
+ cpuQuota: int,
+ cpuShares: int,
+ cpusetCpus: string,
+ cpusetMems: string,
+ memory: int,
+ memorySwap: int,
+ shmSize: string,
+ ulimit: []string,
+ volume: []string
+)
+
# BuildInfo is used to describe user input for building images
type BuildInfo (
- # paths to one or more dockerfiles
- dockerfile: []string,
- tags: []string,
- add_hosts: []string,
- cgroup_parent: string,
- cpu_period: int,
- cpu_quota: int,
- cpu_shares: int,
- cpuset_cpus: string,
- cpuset_mems: string,
- memory: string,
- memory_swap: string,
- security_opts: []string,
- shm_size: string,
- ulimit: []string,
- volume: []string,
- squash: bool,
- pull: bool,
- pull_always: bool,
- force_rm: bool,
- rm: bool,
- label: []string,
+ additionalTags: []string,
annotations: []string,
- build_args: [string]string,
- image_format: string
+ buildArgs: [string]string,
+ buildOptions: BuildOptions,
+ cniConfigDir: string,
+ cniPluginDir: string,
+ compression: string,
+ contextDir: string,
+ defaultsMountFilePath: string,
+ dockerfiles: []string,
+ err: string,
+ forceRmIntermediateCtrs: bool,
+ iidfile: string,
+ label: []string,
+ layers: bool,
+ nocache: bool,
+ out: string,
+ output: string,
+ outputFormat: string,
+ pullPolicy: string,
+ quiet: bool,
+ remoteIntermediateCtrs: bool,
+ reportWriter: string,
+ runtimeArgs: []string,
+ signaturePolicyPath: string,
+ squash: bool
)
# MoreResponse is a struct for when responses from varlink requires longer output
diff --git a/libpod/adapter/runtime.go b/libpod/adapter/runtime.go
index 7dd845616..3146cf5db 100644
--- a/libpod/adapter/runtime.go
+++ b/libpod/adapter/runtime.go
@@ -9,6 +9,9 @@ import (
"os"
"strconv"
+ "github.com/containers/buildah"
+ "github.com/containers/buildah/imagebuildah"
+ "github.com/containers/buildah/pkg/parse"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
@@ -254,3 +257,51 @@ func libpodVolumeToVolume(volumes []*libpod.Volume) []*Volume {
}
return vols
}
+
+// Build is the wrapper to build images
+func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, options imagebuildah.BuildOptions, dockerfiles []string) error {
+ namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing namespace-related options")
+ }
+ usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing ID mapping options")
+ }
+ namespaceOptions.AddOrReplace(usernsOption...)
+
+ systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command)
+ if err != nil {
+ return errors.Wrapf(err, "error building system context")
+ }
+
+ authfile := c.Authfile
+ if len(c.Authfile) == 0 {
+ authfile = os.Getenv("REGISTRY_AUTH_FILE")
+ }
+
+ systemContext.AuthFilePath = authfile
+ commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command)
+ if err != nil {
+ return err
+ }
+
+ options.NamespaceOptions = namespaceOptions
+ options.ConfigureNetwork = networkPolicy
+ options.IDMappingOptions = idmappingOptions
+ options.CommonBuildOpts = commonOpts
+ options.SystemContext = systemContext
+
+ if c.Flag("runtime").Changed {
+ options.Runtime = r.GetOCIRuntimePath()
+ }
+ if c.Quiet {
+ options.ReportWriter = ioutil.Discard
+ }
+
+ if rootless.IsRootless() {
+ options.Isolation = buildah.IsolationOCIRootless
+ }
+
+ return r.Runtime.Build(ctx, options, dockerfiles...)
+}
diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go
index d0d827582..66ff5ed51 100644
--- a/libpod/adapter/runtime_remote.go
+++ b/libpod/adapter/runtime_remote.go
@@ -7,19 +7,22 @@ import (
"context"
"encoding/json"
"fmt"
- "github.com/pkg/errors"
"io"
+ "io/ioutil"
"os"
"strings"
"time"
+ "github.com/containers/buildah/imagebuildah"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
+ "github.com/containers/storage/pkg/archive"
"github.com/opencontainers/go-digest"
+ "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/varlink/go/varlink"
)
@@ -376,6 +379,108 @@ func (r *LocalRuntime) Export(name string, path string) error {
// Import implements the remote calls required to import a container image to the store
func (r *LocalRuntime) Import(ctx context.Context, source, reference string, changes []string, history string, quiet bool) (string, error) {
// First we send the file to the host
+ tempFile, err := r.SendFileOverVarlink(source)
+ if err != nil {
+ return "", err
+ }
+ return iopodman.ImportImage().Call(r.Conn, strings.TrimRight(tempFile, ":"), reference, history, changes, true)
+}
+
+func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, options imagebuildah.BuildOptions, dockerfiles []string) error {
+ buildOptions := iopodman.BuildOptions{
+ AddHosts: options.CommonBuildOpts.AddHost,
+ CgroupParent: options.CommonBuildOpts.CgroupParent,
+ CpuPeriod: int64(options.CommonBuildOpts.CPUPeriod),
+ CpuQuota: options.CommonBuildOpts.CPUQuota,
+ CpuShares: int64(options.CommonBuildOpts.CPUShares),
+ CpusetCpus: options.CommonBuildOpts.CPUSetMems,
+ CpusetMems: options.CommonBuildOpts.CPUSetMems,
+ Memory: options.CommonBuildOpts.Memory,
+ MemorySwap: options.CommonBuildOpts.MemorySwap,
+ ShmSize: options.CommonBuildOpts.ShmSize,
+ Ulimit: options.CommonBuildOpts.Ulimit,
+ Volume: options.CommonBuildOpts.Volumes,
+ }
+
+ buildinfo := iopodman.BuildInfo{
+ AdditionalTags: options.AdditionalTags,
+ Annotations: options.Annotations,
+ BuildArgs: options.Args,
+ BuildOptions: buildOptions,
+ CniConfigDir: options.CNIConfigDir,
+ CniPluginDir: options.CNIPluginPath,
+ Compression: string(options.Compression),
+ DefaultsMountFilePath: options.DefaultMountsFilePath,
+ Dockerfiles: dockerfiles,
+ //Err: string(options.Err),
+ ForceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
+ Iidfile: options.IIDFile,
+ Label: options.Labels,
+ Layers: options.Layers,
+ Nocache: options.NoCache,
+ //Out:
+ Output: options.Output,
+ OutputFormat: options.OutputFormat,
+ PullPolicy: options.PullPolicy.String(),
+ Quiet: options.Quiet,
+ RemoteIntermediateCtrs: options.RemoveIntermediateCtrs,
+ //ReportWriter:
+ RuntimeArgs: options.RuntimeArgs,
+ SignaturePolicyPath: options.SignaturePolicyPath,
+ Squash: options.Squash,
+ }
+ // tar the file
+ logrus.Debugf("creating tarball of context dir %s", options.ContextDirectory)
+ input, err := archive.Tar(options.ContextDirectory, archive.Uncompressed)
+ if err != nil {
+ return errors.Wrapf(err, "unable to create tarball of context dir %s", options.ContextDirectory)
+ }
+
+ // Write the tarball to the fs
+ // TODO we might considering sending this without writing to the fs for the sake of performance
+ // under given conditions like memory availability.
+ outputFile, err := ioutil.TempFile("", "varlink_tar_send")
+ if err != nil {
+ return err
+ }
+ defer outputFile.Close()
+ logrus.Debugf("writing context dir tarball to %s", outputFile.Name())
+
+ _, err = io.Copy(outputFile, input)
+ if err != nil {
+ return err
+ }
+
+ logrus.Debugf("completed writing context dir tarball %s", outputFile.Name())
+ // Send the context dir tarball over varlink.
+ tempFile, err := r.SendFileOverVarlink(outputFile.Name())
+ if err != nil {
+ return err
+ }
+ buildinfo.ContextDir = strings.Replace(tempFile, ":", "", -1)
+
+ reply, err := iopodman.BuildImage().Send(r.Conn, varlink.More, buildinfo)
+ if err != nil {
+ return err
+ }
+
+ for {
+ responses, flags, err := reply()
+ if err != nil {
+ return err
+ }
+ for _, line := range responses.Logs {
+ fmt.Print(line)
+ }
+ if flags&varlink.Continues == 0 {
+ break
+ }
+ }
+ return err
+}
+
+// SendFileOverVarlink sends a file over varlink in an upgraded connection
+func (r *LocalRuntime) SendFileOverVarlink(source string) (string, error) {
fs, err := os.Open(source)
if err != nil {
return "", err
@@ -385,6 +490,7 @@ func (r *LocalRuntime) Import(ctx context.Context, source, reference string, cha
if err != nil {
return "", err
}
+ logrus.Debugf("sending %s over varlink connection", source)
reply, err := iopodman.SendFile().Send(r.Conn, varlink.Upgrade, "", int64(fileInfo.Size()))
if err != nil {
return "", err
@@ -399,6 +505,7 @@ func (r *LocalRuntime) Import(ctx context.Context, source, reference string, cha
if err != nil {
return "", err
}
+ logrus.Debugf("file transfer complete for %s", source)
r.Conn.Writer.Flush()
// All was sent, wait for the ACK from the server
@@ -412,7 +519,8 @@ func (r *LocalRuntime) Import(ctx context.Context, source, reference string, cha
return "", err
}
- return iopodman.ImportImage().Call(r.Conn, strings.TrimRight(tempFile, ":"), reference, history, changes, true)
+
+ return tempFile, nil
}
// GetAllVolumes retrieves all the volumes
diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go
index ca920dfeb..534419f6f 100644
--- a/pkg/varlinkapi/images.go
+++ b/pkg/varlinkapi/images.go
@@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
+ "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -24,7 +25,7 @@ import (
sysreg "github.com/containers/libpod/pkg/registries"
"github.com/containers/libpod/pkg/util"
"github.com/containers/libpod/utils"
- "github.com/docker/go-units"
+ "github.com/containers/storage/pkg/archive"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -110,83 +111,46 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error {
// BuildImage ...
func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildInfo) error {
var (
- memoryLimit int64
- memorySwap int64
- namespace []buildah.NamespaceOption
- err error
+ namespace []buildah.NamespaceOption
+ err error
)
systemContext := types.SystemContext{}
- dockerfiles := config.Dockerfile
- contextDir := ""
-
- for i := range dockerfiles {
- if strings.HasPrefix(dockerfiles[i], "http://") ||
- strings.HasPrefix(dockerfiles[i], "https://") ||
- strings.HasPrefix(dockerfiles[i], "git://") ||
- strings.HasPrefix(dockerfiles[i], "github.com/") {
- continue
- }
- absFile, err := filepath.Abs(dockerfiles[i])
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
- }
- contextDir = filepath.Dir(absFile)
- dockerfiles[i], err = filepath.Rel(contextDir, absFile)
- if err != nil {
- return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i])
- }
- break
- }
-
- pullPolicy := imagebuildah.PullNever
- if config.Pull {
- pullPolicy = imagebuildah.PullIfMissing
- }
-
- if config.Pull_always {
- pullPolicy = imagebuildah.PullAlways
- }
- manifestType := "oci" //nolint
- if config.Image_format != "" {
- manifestType = config.Image_format
- }
+ contextDir := config.ContextDir
- if strings.HasPrefix(manifestType, "oci") {
- manifestType = buildah.OCIv1ImageManifest
- } else if strings.HasPrefix(manifestType, "docker") {
- manifestType = buildah.Dockerv2ImageManifest
- } else {
- return call.ReplyErrorOccurred(fmt.Sprintf("unrecognized image type %q", manifestType))
+ newContextDir, err := ioutil.TempDir("", "buildTarball")
+ if err != nil {
+ call.ReplyErrorOccurred("unable to create tempdir")
}
+ logrus.Debugf("created new context dir at %s", newContextDir)
- if config.Memory != "" {
- memoryLimit, err = units.RAMInBytes(config.Memory)
- if err != nil {
- return call.ReplyErrorOccurred(err.Error())
- }
+ reader, err := os.Open(contextDir)
+ if err != nil {
+ logrus.Errorf("failed to open the context dir tar file %s", contextDir)
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to open context dir tar file %s", contextDir))
}
-
- if config.Memory_swap != "" {
- memorySwap, err = units.RAMInBytes(config.Memory_swap)
- if err != nil {
- return call.ReplyErrorOccurred(err.Error())
- }
+ defer reader.Close()
+ if err := archive.Untar(reader, newContextDir, &archive.TarOptions{}); err != nil {
+ logrus.Errorf("fail to untar the context dir tarball (%s) to the context dir (%s)", contextDir, newContextDir)
+ return call.ReplyErrorOccurred(fmt.Sprintf("unable to untar context dir %s", contextDir))
}
+ logrus.Debugf("untar of %s successful", contextDir)
+ // All output (stdout, stderr) is captured in output as well
output := bytes.NewBuffer([]byte{})
+
commonOpts := &buildah.CommonBuildOptions{
- AddHost: config.Add_hosts,
- CgroupParent: config.Cgroup_parent,
- CPUPeriod: uint64(config.Cpu_period),
- CPUQuota: config.Cpu_quota,
- CPUSetCPUs: config.Cpuset_cpus,
- CPUSetMems: config.Cpuset_mems,
- Memory: memoryLimit,
- MemorySwap: memorySwap,
- ShmSize: config.Shm_size,
- Ulimit: config.Ulimit,
- Volumes: config.Volume,
+ AddHost: config.BuildOptions.AddHosts,
+ CgroupParent: config.BuildOptions.CgroupParent,
+ CPUPeriod: uint64(config.BuildOptions.CpuPeriod),
+ CPUQuota: config.BuildOptions.CpuQuota,
+ CPUSetCPUs: config.BuildOptions.CpusetCpus,
+ CPUSetMems: config.BuildOptions.CpusetMems,
+ Memory: config.BuildOptions.Memory,
+ MemorySwap: config.BuildOptions.MemorySwap,
+ ShmSize: config.BuildOptions.ShmSize,
+ Ulimit: config.BuildOptions.Ulimit,
+ Volumes: config.BuildOptions.Volume,
}
hostNetwork := buildah.NamespaceOption{
@@ -197,37 +161,68 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
namespace = append(namespace, hostNetwork)
options := imagebuildah.BuildOptions{
- ContextDirectory: contextDir,
- PullPolicy: pullPolicy,
- Compression: imagebuildah.Gzip,
- Quiet: false,
- //SignaturePolicyPath:
- Args: config.Build_args,
- //Output:
- AdditionalTags: config.Tags,
- //Runtime: runtime.
- //RuntimeArgs: ,
- OutputFormat: manifestType,
- SystemContext: &systemContext,
- CommonBuildOpts: commonOpts,
- Squash: config.Squash,
- Labels: config.Label,
- Annotations: config.Annotations,
- ReportWriter: output,
- NamespaceOptions: namespace,
+ CommonBuildOpts: commonOpts,
+ AdditionalTags: config.AdditionalTags,
+ Annotations: config.Annotations,
+ Args: config.BuildArgs,
+ CNIConfigDir: config.CniConfigDir,
+ CNIPluginPath: config.CniPluginDir,
+ Compression: stringCompressionToArchiveType(config.Compression),
+ ContextDirectory: newContextDir,
+ DefaultMountsFilePath: config.DefaultsMountFilePath,
+ Err: output,
+ ForceRmIntermediateCtrs: config.ForceRmIntermediateCtrs,
+ IIDFile: config.Iidfile,
+ Labels: config.Label,
+ Layers: config.Layers,
+ NoCache: config.Nocache,
+ Out: output,
+ Output: config.Output,
+ NamespaceOptions: namespace,
+ OutputFormat: config.OutputFormat,
+ PullPolicy: stringPullPolicyToType(config.PullPolicy),
+ Quiet: config.Quiet,
+ RemoveIntermediateCtrs: config.RemoteIntermediateCtrs,
+ ReportWriter: output,
+ RuntimeArgs: config.RuntimeArgs,
+ SignaturePolicyPath: config.SignaturePolicyPath,
+ Squash: config.Squash,
+ SystemContext: &systemContext,
}
if call.WantsMore() {
call.Continues = true
}
- c := build(i.Runtime, options, config.Dockerfile)
+ var newPathDockerFiles []string
+
+ for _, d := range config.Dockerfiles {
+ if strings.HasPrefix(d, "http://") ||
+ strings.HasPrefix(d, "https://") ||
+ strings.HasPrefix(d, "git://") ||
+ strings.HasPrefix(d, "github.com/") {
+ newPathDockerFiles = append(newPathDockerFiles, d)
+ continue
+ }
+ base := filepath.Base(d)
+ newPathDockerFiles = append(newPathDockerFiles, filepath.Join(newContextDir, base))
+ }
+
+ c := build(i.Runtime, options, newPathDockerFiles)
var log []string
done := false
for {
- line, err := output.ReadString('\n')
+ outputLine, err := output.ReadString('\n')
if err == nil {
- log = append(log, line)
+ log = append(log, outputLine)
+ if call.WantsMore() {
+ // we want to reply with what we have
+ br := iopodman.MoreResponse{
+ Logs: log,
+ }
+ call.ReplyBuildImage(br)
+ log = []string{}
+ }
continue
} else if err == io.EOF {
select {
@@ -237,15 +232,10 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
}
done = true
default:
- if !call.WantsMore() {
+ if call.WantsMore() {
time.Sleep(1 * time.Second)
break
}
- br := iopodman.MoreResponse{
- Logs: log,
- }
- call.ReplyBuildImage(br)
- log = []string{}
}
} else {
return call.ReplyErrorOccurred(err.Error())
@@ -255,7 +245,8 @@ func (i *LibpodAPI) BuildImage(call iopodman.VarlinkCall, config iopodman.BuildI
}
}
call.Continues = false
- newImage, err := i.Runtime.ImageRuntime().NewFromLocal(config.Tags[0])
+
+ newImage, err := i.Runtime.ImageRuntime().NewFromLocal(config.Output)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go
index 0cb7e5e2e..9a97bc810 100644
--- a/pkg/varlinkapi/transfers.go
+++ b/pkg/varlinkapi/transfers.go
@@ -8,6 +8,7 @@ import (
"os"
"github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/sirupsen/logrus"
)
// SendFile allows a client to send a file to the varlink server
@@ -34,6 +35,7 @@ func (i *LibpodAPI) SendFile(call iopodman.VarlinkCall, ftype string, length int
return err
}
+ logrus.Debugf("successfully received %s", outputFile.Name())
// Send an ACK to the client
call.Call.Writer.WriteString(fmt.Sprintf("%s:", outputFile.Name()))
call.Call.Writer.Flush()
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index 7f6f95d3b..7e487c03a 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -3,11 +3,14 @@ package varlinkapi
import (
"context"
"strconv"
+ "strings"
"time"
+ "github.com/containers/buildah"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ "github.com/containers/storage/pkg/archive"
)
// getContext returns a non-nil, empty context
@@ -133,3 +136,27 @@ func handlePodCall(call iopodman.VarlinkCall, pod *libpod.Pod, ctrErrs map[strin
return nil
}
+
+func stringCompressionToArchiveType(s string) archive.Compression {
+ switch strings.ToUpper(s) {
+ case "BZIP2":
+ return archive.Bzip2
+ case "GZIP":
+ return archive.Gzip
+ case "XZ":
+ return archive.Xz
+ }
+ return archive.Uncompressed
+}
+
+func stringPullPolicyToType(s string) buildah.PullPolicy {
+ switch strings.ToUpper(s) {
+ case "PULLIFMISSING":
+ return buildah.PullIfMissing
+ case "PULLALWAYS":
+ return buildah.PullAlways
+ case "PULLNEVER":
+ return buildah.PullNever
+ }
+ return buildah.PullIfMissing
+}