summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--Makefile14
-rw-r--r--README.md4
-rw-r--r--cmd/podman/cliconfig/config.go1
-rw-r--r--cmd/podman/main.go5
-rw-r--r--cmd/podman/main_local.go5
-rw-r--r--cmd/podman/main_remote.go10
-rw-r--r--cmd/podman/remoteclientconfig/config.go1
-rw-r--r--cmd/podman/remoteclientconfig/configfile_test.go14
-rw-r--r--contrib/cirrus/lib.sh18
-rw-r--r--contrib/msi/podman.bat25
-rw-r--r--contrib/msi/podman.wxs5
-rw-r--r--docs/links-to-html.lua5
-rw-r--r--docs/podman-remote.1.md4
-rw-r--r--docs/podman-remote.conf.5.md4
-rwxr-xr-xdocs/podman-remote.sh105
-rw-r--r--docs/tutorials/README.md10
-rw-r--r--docs/tutorials/mac_client.md (renamed from mac_client.md)0
-rw-r--r--docs/tutorials/podman_tutorial.md3
-rw-r--r--docs/tutorials/remote_client.md (renamed from remote_client.md)4
-rw-r--r--go.mod2
-rw-r--r--go.sum2
-rw-r--r--libpod/runtime.go2
-rw-r--r--pkg/adapter/client.go2
-rw-r--r--pkg/adapter/client_unix.go8
-rw-r--r--pkg/spec/storage.go20
-rw-r--r--rootless.md3
-rw-r--r--vendor/github.com/containers/storage/Makefile1
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/images.go30
-rw-r--r--vendor/github.com/containers/storage/layers.go71
-rw-r--r--vendor/github.com/containers/storage/store.go10
-rw-r--r--vendor/modules.txt2
33 files changed, 309 insertions, 85 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 70f65436e..461a39e4b 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -489,7 +489,7 @@ special_testing_cgroupv2_task:
TEST_REMOTE_CLIENT: true
TEST_REMOTE_CLIENT: false
- timeout_in: 20m
+ timeout_in: 120m
networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
diff --git a/Makefile b/Makefile
index 0dc72ce4d..6734ef1b0 100644
--- a/Makefile
+++ b/Makefile
@@ -165,8 +165,13 @@ podman-remote: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build with podman on
$(GO_BUILD) $(BUILDFLAGS) -gcflags '$(GCFLAGS)' -asmflags '$(ASMFLAGS)' -ldflags '$(LDFLAGS_PODMAN)' -tags "$(BUILDTAGS) remoteclient" -o bin/$@ $(PROJECT)/cmd/podman
.PHONY: podman.msi
-podman.msi: podman-remote-windows ## Will always rebuild exe as there is no podman-remote-windows.exe target to verify timestamp
- wixl -D VERSION=$(RELEASE_NUMBER) -o bin/podman-v$(RELEASE_NUMBER).msi contrib/msi/podman.wxs
+podman.msi: podman-remote podman-remote-windows docs ## Will always rebuild exe as there is no podman-remote-windows.exe target to verify timestamp
+ rm -rf bin/windows
+ mkdir -p bin/windows
+ docs/podman-remote.sh windows bin/windows docs
+ find bin/windows -print \
+ |wixl-heat --var var.ManSourceDir --component-group ManFiles --directory-ref INSTALLDIR --prefix bin/windows/ >bin/windows/pages.wsx
+ wixl -D VERSION=$(RELEASE_NUMBER) -D ManSourceDir=bin/windows -o podman-v$(RELEASE_NUMBER).msi contrib/msi/podman.wxs bin/windows/pages.wsx
podman-remote-%: .gopathok $(PODMAN_VARLINK_DEPENDENCIES) ## Build podman for a specific GOOS
$(eval BINSFX := $(shell test "$*" != "windows" || echo ".exe"))
@@ -316,8 +321,9 @@ $(MANPAGES): %: %.md .gopathok
docs: $(MANPAGES) ## Generate documentation
-install-podman-remote-docs: docs
- @(cd docs; ./podman-remote.sh ./remote)
+install-podman-remote-docs: podman-remote docs
+ rm -rf docs/remote
+ docs/podman-remote.sh darwin docs/remote docs
man-page-check:
./hack/man-page-checker
diff --git a/README.md b/README.md
index f04dd75d5..4cdccd3a9 100644
--- a/README.md
+++ b/README.md
@@ -102,10 +102,10 @@ includes tables showing Docker commands and their Podman equivalent commands.
**[Tutorials](docs/tutorials)**
Tutorials on using Podman.
-**[Remote Client](remote_client.md)**
+**[Remote Client](https://github.com/containers/libpod/blob/master/docs/tutorials/remote_client.md)**
A brief how-to on using the Podman remote-client.
-**[Basic Setup and Use of Podman in a Rootless environment](https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md)
+**[Basic Setup and Use of Podman in a Rootless environment](https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md)**
A tutorial showing the setup and configuration necessary to run Rootless Podman.
**[Release Notes](RELEASE_NOTES.md)**
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go
index e0ce202cc..b8796f9b3 100644
--- a/cmd/podman/cliconfig/config.go
+++ b/cmd/podman/cliconfig/config.go
@@ -41,6 +41,7 @@ type MainFlags struct {
VarlinkAddress string
ConnectionName string
RemoteConfigFilePath string
+ Port int
}
type AttachValues struct {
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index b83ccd9a5..992dbe1d5 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -111,6 +111,11 @@ func before(cmd *cobra.Command, args []string) error {
return err
}
+ // check that global opts input is valid
+ if err := checkInput(); err != nil {
+ return err
+ }
+
// Set log level; if not log-level is provided, default to error
logLevel := MainGlobalOpts.LogLevel
if logLevel == "" {
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 08d7ccaf4..917096e17 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -267,3 +267,8 @@ func setUMask() {
// Be sure we can create directories with 0755 mode.
syscall.Umask(0022)
}
+
+// checkInput can be used to verify any of the globalopt values
+func checkInput() error {
+ return nil
+}
diff --git a/cmd/podman/main_remote.go b/cmd/podman/main_remote.go
index a005e925c..f617422e6 100644
--- a/cmd/podman/main_remote.go
+++ b/cmd/podman/main_remote.go
@@ -3,6 +3,7 @@
package main
import (
+ "github.com/pkg/errors"
"os/user"
"github.com/spf13/cobra"
@@ -18,6 +19,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.ConnectionName, "connection", "", "remote connection name")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.RemoteConfigFilePath, "remote-config-path", "", "alternate path for configuration file")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.RemoteUserName, "username", username, "username on the remote host")
+ rootCmd.PersistentFlags().IntVar(&MainGlobalOpts.Port, "port", 22, "port on remote host")
rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.RemoteHost, "remote-host", "", "remote host")
// TODO maybe we allow the altering of this for bridge connections?
// rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.VarlinkAddress, "varlink-address", adapter.DefaultAddress, "address of the varlink socket")
@@ -42,3 +44,11 @@ func setRLimits() error {
}
func setUMask() {}
+
+// checkInput can be used to verify any of the globalopt values
+func checkInput() error {
+ if MainGlobalOpts.Port < 0 || MainGlobalOpts.Port > 65536 {
+ return errors.Errorf("remote port must be between 0 and 65536")
+ }
+ return nil
+}
diff --git a/cmd/podman/remoteclientconfig/config.go b/cmd/podman/remoteclientconfig/config.go
index 01f293ec3..13880a868 100644
--- a/cmd/podman/remoteclientconfig/config.go
+++ b/cmd/podman/remoteclientconfig/config.go
@@ -12,6 +12,7 @@ type RemoteConnection struct {
Destination string `toml:"destination"`
Username string `toml:"username"`
IsDefault bool `toml:"default"`
+ Port int `toml:"port"`
}
// GetConfigFilePath is a simple helper to export the configuration file's
diff --git a/cmd/podman/remoteclientconfig/configfile_test.go b/cmd/podman/remoteclientconfig/configfile_test.go
index 66e0a4693..ea2224ea7 100644
--- a/cmd/podman/remoteclientconfig/configfile_test.go
+++ b/cmd/podman/remoteclientconfig/configfile_test.go
@@ -13,11 +13,13 @@ var goodConfig = `
[connections.homer]
destination = "192.168.1.1"
username = "myuser"
+port = 22
default = true
[connections.bart]
destination = "foobar.com"
username = "root"
+port = 22
`
var noDest = `
[connections]
@@ -26,9 +28,11 @@ var noDest = `
destination = "192.168.1.1"
username = "myuser"
default = true
+port = 22
[connections.bart]
username = "root"
+port = 22
`
var noUser = `
@@ -36,6 +40,7 @@ var noUser = `
[connections.homer]
destination = "192.168.1.1"
+port = 22
`
func makeGoodResult() *RemoteConfig {
@@ -44,10 +49,12 @@ func makeGoodResult() *RemoteConfig {
Destination: "192.168.1.1",
Username: "myuser",
IsDefault: true,
+ Port: 22,
}
goodConnections["bart"] = RemoteConnection{
Destination: "foobar.com",
Username: "root",
+ Port: 22,
}
var goodResult = RemoteConfig{
Connections: goodConnections,
@@ -59,6 +66,7 @@ func makeNoUserResult() *RemoteConfig {
var goodConnections = make(map[string]RemoteConnection)
goodConnections["homer"] = RemoteConnection{
Destination: "192.168.1.1",
+ Port: 22,
}
var goodResult = RemoteConfig{
Connections: goodConnections,
@@ -135,7 +143,7 @@ func TestRemoteConfig_GetDefault(t *testing.T) {
wantErr bool
}{
// A good toml should return the connection that is marked isDefault
- {"good", fields{Connections: makeGoodResult().Connections}, &RemoteConnection{"192.168.1.1", "myuser", true}, false},
+ {"good", fields{Connections: makeGoodResult().Connections}, &RemoteConnection{"192.168.1.1", "myuser", true, 22}, false},
// If nothing is marked as isDefault and there is more than one connection, error should occur
{"nodefault", fields{Connections: noDefault}, nil, true},
// if nothing is marked as isDefault but there is only one connection, the one connection is considered the default
@@ -175,9 +183,9 @@ func TestRemoteConfig_GetRemoteConnection(t *testing.T) {
wantErr bool
}{
// Good connection
- {"goodhomer", fields{Connections: makeGoodResult().Connections}, args{name: "homer"}, &RemoteConnection{"192.168.1.1", "myuser", true}, false},
+ {"goodhomer", fields{Connections: makeGoodResult().Connections}, args{name: "homer"}, &RemoteConnection{"192.168.1.1", "myuser", true, 22}, false},
// Good connection
- {"goodbart", fields{Connections: makeGoodResult().Connections}, args{name: "bart"}, &RemoteConnection{"foobar.com", "root", false}, false},
+ {"goodbart", fields{Connections: makeGoodResult().Connections}, args{name: "bart"}, &RemoteConnection{"foobar.com", "root", false, 22}, false},
// Getting an unknown connection should result in error
{"noexist", fields{Connections: makeGoodResult().Connections}, args{name: "foobar"}, nil, true},
// Getting a connection when there are none should result in an error
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index cd8b2ef61..f26eec87f 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -345,6 +345,21 @@ install_test_configs(){
remove_packaged_podman_files(){
echo "Removing packaged podman files to prevent conflicts with source build and testing."
req_env_var OS_RELEASE_ID
+
+ # If any binaries are resident they could cause unexpected pollution
+ for unit in io.podman.service io.podman.socket
+ do
+ for state in enabled active
+ do
+ if systemctl --quiet is-$state $unit
+ then
+ echo "Warning: $unit found $state prior to packaged-file removal"
+ systemctl --quiet disable $unit || true
+ systemctl --quiet stop $unit || true
+ fi
+ done
+ done
+
if [[ "$OS_RELEASE_ID" =~ "ubuntu" ]]
then
LISTING_CMD="sudo -E dpkg-query -L podman"
@@ -359,6 +374,9 @@ remove_packaged_podman_files(){
if [[ -d "$fullpath" ]] || [[ $(basename "$fullpath") == "conmon" ]] ; then continue; fi
ooe.sh sudo rm -vf "$fullpath"
done
+
+ # Be super extra sure and careful vs performant and completely safe
+ sync && echo 3 > /proc/sys/vm/drop_caches
}
systemd_banish(){
diff --git a/contrib/msi/podman.bat b/contrib/msi/podman.bat
index 091c1c4c4..e0c7e1137 100644
--- a/contrib/msi/podman.bat
+++ b/contrib/msi/podman.bat
@@ -3,6 +3,14 @@ setlocal enableextensions
title Podman
+if "%1" EQU "" (
+ goto run_help
+)
+
+if "%1" EQU "/?" (
+ goto run_help
+)
+
:: If remote-host is given on command line -- use it
setlocal enabledelayedexpansion
for %%a in (%*) do (
@@ -39,5 +47,22 @@ set /p user="Please enter the remote user name: "
:run_podman
endlocal
podman-remote-windows.exe %*
+goto end
+
+:run_help
+set run=start "Podman Help" /D "%~dp0" /B
+
+if not "%3" == "" (
+ %run% "podman-%2-%3.html
+ goto end
+)
+
+if not "%2" == "" (
+ %run% "podman-%2.html
+ goto end
+)
+
+%run% "%podman-remote.html"
+goto end
:End
diff --git a/contrib/msi/podman.wxs b/contrib/msi/podman.wxs
index 77c6e2815..ec62a93c5 100644
--- a/contrib/msi/podman.wxs
+++ b/contrib/msi/podman.wxs
@@ -5,6 +5,10 @@
<?error VERSION must be defined via command line argument?>
<?endif?>
+ <?ifndef var.ManSourceDir?>
+ <?define ManSourceDir = "bin/windows" ?>
+ <?endif?>
+
<Product Name="Podman $(var.VERSION)" Id="*" UpgradeCode="696BAB5D-CA1F-4B05-B123-320F245B8D6D" Version="$(var.VERSION)" Language="1033" Manufacturer="Red Hat Inc.">
<Package Id="*" Keywords="Installer" Description="Red Hat's Podman $(var.VERSION) Installer" Comments="Apache 2.0 License" Manufacturer="Red Hat Inc." InstallScope="perMachine" InstallerVersion="100" Compressed="yes"/>
@@ -34,6 +38,7 @@
<Feature Id="Complete" Level="1">
<ComponentRef Id="INSTALLDIR_Component"/>
<ComponentRef Id="MainExecutable"/>
+ <ComponentGroupRef Id="ManFiles"/>
</Feature>
<Icon Id="podman.ico" SourceFile="contrib/msi/podman-logo.ico"/>
diff --git a/docs/links-to-html.lua b/docs/links-to-html.lua
new file mode 100644
index 000000000..74072a9e4
--- /dev/null
+++ b/docs/links-to-html.lua
@@ -0,0 +1,5 @@
+# links-to-html.lua
+function Link(el)
+ el.target = string.gsub(el.target, "%.1.md", ".html")
+ return el
+end
diff --git a/docs/podman-remote.1.md b/docs/podman-remote.1.md
index 84042a842..04010abaf 100644
--- a/docs/podman-remote.1.md
+++ b/docs/podman-remote.1.md
@@ -35,6 +35,10 @@ Print usage statement
Log messages above specified level: debug, info, warn, error (default), fatal or panic
+**--port**=*integer*
+
+Use an alternative port for the ssh connections. The default port is 22
+
**--remote-config-path**=*path*
Alternate path for configuration file
diff --git a/docs/podman-remote.conf.5.md b/docs/podman-remote.conf.5.md
index 3e1cffb02..3c8a1a801 100644
--- a/docs/podman-remote.conf.5.md
+++ b/docs/podman-remote.conf.5.md
@@ -22,6 +22,9 @@ of the user's remote connections.
Denotes whether the connection is the default connection for the user. The default connection
is used when the user does not specify a destination or connection name to `podman`.
+**port** = int
+ Use an alternative port for the ssh connections. The default port is 22.
+
## EXAMPLE
@@ -37,6 +40,7 @@ is designated as the default connection.
[connections.host2]
destination = "192.168.122.133"
username = "fedora"
+ port = 2222
```
## FILES
diff --git a/docs/podman-remote.sh b/docs/podman-remote.sh
index db3bb6d50..2f8e76d1b 100755
--- a/docs/podman-remote.sh
+++ b/docs/podman-remote.sh
@@ -1,11 +1,100 @@
-#!/bin/sh
+#!/bin/bash -e
+# Assemble remote man pages for darwin or windows from markdown files
-BREWDIR=$1
-mkdir -p $BREWDIR
-docs() {
-[ -z $1 ] || type="-$1"
-for i in $(podman-remote $1 --help | sed -n '/^Available Commands:/,/^Flags:/p'| sed -e '1d;$d' -e '/^$/d' | awk '{print $1}'); do install podman$type-$i.1 $BREWDIR 2>/dev/null || install links/podman$type-$i.1 $BREWDIR; done
+PLATFORM=$1 ## windows or darwin
+TARGET=$2 ## where to output files
+SOURCES=${@:3} ## directories to find markdown files
+
+PODMAN=${PODMAN:-bin/podman-remote} ## location overridden for testing
+
+function usage() {
+ echo >&2 "$0 PLATFORM TARGET SOURCES..."
+ echo >&2 "PLATFORM: Is either darwin or windows."
+ echo >&2 "TARGET: Is the directory where files will be staged."
+ echo >&2 "SOURCES: Are the directories to source markdown files."
+}
+
+function fail() {
+ echo >&2 -e "$@\n"
+ usage
+ exit 1
+}
+
+case $PLATFORM in
+'darwin')
+ EXT=1
+ PUBLISHER=darwin_fn
+ ;;
+'windows')
+ EXT=1.md
+ PUBLISHER=windows_fn
+ ;;
+'-help')
+ usage
+ exit 0
+ ;;
+*) fail '"darwin" and "windows" are currently the only supported platforms.' ;;
+esac
+
+if [[ -z $TARGET ]]; then
+ fail 'TARGET directory is required'
+fi
+
+if [[ -z $SOURCES ]]; then
+ fail 'At least one SOURCE directory is required'
+fi
+
+if [[ ! -x $PODMAN ]]; then
+ fail "$PODMAN does not exist"
+fi
+
+## darwin_fn copies the markdown page or link to flattened directory
+function darwin_fn() {
+ local markdown=$1
+ local file=$(basename $markdown)
+ local dir=$(dirname $markdown)
+
+ if [[ -f $dir/links/$file ]]; then
+ markdown=$dir/links/$file
+ fi
+ install $markdown $TARGET
+}
+
+## windows_fn converts the markdown page or link to HTML
+function windows_fn() {
+ local markdown=$1
+ local file=$(basename $markdown)
+ local dir=$(dirname $markdown)
+
+ if [[ ! -f $markdown ]]; then
+ local link=$(sed -e 's?.so man1/\(.*\)?\1?' <$dir/links/${file%.md})
+ markdown=$dir/$link.md
+ fi
+ pandoc --ascii --lua-filter=$dir/links-to-html.lua -o $TARGET/${file%.$EXT}.html $markdown
+}
+
+## pub_pages finds and publishes the remote manual pages
+function pub_pages() {
+ local source=$1
+ local publisher=$2
+ for f in $(ls $source/podman-remote*$EXT); do
+ $publisher $f
+ done
+
+ for c in "container" "image" "pod" "volume" ""; do
+ local cmd=${c:+-$c}
+ for s in $($PODMAN $c --help | sed -n '/^Available Commands:/,/^Flags:/p' | sed -e '1d;$d' -e '/^$/d' | awk '{print $1}'); do
+ $publisher $source/podman$cmd-$s.$EXT
+ done
+ done
}
-docs
-for cmd in 'container image pod volume'; do docs $cmd; done
+## walk the SOURCES for markdown sources
+mkdir -p $TARGET
+for s in $SOURCES; do
+ if [[ -d $s ]]; then
+ pub_pages $s $PUBLISHER
+ else
+ echo >&2 "Warning: $s does not exist"
+ fi
+done
diff --git a/docs/tutorials/README.md b/docs/tutorials/README.md
index 925cfb970..c340d683f 100644
--- a/docs/tutorials/README.md
+++ b/docs/tutorials/README.md
@@ -8,6 +8,14 @@
Learn how to setup Podman and perform some basic commands with the utility.
-**[Basic Setup and Use of Podman in a Rootless environment.](https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md).
+**[Basic Setup and Use of Podman in a Rootless environment.](https://github.com/containers/libpod/blob/master/docs/tutorials/rootless_tutorial.md).**
The steps required to setup rootless Podman are enumerated.
+
+**[Setup on OS X](https://github.com/containers/libpod/blob/master/doc/tutorials/mac_client.md)**
+
+Special setup for running the Podman remote client on a Mac and connecting to Podman running on a Linux VM are documented
+
+**[Remote Client](https://github.com/containers/libpod/blob/master/doc/tutorials/remote_client.md)**
+
+A brief how-to on using the Podman remote-client.
diff --git a/mac_client.md b/docs/tutorials/mac_client.md
index bf08e8cc1..bf08e8cc1 100644
--- a/mac_client.md
+++ b/docs/tutorials/mac_client.md
diff --git a/docs/tutorials/podman_tutorial.md b/docs/tutorials/podman_tutorial.md
index d2f8e08fa..559d25d6a 100644
--- a/docs/tutorials/podman_tutorial.md
+++ b/docs/tutorials/podman_tutorial.md
@@ -5,6 +5,9 @@ Podman is a utility provided as part of the libpod library. It can be used to c
containers. The following tutorial will teach you how to set up Podman and perform some basic
commands with Podman.
+If you are running on a Mac, you should instead follow the [Mac tutorial](https://github.com/containers/libpod/blob/master/mac_client.md)
+to set up the remote Podman client.
+
**NOTE**: the code samples are intended to be run as a non-root user, and use `sudo` where
root escalation is required.
diff --git a/remote_client.md b/docs/tutorials/remote_client.md
index be5c918c8..197ff3d26 100644
--- a/remote_client.md
+++ b/docs/tutorials/remote_client.md
@@ -19,8 +19,8 @@ system as a user with privileges to the varlink socket (more on this later).
## Building the remote client
At this time, the remote-client is not being packaged for any distribution. It must be built from
-source. To set up your build environment, see [Installation notes](install.md) and follow the
-section [Building from scratch](install.md#building-from-scratch). Once you can successfully
+source. To set up your build environment, see [Installation notes](https://github.com/containers/libpod/blob/master/install.md) and follow the
+section [Building from scratch](https://github.com/containers/libpod/blob/master/install.md#building-from-scratch). Once you can successfully
build the regular Podman binary, you can now build the remote-client.
```
$ make podman-remote
diff --git a/go.mod b/go.mod
index 328ebad0c..117f85b3c 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
github.com/containers/conmon v0.3.0 // indirect
github.com/containers/image v3.0.2+incompatible
github.com/containers/psgo v1.3.1
- github.com/containers/storage v1.13.2
+ github.com/containers/storage v1.13.3
github.com/coreos/bbolt v1.3.3 // indirect
github.com/coreos/etcd v3.3.13+incompatible // indirect
github.com/coreos/go-iptables v0.4.2 // indirect
diff --git a/go.sum b/go.sum
index fbf0e667d..63c2ddd30 100644
--- a/go.sum
+++ b/go.sum
@@ -108,6 +108,8 @@ github.com/containers/storage v1.13.1 h1:rjVirLS9fCGkUFlLDZEoGDDUugtIf46DufWvJu0
github.com/containers/storage v1.13.1/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.2 h1:UXZ0Ckmk6+6+4vj2M2ywruVtH97pnRoAhTG8ctd+yQI=
github.com/containers/storage v1.13.2/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
+github.com/containers/storage v1.13.3 h1:9EzTXZXG/8SGD9MnkSCe/jLq3QldcE1QlgW7vePEsjw=
+github.com/containers/storage v1.13.3/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 80b58654e..e2b9667be 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -247,7 +247,7 @@ type RuntimeConfig struct {
// EventsLogger determines where events should be logged
EventsLogger string `toml:"events_logger"`
// EventsLogFilePath is where the events log is stored.
- EventsLogFilePath string `toml:"-events_logfile_path"`
+ EventsLogFilePath string `toml:"events_logfile_path"`
//DetachKeys is the sequence of keys used to detach a container
DetachKeys string `toml:"detach_keys"`
diff --git a/pkg/adapter/client.go b/pkg/adapter/client.go
index da6ff5fd0..1805c758d 100644
--- a/pkg/adapter/client.go
+++ b/pkg/adapter/client.go
@@ -35,7 +35,7 @@ func (r RemoteRuntime) RemoteEndpoint() (remoteEndpoint *Endpoint, err error) {
if len(r.cmd.RemoteUserName) < 1 {
return nil, errors.New("you must provide a username when providing a remote host name")
}
- rc := remoteclientconfig.RemoteConnection{r.cmd.RemoteHost, r.cmd.RemoteUserName, false}
+ rc := remoteclientconfig.RemoteConnection{r.cmd.RemoteHost, r.cmd.RemoteUserName, false, r.cmd.Port}
remoteEndpoint, err = newBridgeConnection("", &rc, r.cmd.LogLevel)
// if the user has a config file with connections in it
} else if len(remoteConfigConnections.Connections) > 0 {
diff --git a/pkg/adapter/client_unix.go b/pkg/adapter/client_unix.go
index 4781acd06..a7bc7c1c0 100644
--- a/pkg/adapter/client_unix.go
+++ b/pkg/adapter/client_unix.go
@@ -10,7 +10,11 @@ import (
)
func formatDefaultBridge(remoteConn *remoteclientconfig.RemoteConnection, logLevel string) string {
+ port := remoteConn.Port
+ if port == 0 {
+ port = 22
+ }
return fmt.Sprintf(
- `ssh -T %s@%s -- /usr/bin/varlink -A \'/usr/bin/podman --log-level=%s varlink \\\$VARLINK_ADDRESS\' bridge`,
- remoteConn.Username, remoteConn.Destination, logLevel)
+ `ssh -p %d -T %s@%s -- /usr/bin/varlink -A \'/usr/bin/podman --log-level=%s varlink \\\$VARLINK_ADDRESS\' bridge`,
+ port, remoteConn.Username, remoteConn.Destination, logLevel)
}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index cc091dcee..3d59d70d8 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -220,6 +220,7 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount,
// volumes, and return a list of them.
// Conflicts are resolved simply - the last container specified wins.
// Container names may be suffixed by mount options after a colon.
+// TODO: We should clean these paths if possible
func (config *CreateConfig) getVolumesFrom(runtime *libpod.Runtime) (map[string]spec.Mount, map[string]*libpod.ContainerNamedVolume, error) {
// Both of these are maps of mount destination to mount type.
// We ensure that each destination is only mounted to once in this way.
@@ -465,7 +466,7 @@ func getBindMount(args []string) (spec.Mount, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
}
- newMount.Destination = kv[1]
+ newMount.Destination = filepath.Clean(kv[1])
setDest = true
case "relabel":
if setRelabel {
@@ -559,7 +560,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
}
- newMount.Destination = kv[1]
+ newMount.Destination = filepath.Clean(kv[1])
setDest = true
default:
return newMount, errors.Wrapf(util.ErrBadMntOption, kv[0])
@@ -623,7 +624,7 @@ func getNamedVolume(args []string) (*libpod.ContainerNamedVolume, error) {
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return nil, err
}
- newVolume.Dest = kv[1]
+ newVolume.Dest = filepath.Clean(kv[1])
setDest = true
default:
return nil, errors.Wrapf(util.ErrBadMntOption, kv[0])
@@ -678,10 +679,12 @@ func (config *CreateConfig) getVolumeMounts() (map[string]spec.Mount, map[string
return nil, nil, err
}
+ cleanDest := filepath.Clean(dest)
+
if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") {
// This is not a named volume
newMount := spec.Mount{
- Destination: dest,
+ Destination: cleanDest,
Type: string(TypeBind),
Source: src,
Options: options,
@@ -694,7 +697,7 @@ func (config *CreateConfig) getVolumeMounts() (map[string]spec.Mount, map[string
// This is a named volume
newNamedVol := new(libpod.ContainerNamedVolume)
newNamedVol.Name = src
- newNamedVol.Dest = dest
+ newNamedVol.Dest = cleanDest
newNamedVol.Options = options
if _, ok := volumes[newNamedVol.Dest]; ok {
@@ -719,10 +722,11 @@ func (config *CreateConfig) getImageVolumes() (map[string]spec.Mount, map[string
}
for vol := range config.BuiltinImgVolumes {
+ cleanDest := filepath.Clean(vol)
if config.ImageVolumeType == "tmpfs" {
// Tmpfs image volumes are handled as mounts
mount := spec.Mount{
- Destination: vol,
+ Destination: cleanDest,
Source: TypeTmpfs,
Type: TypeTmpfs,
Options: []string{"rprivate", "rw", "nodev"},
@@ -732,7 +736,7 @@ func (config *CreateConfig) getImageVolumes() (map[string]spec.Mount, map[string
namedVolume := new(libpod.ContainerNamedVolume)
namedVolume.Name = stringid.GenerateNonCryptoID()
namedVolume.Options = []string{"rprivate", "rw", "nodev"}
- namedVolume.Dest = vol
+ namedVolume.Dest = cleanDest
volumes[vol] = namedVolume
}
}
@@ -760,7 +764,7 @@ func (config *CreateConfig) getTmpfsMounts() (map[string]spec.Mount, error) {
}
mount := spec.Mount{
- Destination: destPath,
+ Destination: filepath.Clean(destPath),
Type: string(TypeTmpfs),
Options: options,
Source: string(TypeTmpfs),
diff --git a/rootless.md b/rootless.md
index 960430d54..53463dccc 100644
--- a/rootless.md
+++ b/rootless.md
@@ -14,6 +14,9 @@ can easily fail
* No cgroup V1 Support
* cgroup V1 does not safely support cgroup delegation.
* However, cgroup V2 provides cgroup delegation and is available on Fedora starting with version 29 and other Linux distributions.
+* Some systemd's unit configuration options do not work in the rootless container
+ * systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit).
+ * Use of certain options will cause service startup failures (e.g. PrivateNetwork).
* Can not share container images with CRI-O or other users
* Difficult to use additional stores for sharing content
* Does not work on NFS or parallel filesystem homedirs (e.g. [GPFS](https://www.ibm.com/support/knowledgecenter/en/SSFKCN/gpfs_welcome.html))
diff --git a/vendor/github.com/containers/storage/Makefile b/vendor/github.com/containers/storage/Makefile
index bb1de007b..fa0fddaeb 100644
--- a/vendor/github.com/containers/storage/Makefile
+++ b/vendor/github.com/containers/storage/Makefile
@@ -1,4 +1,5 @@
export GO111MODULE=off
+export GOPROXY=https://proxy.golang.org
.PHONY: \
all \
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 065f9ec4c..01b756823 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.13.3-dev
+1.13.3
diff --git a/vendor/github.com/containers/storage/images.go b/vendor/github.com/containers/storage/images.go
index b1df9b765..5d6a2e48d 100644
--- a/vendor/github.com/containers/storage/images.go
+++ b/vendor/github.com/containers/storage/images.go
@@ -372,7 +372,7 @@ func (r *imageStore) ClearFlag(id string, flag string) error {
}
image, ok := r.lookup(id)
if !ok {
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
delete(image.Flags, flag)
return r.Save()
@@ -384,7 +384,7 @@ func (r *imageStore) SetFlag(id string, flag string, value interface{}) error {
}
image, ok := r.lookup(id)
if !ok {
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
if image.Flags == nil {
image.Flags = make(map[string]interface{})
@@ -456,14 +456,14 @@ func (r *imageStore) addMappedTopLayer(id, layer string) error {
image.MappedTopLayers = append(image.MappedTopLayers, layer)
return r.Save()
}
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) Metadata(id string) (string, error) {
if image, ok := r.lookup(id); ok {
return image.Metadata, nil
}
- return "", ErrImageUnknown
+ return "", errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) SetMetadata(id, metadata string) error {
@@ -474,7 +474,7 @@ func (r *imageStore) SetMetadata(id, metadata string) error {
image.Metadata = metadata
return r.Save()
}
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) removeName(image *Image, name string) {
@@ -499,7 +499,7 @@ func (r *imageStore) SetNames(id string, names []string) error {
image.Names = names
return r.Save()
}
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) Delete(id string) error {
@@ -508,7 +508,7 @@ func (r *imageStore) Delete(id string) error {
}
image, ok := r.lookup(id)
if !ok {
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
id = image.ID
toDeleteIndex := -1
@@ -551,14 +551,14 @@ func (r *imageStore) Get(id string) (*Image, error) {
if image, ok := r.lookup(id); ok {
return copyImage(image), nil
}
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) Lookup(name string) (id string, err error) {
if image, ok := r.lookup(name); ok {
return image.ID, nil
}
- return "", ErrImageUnknown
+ return "", errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (r *imageStore) Exists(id string) bool {
@@ -570,7 +570,7 @@ func (r *imageStore) ByDigest(d digest.Digest) ([]*Image, error) {
if images, ok := r.bydigest[d]; ok {
return copyImageSlice(images), nil
}
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with digest %q", d)
}
func (r *imageStore) BigData(id, key string) ([]byte, error) {
@@ -579,7 +579,7 @@ func (r *imageStore) BigData(id, key string) ([]byte, error) {
}
image, ok := r.lookup(id)
if !ok {
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
return ioutil.ReadFile(r.datapath(image.ID, key))
}
@@ -590,7 +590,7 @@ func (r *imageStore) BigDataSize(id, key string) (int64, error) {
}
image, ok := r.lookup(id)
if !ok {
- return -1, ErrImageUnknown
+ return -1, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
if image.BigDataSizes == nil {
image.BigDataSizes = make(map[string]int64)
@@ -610,7 +610,7 @@ func (r *imageStore) BigDataDigest(id, key string) (digest.Digest, error) {
}
image, ok := r.lookup(id)
if !ok {
- return "", ErrImageUnknown
+ return "", errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
if image.BigDataDigests == nil {
image.BigDataDigests = make(map[string]digest.Digest)
@@ -624,7 +624,7 @@ func (r *imageStore) BigDataDigest(id, key string) (digest.Digest, error) {
func (r *imageStore) BigDataNames(id string) ([]string, error) {
image, ok := r.lookup(id)
if !ok {
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
return copyStringSlice(image.BigDataNames), nil
}
@@ -649,7 +649,7 @@ func (r *imageStore) SetBigData(id, key string, data []byte, digestManifest func
}
image, ok := r.lookup(id)
if !ok {
- return ErrImageUnknown
+ return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
err := os.MkdirAll(r.datadir(image.ID), 0700)
if err != nil {
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index d746ba061..ac905b0b4 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -363,7 +363,7 @@ func (r *layerStore) Load() error {
}
if cleanup, ok := layer.Flags[incompleteFlag]; ok {
if b, ok := cleanup.(bool); ok && b {
- err = r.Delete(layer.ID)
+ err = r.deleteInternal(layer.ID)
if err != nil {
break
}
@@ -372,7 +372,7 @@ func (r *layerStore) Load() error {
}
}
if shouldSave {
- return r.Save()
+ return r.saveLayers()
}
}
return err
@@ -416,6 +416,16 @@ func (r *layerStore) loadMounts() error {
}
func (r *layerStore) Save() error {
+ r.mountsLockfile.Lock()
+ defer r.mountsLockfile.Unlock()
+ defer r.mountsLockfile.Touch()
+ if err := r.saveLayers(); err != nil {
+ return err
+ }
+ return r.saveMounts()
+}
+
+func (r *layerStore) saveLayers() error {
if !r.IsReadWrite() {
return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to modify the layer store at %q", r.layerspath())
}
@@ -431,13 +441,7 @@ func (r *layerStore) Save() error {
return err
}
defer r.Touch()
- if err := ioutils.AtomicWriteFile(rpath, jldata, 0600); err != nil {
- return err
- }
- r.mountsLockfile.Lock()
- defer r.mountsLockfile.Unlock()
- defer r.mountsLockfile.Touch()
- return r.saveMounts()
+ return ioutils.AtomicWriteFile(rpath, jldata, 0600)
}
func (r *layerStore) saveMounts() error {
@@ -954,7 +958,7 @@ func (r *layerStore) tspath(id string) string {
return filepath.Join(r.layerdir, id+tarSplitSuffix)
}
-func (r *layerStore) Delete(id string) error {
+func (r *layerStore) deleteInternal(id string) error {
if !r.IsReadWrite() {
return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to delete layers at %q", r.layerspath())
}
@@ -963,23 +967,7 @@ func (r *layerStore) Delete(id string) error {
return ErrLayerUnknown
}
id = layer.ID
- // The layer may already have been explicitly unmounted, but if not, we
- // should try to clean that up before we start deleting anything at the
- // driver level.
- mountCount, err := r.Mounted(id)
- if err != nil {
- return errors.Wrapf(err, "error checking if layer %q is still mounted", id)
- }
- for mountCount > 0 {
- if _, err := r.Unmount(id, false); err != nil {
- return err
- }
- mountCount, err = r.Mounted(id)
- if err != nil {
- return errors.Wrapf(err, "error checking if layer %q is still mounted", id)
- }
- }
- err = r.driver.Remove(id)
+ err := r.driver.Remove(id)
if err == nil {
os.Remove(r.tspath(id))
delete(r.byid, id)
@@ -1015,11 +1003,36 @@ func (r *layerStore) Delete(id string) error {
label.ReleaseLabel(mountLabel)
}
}
- if err = r.Save(); err != nil {
+ }
+ return err
+}
+
+func (r *layerStore) Delete(id string) error {
+ layer, ok := r.lookup(id)
+ if !ok {
+ return ErrLayerUnknown
+ }
+ id = layer.ID
+ // The layer may already have been explicitly unmounted, but if not, we
+ // should try to clean that up before we start deleting anything at the
+ // driver level.
+ mountCount, err := r.Mounted(id)
+ if err != nil {
+ return errors.Wrapf(err, "error checking if layer %q is still mounted", id)
+ }
+ for mountCount > 0 {
+ if _, err := r.Unmount(id, false); err != nil {
return err
}
+ mountCount, err = r.Mounted(id)
+ if err != nil {
+ return errors.Wrapf(err, "error checking if layer %q is still mounted", id)
+ }
}
- return err
+ if err := r.deleteInternal(id); err != nil {
+ return err
+ }
+ return r.Save()
}
func (r *layerStore) Lookup(name string) (id string, err error) {
diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go
index 74275482b..dd3405212 100644
--- a/vendor/github.com/containers/storage/store.go
+++ b/vendor/github.com/containers/storage/store.go
@@ -1202,7 +1202,7 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
}
}
if cimage == nil {
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
imageID = cimage.ID
@@ -1437,7 +1437,7 @@ func (s *store) ListImageBigData(id string) ([]string, error) {
return bigDataNames, err
}
}
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (s *store) ImageBigDataSize(id, key string) (int64, error) {
@@ -1516,7 +1516,7 @@ func (s *store) ImageBigData(id, key string) ([]byte, error) {
return data, nil
}
}
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (s *store) SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error {
@@ -2891,7 +2891,7 @@ func (s *store) Image(id string) (*Image, error) {
return image, nil
}
}
- return nil, ErrImageUnknown
+ return nil, errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id)
}
func (s *store) ImagesByTopLayer(id string) ([]*Image, error) {
@@ -2953,7 +2953,7 @@ func (s *store) ImagesByDigest(d digest.Digest) ([]*Image, error) {
}
}
imageList, err := store.ByDigest(d)
- if err != nil && err != ErrImageUnknown {
+ if err != nil && errors.Cause(err) != ErrImageUnknown {
return nil, err
}
images = append(images, imageList...)
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1de9fede0..3a27eea12 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -109,7 +109,7 @@ github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
github.com/containers/psgo/internal/host
-# github.com/containers/storage v1.13.2
+# github.com/containers/storage v1.13.3
github.com/containers/storage
github.com/containers/storage/pkg/archive
github.com/containers/storage/pkg/chrootarchive