diff options
-rw-r--r-- | cmd/podman/cp.go | 80 | ||||
-rw-r--r-- | cmd/podman/version.go | 50 | ||||
-rw-r--r-- | docs/podman-cp.1.md | 3 | ||||
-rw-r--r-- | docs/tutorials/podman_tutorial.md | 111 | ||||
-rw-r--r-- | install.md | 198 | ||||
-rw-r--r-- | pkg/adapter/runtime.go | 8 | ||||
-rw-r--r-- | pkg/adapter/runtime_remote.go | 37 | ||||
-rw-r--r-- | test/e2e/cp_test.go | 75 | ||||
-rw-r--r-- | test/e2e/version_test.go | 4 |
9 files changed, 345 insertions, 221 deletions
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 82f2d3f20..4cb8a8c54 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -1,7 +1,9 @@ package main import ( + "archive/tar" "fmt" + "io" "os" "path/filepath" "strings" @@ -142,7 +144,11 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin var lastError error for _, src := range glob { - err := copy(src, destPath, dest, idMappingOpts, &containerOwner, extract) + if src == "-" { + src = os.Stdin.Name() + extract = true + } + err := copy(src, destPath, dest, idMappingOpts, &containerOwner, extract, isFromHostToCtr) if lastError != nil { logrus.Error(lastError) } @@ -195,7 +201,7 @@ func getPathInfo(path string) (string, os.FileInfo, error) { return path, srcfi, nil } -func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract bool) error { +func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract, isFromHostToCtr bool) error { srcPath, err := filepath.EvalSymlinks(src) if err != nil { return errors.Wrapf(err, "error evaluating symlinks %q", srcPath) @@ -205,6 +211,16 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch if err != nil { return err } + + filename := filepath.Base(destPath) + if filename == "-" && !isFromHostToCtr { + err := streamFileToStdout(srcPath, srcfi) + if err != nil { + return errors.Wrapf(err, "error streaming source file %s to Stdout", srcPath) + } + return nil + } + destdir := destPath if !srcfi.IsDir() && !strings.HasSuffix(dest, string(os.PathSeparator)) { destdir = filepath.Dir(destPath) @@ -224,7 +240,6 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch untarPath := chrootarchive.UntarPathAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) if srcfi.IsDir() { - logrus.Debugf("copying %q to %q", srcPath+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*") if destDirIsExist && !strings.HasSuffix(src, fmt.Sprintf("%s.", string(os.PathSeparator))) { destPath = filepath.Join(destPath, filepath.Base(srcPath)) @@ -276,3 +291,62 @@ func convertIDMap(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping } return convertedIDMap } + +func streamFileToStdout(srcPath string, srcfi os.FileInfo) error { + if srcfi.IsDir() { + tw := tar.NewWriter(os.Stdout) + err := filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error { + if err != nil || !info.Mode().IsRegular() || path == srcPath { + return err + } + hdr, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + + if err = tw.WriteHeader(hdr); err != nil { + return err + } + fh, err := os.Open(path) + if err != nil { + return err + } + defer fh.Close() + + _, err = io.Copy(tw, fh) + return err + }) + if err != nil { + return errors.Wrapf(err, "error streaming directory %s to Stdout", srcPath) + } + return nil + } + + file, err := os.Open(srcPath) + if err != nil { + return errors.Wrapf(err, "error opening file %s", srcPath) + } + defer file.Close() + if !archive.IsArchivePath(srcPath) { + tw := tar.NewWriter(os.Stdout) + hdr, err := tar.FileInfoHeader(srcfi, "") + if err != nil { + return err + } + err = tw.WriteHeader(hdr) + if err != nil { + return err + } + _, err = io.Copy(tw, file) + if err != nil { + return errors.Wrapf(err, "error streaming archive %s to Stdout", srcPath) + } + return nil + } + + _, err = io.Copy(os.Stdout, file) + if err != nil { + return errors.Wrapf(err, "error streaming file to Stdout") + } + return nil +} diff --git a/cmd/podman/version.go b/cmd/podman/version.go index e964bdbb5..439a1cca6 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "os" "strings" "text/tabwriter" @@ -10,6 +11,7 @@ import ( "github.com/containers/buildah/pkg/formats" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/adapter" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -38,7 +40,7 @@ func init() { // versionCmd gets and prints version info for version command func versionCmd(c *cliconfig.VersionValues) error { - output, err := libpod.GetVersion() + clientVersion, err := libpod.GetVersion() if err != nil { errors.Wrapf(err, "unable to determine version") } @@ -51,25 +53,49 @@ func versionCmd(c *cliconfig.VersionValues) error { var out formats.Writer switch versionOutputFormat { case formats.JSONString: - out = formats.JSONStruct{Output: output} + out = formats.JSONStruct{Output: clientVersion} default: - out = formats.StdoutTemplate{Output: output, Template: versionOutputFormat} + out = formats.StdoutTemplate{Output: clientVersion, Template: versionOutputFormat} } return formats.Writer(out).Out() } w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) defer w.Flush() - fmt.Fprintf(w, "Version:\t%s\n", output.Version) - fmt.Fprintf(w, "RemoteAPI Version:\t%d\n", output.RemoteAPIVersion) - fmt.Fprintf(w, "Go Version:\t%s\n", output.GoVersion) - if output.GitCommit != "" { - fmt.Fprintf(w, "Git Commit:\t%s\n", output.GitCommit) + + if remote { + fmt.Fprintf(w, "Client:\n") + } + formatVersion(w, clientVersion) + + if remote { + fmt.Fprintf(w, "\nService:\n") + + runtime, err := adapter.GetRuntime(getContext(), nil) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + + serviceVersion, err := runtime.GetVersion() + if err != nil { + return err + } + formatVersion(w, serviceVersion) + } + return nil +} + +func formatVersion(writer io.Writer, version libpod.Version) { + fmt.Fprintf(writer, "Version:\t%s\n", version.Version) + fmt.Fprintf(writer, "RemoteAPI Version:\t%d\n", version.RemoteAPIVersion) + 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 output.Built != 0 { - fmt.Fprintf(w, "Built:\t%s\n", time.Unix(output.Built, 0).Format(time.ANSIC)) + if version.Built != 0 { + fmt.Fprintf(writer, "Built:\t%s\n", time.Unix(version.Built, 0).Format(time.ANSIC)) } - fmt.Fprintf(w, "OS/Arch:\t%s\n", output.OsArch) - return nil + fmt.Fprintf(writer, "OS/Arch:\t%s\n", version.OsArch) } diff --git a/docs/podman-cp.1.md b/docs/podman-cp.1.md index 44612003d..406dd51df 100644 --- a/docs/podman-cp.1.md +++ b/docs/podman-cp.1.md @@ -8,6 +8,7 @@ podman\-cp - Copy files/folders between a container and the local filesystem ## DESCRIPTION Copies the contents of **src_path** to the **dest_path**. You can copy from the containers's filesystem to the local machine or the reverse, from the local filesystem to the container. +If - is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT. The CONTAINER can be a running or stopped container. The **src_path** or **dest_path** can be a file or directory. @@ -107,5 +108,7 @@ podman cp containerID:/home/myuser/. /home/myuser/ podman cp --extract /home/myuser/myfiles.tar.gz containerID:/myfiles +podman cp - containerID:/myfiles.tar.gz < myfiles.tar.gz + ## SEE ALSO podman(1), podman-mount(1), podman-umount(1) diff --git a/docs/tutorials/podman_tutorial.md b/docs/tutorials/podman_tutorial.md index f972853e6..032b7c851 100644 --- a/docs/tutorials/podman_tutorial.md +++ b/docs/tutorials/podman_tutorial.md @@ -8,114 +8,9 @@ commands with Podman. **NOTE**: the code samples are intended to be run as a non-root user, and use `sudo` where root escalation is required. -## Install Podman on Fedora from RPM Repositories -Fedora 27 and later provide Podman via the package manager. -```console -sudo dnf install -y podman -``` - -*Optional*: If you've already installed podman on Fedora and you're feeling -adventerous, you can test the very latest podman in Fedora's `updates-testing` -repository before it goes out to all Fedora users. -```console -sudo yum distro-sync --enablerepo=updates-testing podman -``` - -If you use a newer podman package from Fedora's `updates-testing`, we would -appreciate your `+1` feedback in [Bodhi, Fedora's update management -system](https://bodhi.fedoraproject.org/updates/?packages=podman). - -## Install Podman on Fedora from Source -Many of the basic components to run Podman are readily available from the Fedora RPM repositories. -In this section, we will help you install all the runtime and build dependencies for Podman, -acquire the source, and build it. - -### Installing build and runtime dependencies -```console -sudo dnf install -y git runc libassuan-devel golang golang-github-cpuguy83-go-md2man glibc-static \ - gpgme-devel glib2-devel device-mapper-devel libseccomp-devel \ - atomic-registries iptables containers-common containernetworking-cni \ - conmon ostree-devel -``` -### Building and installing podman - -First, configure a `GOPATH` (if you are using go1.8 or later, this defaults to `~/go`), then clone -and make libpod. - -```console -export GOPATH=~/go -mkdir -p $GOPATH -git clone https://github.com/containers/libpod/ $GOPATH/src/github.com/containers/libpod -cd $GOPATH/src/github.com/containers/libpod -make -sudo make install PREFIX=/usr -``` - -You now have a working podman environment. Jump to [Familiarizing yourself with Podman](#familiarizing-yourself-with-podman) -to begin using Podman. - -## Install podman on Ubuntu - -The default Ubuntu cloud image size will not allow for the following exercise to be done without increasing its -capacity. Be sure to add at least 5GB to the image. Instructions to do this are outside the scope of this -tutorial. For this tutorial, the Ubuntu **artful-server-cloudimg** image was used. +## Installing Podman -### Installing build and runtime dependencies - -#### Installing base packages -```console -sudo apt-get update -sudo apt-get install libdevmapper-dev libglib2.0-dev libgpgme11-dev golang libseccomp-dev libostree-dev \ - go-md2man libprotobuf-dev libprotobuf-c0-dev libseccomp-dev python3-setuptools -``` -#### Building and installing conmon -First, configure a `GOPATH` (if you are using go1.8 or later, this defaults to `~/go`), then clone -and make libpod. - -```console -export GOPATH=~/go -mkdir -p $GOPATH -git clone https://github.com/kubernetes-sigs/cri-o $GOPATH/src/github.com/kubernetes-sigs/cri-o -cd $GOPATH/src/github.com/kubernetes-sigs/cri-o -mkdir bin -make bin/conmon -sudo install -D -m 755 bin/conmon /usr/libexec/podman/conmon -``` -#### Adding required configuration files -```console -sudo mkdir -p /etc/containers -sudo curl https://raw.githubusercontent.com/projectatomic/registries/master/registries.fedora -o /etc/containers/registries.conf -sudo curl https://raw.githubusercontent.com/containers/skopeo/master/default-policy.json -o /etc/containers/policy.json -``` -#### Installing CNI plugins -```console -git clone https://github.com/containernetworking/plugins.git $GOPATH/src/github.com/containernetworking/plugins -cd $GOPATH/src/github.com/containernetworking/plugins -./build_linux.sh -sudo mkdir -p /usr/libexec/cni -sudo cp bin/* /usr/libexec/cni -``` -#### Installing CNI config -Add a most basic network config -```console -mkdir -p /etc/cni/net.d -curl -qsSL https://raw.githubusercontent.com/containers/libpod/master/cni/87-podman-bridge.conflist | sudo tee /etc/cni/net.d/99-loopback.conf -``` -#### Installing runc -```console -git clone https://github.com/opencontainers/runc.git $GOPATH/src/github.com/opencontainers/runc -cd $GOPATH/src/github.com/opencontainers/runc -make BUILDTAGS="seccomp" -sudo cp runc /usr/bin/runc -``` - -### Building and installing Podman -```console -git clone https://github.com/containers/libpod/ $GOPATH/src/github.com/containers/libpod -cd $GOPATH/src/github.com/containers/libpod -make -sudo make install PREFIX=/usr -``` +For installing or building Podman, please see the [installation instructions](install.md). ## Familiarizing yourself with Podman @@ -128,7 +23,7 @@ podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/var/run/httpd -e HTTPD_MAIN_CO -e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \ registry.fedoraproject.org/f27/httpd /usr/bin/run-httpd ``` -Because the container is being run in detached mode, represented by the *-d* in the podman run command, podman +Because the container is being run in detached mode, represented by the *-d* in the `podman run` command, Podman will print the container ID after it has run. Note that we use port forwarding to be able to access the HTTP server. For successful running at least slirp4netns v0.3.0 is needed. diff --git a/install.md b/install.md index bd7f326c3..82dd4c36a 100644 --- a/install.md +++ b/install.md @@ -8,7 +8,7 @@ sudo pacman -S podman ``` -If you have problems when running podman in [rootless](README.md#rootless) mode follow [these instructions](https://wiki.archlinux.org/index.php/Linux_Containers#Enable_support_to_run_unprivileged_containers_(optional)) +If you have problems when running Podman in [rootless](README.md#rootless) mode follow the instructions [here](https://wiki.archlinux.org/index.php/Linux_Containers#Enable_support_to_run_unprivileged_containers_(optional)) #### [Fedora](https://www.fedoraproject.org), [CentOS](https://www.centos.org) @@ -16,7 +16,6 @@ If you have problems when running podman in [rootless](README.md#rootless) mode sudo yum -y install podman ``` - #### [Fedora-CoreOS](https://coreos.fedoraproject.org), [Fedora SilverBlue](https://silverblue.fedoraproject.org) Built-in, no need to install @@ -39,7 +38,7 @@ Built-in, no need to install #### [RHEL7](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux) -Subscribe, then enable Extras channel and install podman. +Subscribe, then enable Extras channel and install Podman. ```bash sudo subscription-manager repos --enable=rhel-7-server-extras-rpms @@ -53,8 +52,12 @@ sudo yum module enable -y container-tools:1.0 sudo yum module install -y container-tools:1.0 ``` +### Installing development versions of Podman + #### [Ubuntu](https://www.ubuntu.com) +The latest builds are available in a PPA. Take note of the [Build and Run Dependencies](#build-and-run-dependencies) listed below if you run into any issues. + ```bash sudo apt-get update -qq sudo apt-get install -qq -y software-properties-common uidmap @@ -63,25 +66,20 @@ sudo apt-get update -qq sudo apt-get -qq -y install podman ``` -Take note of the [Build and Run Dependencies](#build-and-run-dependencies) listed below if you run into any issues. - -## Building from scratch +#### Fedora -### Prerequisites +You can test the very latest Podman in Fedora's `updates-testing` +repository before it goes out to all Fedora users. -#### runc installed - -The latest version of `runc` is expected to be installed on the system. It is picked up as the default runtime by podman. - -#### conmon installed - -The latest version of `conmon` is expected to be installed on the system. Conmon is used to monitor OCI Runtimes. +```console +sudo yum distro-sync --enablerepo=updates-testing podman +``` -#### Setup CNI networking +If you use a newer Podman package from Fedora's `updates-testing`, we would +appreciate your `+1` feedback in [Bodhi, Fedora's update management +system](https://bodhi.fedoraproject.org/updates/?packages=podman). -A proper description of setting up CNI networking is given in the [`cni` README](cni/README.md). -But the gist is that you need to have some basic network configurations enabled and -CNI plugins installed on your system. +## Building from scratch ### Build and Run Dependencies @@ -90,7 +88,7 @@ CNI plugins installed on your system. Fedora, CentOS, RHEL, and related distributions: ```bash -yum install -y \ +sudo yum install -y \ atomic-registries \ btrfs-progs-devel \ conmon \ @@ -118,42 +116,133 @@ yum install -y \ Debian, Ubuntu, and related distributions: ```bash -apt-get install -y \ +sudo apt-get install \ btrfs-tools \ git \ golang-go \ go-md2man \ iptables \ libassuan-dev \ + libc6-dev \ libdevmapper-dev \ libglib2.0-dev \ - libc6-dev \ - libgpgme11-dev \ + libgpgme-dev \ libgpg-error-dev \ + libostree-dev \ libprotobuf-dev \ libprotobuf-c0-dev \ libseccomp-dev \ libselinux1-dev \ + libsystemd-dev \ pkg-config \ + runc \ uidmap ``` -Debian, Ubuntu, and related distributions will also need to do the following setup: +### Building missing dependencies - * A copy of the development libraries for `ostree`, either in the form of the `libostree-dev` package from the [flatpak](https://launchpad.net/~alexlarsson/+archive/ubuntu/flatpak) PPA, or built [from source](https://github.com/ostreedev/ostree) (more on that [here](https://ostree.readthedocs.io/en/latest/#building)). As of Ubuntu 18.04, `libostree-dev` is available in the main repositories, and the PPA is no longer required. - * [Add required configuration files](https://github.com/containers/libpod/blob/master/docs/tutorials/podman_tutorial.md#adding-required-configuration-files) - * Install conmon, CNI plugins and runc - * [Install conmon](https://github.com/containers/libpod/blob/master/docs/tutorials/podman_tutorial.md#building-and-installing-conmon) - * [Install CNI plugins](https://github.com/containers/libpod/blob/master/docs/tutorials/podman_tutorial.md#installing-cni-plugins) - * [runc Installation](https://github.com/containers/libpod/blob/master/docs/tutorials/podman_tutorial.md#installing-runc) - Although installable, the latest runc is not available in the Ubuntu repos. Version 1.0.0-rc4 is the minimal requirement. +If any dependencies cannot be installed or are not sufficiently current, they have to be built from source. +This will mainly affect Debian, Ubuntu, and related distributions, or RHEL where no subscription is active (e.g. Cloud VMs). -**NOTE** +#### ostree -If using an older release or a long-term support release, be careful to double-check that the version of `runc` is new enough (running `runc --version` should produce `spec: 1.0.0`), or else [build](https://github.com/containers/libpod/blob/master/docs/tutorials/podman_tutorial.md#installing-runc) your own. +A copy of the development libraries for `ostree` is necessary, either in the form of the `libostree-dev` package +from the [flatpak](https://launchpad.net/~alexlarsson/+archive/ubuntu/flatpak) PPA, +or built [from source](https://github.com/ostreedev/ostree/blob/master/docs/contributing-tutorial.md) +(see also [here](https://ostree.readthedocs.io/en/latest/#building)). As of Ubuntu 18.04, `libostree-dev` is available in the main repositories, +and the PPA is no longer required. -Be careful to double-check that the version of golang is new enough, version 1.10.x or higher is required. If needed, golang kits are available at https://golang.org/dl/ +To build, use the following (running `make` can take a while): +```bash +git clone https://github.com/ostreedev/ostree ~/ostree +cd ~/ostree +git submodule update --init +# for Fedora, CentOS, RHEL +sudo yum install -y automake bison e2fsprogs-devel fuse-devel libtool xz-devel zlib-devel +# for Debian, Ubuntu etc. +sudo apt-get install -y automake bison e2fsprogs fuse liblzma-dev libtool zlib1g + +./autogen.sh --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc +# remove --nonet option due to https:/github.com/ostreedev/ostree/issues/1374 +sed -i '/.*--nonet.*/d' ./Makefile-man.am +make +sudo make install +``` + +#### golang + +Be careful to double-check that the version of golang is new enough (i.e. `go version`), version 1.10.x or higher is required. +If needed, golang kits are available at https://golang.org/dl/. Alternatively, go can be built from source as follows +(it's helpful to leave the system-go installed, to avoid having to [bootstrap go](https://golang.org/doc/install/source): + +```bash +export GOPATH=~/go +git clone https://go.googlesource.com/go $GOPATH +cd $GOPATH +git checkout tags/go1.10.8 # optional +cd src +./all.bash +export PATH=$GOPATH/bin:$PATH +``` -**Optional** +#### conmon + +The latest version of `conmon` is expected to be installed on the system. Conmon is used to monitor OCI Runtimes. +To build from source, use the following (if not already executed above, run `export GOPATH=~/go && mkdir -p $GOPATH`): + +```bash +git clone https://github.com/cri-o/cri-o $GOPATH/src/github.com/cri-o/cri-o +cd $GOPATH/src/github.com/cri-o/cri-o +mkdir bin +make bin/conmon +sudo install -D -m 755 bin/conmon /usr/libexec/podman/conmon +``` + +#### runc + +The latest version of `runc` is expected to be installed on the system. It is picked up as the default runtime by Podman. +Version 1.0.0-rc4 is the minimal requirement, which is available in Ubuntu 18.04 already. +To double-check, `runc --version` should produce at least `spec: 1.0.1`, otherwise build your own: + +```bash +git clone https://github.com/opencontainers/runc.git $GOPATH/src/github.com/opencontainers/runc +cd $GOPATH/src/github.com/opencontainers/runc +make BUILDTAGS="selinux seccomp" +sudo cp runc /usr/bin/runc +``` + +#### CNI plugins + +```bash +git clone https://github.com/containernetworking/plugins.git $GOPATH/src/github.com/containernetworking/plugins +cd $GOPATH/src/github.com/containernetworking/plugins +./build_linux.sh +sudo mkdir -p /usr/libexec/cni +sudo cp bin/* /usr/libexec/cni +``` + +#### Setup CNI networking + +A proper description of setting up CNI networking is given in the [`cni` README](cni/README.md). + +Using the CNI plugins from above, a more basic network config is achieved with: + +```bash +mkdir -p /etc/cni/net.d +curl -qsSL https://raw.githubusercontent.com/containers/libpod/master/cni/87-podman-bridge.conflist | sudo tee /etc/cni/net.d/99-loopback.conf +``` + + +#### Add configuration + +```bash +sudo mkdir -p /etc/containers +sudo curl https://raw.githubusercontent.com/projectatomic/registries/master/registries.fedora -o /etc/containers/registries.conf +sudo curl https://raw.githubusercontent.com/containers/skopeo/master/default-policy.json -o /etc/containers/policy.json +``` + + +#### Optional packages Fedora, CentOS, RHEL, and related distributions: @@ -168,53 +257,38 @@ apt-get install -y \ ### Get Source Code -As with other Go projects, PODMAN must be cloned into a directory structure like: +As with other Go projects, Podman must be cloned into a directory structure like: ``` GOPATH └── src └── github.com - └── containers - └── libpod -``` - -First, configure a `GOPATH` (if you are using go1.8 or later, this defaults to `~/go`) -and then add $GOPATH/bin to your $PATH environment variable. - -```bash -export GOPATH=~/go -mkdir -p $GOPATH -export PATH=$PATH:$GOPATH/bin + └── containers + └── libpod ``` -Next, clone the source code using: +First, ensure that the go version that is found first on the $PATH (in case you built your own; see [above](#golang)) is sufficiently recent - +`go version` must be higher than 1.10.x). Then we can finally build Podman (assuming we already have a `$GOPATH` and the corresponding folder, +`export GOPATH=~/go && mkdir -p $GOPATH`): ```bash -mkdir -p $GOPATH/src/github.com/containers -cd $_ # or cd $GOPATH/src/github.com/containers -git clone https://github.com/containers/libpod # or your fork -cd libpod +git clone https://github.com/containers/libpod/ $GOPATH/src/github.com/containers/libpod +cd $GOPATH/src/github.com/containers/libpod +make BUILDTAGS="selinux seccomp" +sudo make install PREFIX= ``` -### Build - -```bash -make install.tools -make -sudo make install -``` +#### Build Tags -Otherwise, if you do not want to build `podman` with seccomp support you can add `BUILDTAGS=""` when running make. +Otherwise, if you do not want to build Podman with seccomp or selinux support you can add `BUILDTAGS=""` when running make. ```bash make BUILDTAGS="" sudo make install ``` -#### Build Tags - -`podman` supports optional build tags for compiling support of various features. -To add build tags to the make option the `BUILDTAGS` variable must be set. +Podman supports optional build tags for compiling support of various features. +To add build tags to the make option the `BUILDTAGS` variable must be set, for example: ```bash make BUILDTAGS='seccomp apparmor' diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go index 0d840d65b..21613c425 100644 --- a/pkg/adapter/runtime.go +++ b/pkg/adapter/runtime.go @@ -5,12 +5,13 @@ package adapter import ( "bufio" "context" - "github.com/containers/libpod/cmd/podman/shared" "io" "io/ioutil" "os" "text/template" + "github.com/containers/libpod/cmd/podman/shared" + "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" "github.com/containers/buildah/pkg/parse" @@ -392,3 +393,8 @@ func (r *LocalRuntime) GetPodsByStatus(statuses []string) ([]*libpod.Pod, error) return pods, nil } + +// GetVersion is an alias to satisfy interface{} +func (r *LocalRuntime) GetVersion() (libpod.Version, error) { + return libpod.GetVersion() +} diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index 8803a26fb..e86287462 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -9,12 +9,13 @@ import ( "fmt" "io" "io/ioutil" - v1 "k8s.io/api/core/v1" "os" "strings" "text/template" "time" + v1 "k8s.io/api/core/v1" + "github.com/containers/buildah/imagebuildah" "github.com/containers/image/docker/reference" "github.com/containers/image/types" @@ -415,19 +416,19 @@ func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, opti Compression: string(options.Compression), DefaultsMountFilePath: options.DefaultMountsFilePath, Dockerfiles: dockerfiles, - //Err: string(options.Err), + // Err: string(options.Err), ForceRmIntermediateCtrs: options.ForceRmIntermediateCtrs, Iidfile: options.IIDFile, Label: options.Labels, Layers: options.Layers, Nocache: options.NoCache, - //Out: + // Out: Output: options.Output, OutputFormat: options.OutputFormat, PullPolicy: options.PullPolicy.String(), Quiet: options.Quiet, RemoteIntermediateCtrs: options.RemoveIntermediateCtrs, - //ReportWriter: + // ReportWriter: RuntimeArgs: options.RuntimeArgs, SignaturePolicyPath: options.SignaturePolicyPath, Squash: options.Squash, @@ -611,7 +612,7 @@ func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeIn return varlinkVolumeToVolume(r, reply), nil } -//Volumes returns a slice of adapter.volumes based on information about libpod +// Volumes returns a slice of adapter.volumes based on information about libpod // volumes over a varlink connection func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) { reply, err := iopodman.GetVolumes().Call(r.Conn, []string{}, true) @@ -907,3 +908,29 @@ func (r *LocalRuntime) GetContainersByContext(all bool, latest bool, namesOrIDs } return containers, nil } + +// GetVersion returns version information from service +func (r *LocalRuntime) GetVersion() (libpod.Version, error) { + version, goVersion, gitCommit, built, osArch, apiVersion, err := iopodman.GetVersion().Call(r.Conn) + if err != nil { + return libpod.Version{}, errors.Wrapf(err, "Unable to obtain server version information") + } + + var buildTime int64 + if built != "" { + t, err := time.Parse(time.RFC3339, built) + if err != nil { + return libpod.Version{}, nil + } + buildTime = t.Unix() + } + + return libpod.Version{ + RemoteAPIVersion: apiVersion, + Version: version, + GoVersion: goVersion, + GitCommit: gitCommit, + Built: buildTime, + OsArch: osArch, + }, nil +} diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 591f533d6..273668f35 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" @@ -58,21 +59,12 @@ var _ = Describe("Podman cp", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "-a", name}) - session.WaitWithDefaultTimeout() - - Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal("copy from host to container")) - session = podmanTest.Podman([]string{"cp", name + ":foo", filepath.Join(path, "cp_from_container")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - c := exec.Command("cat", filepath.Join(path, "cp_from_container")) - output, err := c.Output() - if err != nil { - os.Exit(1) - } - Expect(string(output)).To(Equal("copy from host to container")) + + os.Remove("cp_from_container") + os.Remove("cp_test.txt") }) It("podman cp file to dir", func() { @@ -89,28 +81,18 @@ var _ = Describe("Podman cp", func() { session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foodir/"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"ps", "-a", "-q"}) - session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) name := session.OutputToString() session = podmanTest.Podman([]string{"cp", filepath.Join(path, "cp_test.txt"), name + ":foodir/"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "-a", name}) - session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal("cp_test.txt")) session = podmanTest.Podman([]string{"cp", name + ":foodir/cp_test.txt", path + "/receive/"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - c := exec.Command("cat", filepath.Join(path, "receive", "cp_test.txt")) - output, err := c.Output() - if err != nil { - os.Exit(1) - } - Expect(string(output)).To(Equal("copy from host to container directory")) + + os.Remove("cp_test.txt") + os.RemoveAll("receive") }) It("podman cp dir to dir", func() { @@ -132,17 +114,50 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", testDirPath, name + ":/foodir"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "-a", name}) + + session = podmanTest.Podman([]string{"cp", testDirPath, name + ":/foodir"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(len(session.OutputToStringArray())).To(Equal(0)) - session = podmanTest.Podman([]string{"cp", testDirPath, name + ":/foodir"}) + os.RemoveAll(testDirPath) + }) + + It("podman cp stdin/stdout", func() { + path, err := os.Getwd() + if err != nil { + os.Exit(1) + } + testDirPath := filepath.Join(path, "TestDir") + err = os.Mkdir(testDirPath, 0777) + if err != nil { + os.Exit(1) + } + cmd := exec.Command("tar", "-zcvf", "file.tar.gz", testDirPath) + _, err = cmd.Output() + if err != nil { + os.Exit(1) + } + + session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + name := session.OutputToString() + + data, err := ioutil.ReadFile("foo.tar.gz") + reader := strings.NewReader(string(data)) + cmd.Stdin = reader + session = podmanTest.Podman([]string{"cp", "-", name + ":/foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "-a", name}) + + session = podmanTest.Podman([]string{"cp", "file.tar.gz", name + ":/foo.tar.gz"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal("TestDir")) + session = podmanTest.Podman([]string{"cp", name + ":/foo.tar.gz", "-"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + os.Remove("file.tar.gz") + os.RemoveAll(testDirPath) }) }) diff --git a/test/e2e/version_test.go b/test/e2e/version_test.go index f546158a9..35ee21e49 100644 --- a/test/e2e/version_test.go +++ b/test/e2e/version_test.go @@ -31,6 +31,7 @@ var _ = Describe("Podman version", func() { }) It("podman version", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"version"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -38,6 +39,7 @@ var _ = Describe("Podman version", func() { }) It("podman version --format json", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"version", "--format", "json"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -45,6 +47,7 @@ var _ = Describe("Podman version", func() { }) It("podman version --format json", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"version", "--format", "{{ json .}}"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -52,6 +55,7 @@ var _ = Describe("Podman version", func() { }) It("podman version --format GO template", func() { + SkipIfRemote() session := podmanTest.Podman([]string{"version", "--format", "{{ .Version }}"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) |