Преглед изворни кода

version: add RootlessKit, slirp4netns, and VPNKit version

```console
$ docker --context=rootless version
...
Server:
...
 rootlesskit:
  Version:          0.14.2
  ApiVersion:       1.1.1
  NetworkDriver:    slirp4netns
  PortDriver:       builtin
  StateDir:         /tmp/rootlesskit245426514
 slirp4netns:
  Version:          1.1.9
  GitCommit:        4e37ea557562e0d7a64dc636eff156f64927335e
```

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Akihiro Suda пре 4 година
родитељ
комит
de6732a403

+ 57 - 0
daemon/info_unix.go

@@ -13,6 +13,7 @@ import (
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/pkg/sysinfo"
+	"github.com/docker/docker/rootless"
 	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 )
@@ -208,6 +209,62 @@ func (daemon *Daemon) fillPlatformVersion(v *types.Version) {
 	} else {
 		logrus.Warnf("failed to retrieve %s version: %s", defaultInitBinary, err)
 	}
+
+	daemon.fillRootlessVersion(v)
+}
+
+func (daemon *Daemon) fillRootlessVersion(v *types.Version) {
+	if !rootless.RunningWithRootlessKit() {
+		return
+	}
+	rlc, err := rootless.GetRootlessKitClient()
+	if err != nil {
+		logrus.Warnf("failed to create RootlessKit client: %v", err)
+		return
+	}
+	rlInfo, err := rlc.Info(context.TODO())
+	if err != nil {
+		logrus.Warnf("failed to retrieve RootlessKit version: %v", err)
+		return
+	}
+	v.Components = append(v.Components, types.ComponentVersion{
+		Name:    "rootlesskit",
+		Version: rlInfo.Version,
+		Details: map[string]string{
+			"ApiVersion":    rlInfo.APIVersion,
+			"StateDir":      rlInfo.StateDir,
+			"NetworkDriver": rlInfo.NetworkDriver.Driver,
+			"PortDriver":    rlInfo.PortDriver.Driver,
+		},
+	})
+
+	switch rlInfo.NetworkDriver.Driver {
+	case "slirp4netns":
+		if rv, err := exec.Command("slirp4netns", "--version").Output(); err == nil {
+			if _, ver, commit, err := parseRuntimeVersion(string(rv)); err != nil {
+				logrus.Warnf("failed to parse slirp4netns version: %v", err)
+			} else {
+				v.Components = append(v.Components, types.ComponentVersion{
+					Name:    "slirp4netns",
+					Version: ver,
+					Details: map[string]string{
+						"GitCommit": commit,
+					},
+				})
+			}
+		} else {
+			logrus.Warnf("failed to retrieve slirp4netns version: %v", err)
+		}
+	case "vpnkit":
+		if rv, err := exec.Command("vpnkit", "--version").Output(); err == nil {
+			v.Components = append(v.Components, types.ComponentVersion{
+				Name:    "vpnkit",
+				Version: strings.TrimSpace(string(rv)),
+			})
+		} else {
+			logrus.Warnf("failed to retrieve vpnkit version: %v", err)
+		}
+	}
 }
 
 func fillDriverWarnings(v *types.Info) {

+ 3 - 1
hack/dockerfile/install/rootlesskit.installer

@@ -1,6 +1,8 @@
 #!/bin/sh
 
-: "${ROOTLESSKIT_VERSION:=v0.14.6}"
+# When updating, also update rootlesskit commit in vendor.conf accordingly
+# v0.14.6
+: "${ROOTLESSKIT_VERSION:=b25a0bad15d664c4ee8885ba622569425e918a68}"
 
 install_rootlesskit() {
 	case "$1" in

+ 14 - 0
rootless/rootless.go

@@ -2,7 +2,11 @@ package rootless // import "github.com/docker/docker/rootless"
 
 import (
 	"os"
+	"path/filepath"
 	"sync"
+
+	"github.com/pkg/errors"
+	"github.com/rootless-containers/rootlesskit/pkg/api/client"
 )
 
 const (
@@ -23,3 +27,13 @@ func RunningWithRootlessKit() bool {
 	})
 	return runningWithRootlessKit
 }
+
+// GetRootlessKitClient returns RootlessKit client
+func GetRootlessKitClient() (client.Client, error) {
+	stateDir := os.Getenv("ROOTLESSKIT_STATE_DIR")
+	if stateDir == "" {
+		return nil, errors.New("environment variable `ROOTLESSKIT_STATE_DIR` is not set")
+	}
+	apiSock := filepath.Join(stateDir, "api.sock")
+	return client.New(apiSock)
+}

+ 2 - 1
vendor.mod

@@ -68,6 +68,7 @@ require (
 	github.com/pelletier/go-toml v1.9.4
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.11.0
+	github.com/rootless-containers/rootlesskit v0.14.6
 	github.com/sirupsen/logrus v1.8.1
 	github.com/spf13/cobra v1.1.3
 	github.com/spf13/pflag v1.0.5
@@ -101,7 +102,7 @@ require (
 	github.com/cyphar/filepath-securejoin v0.2.3 // indirect
 	github.com/dustin/go-humanize v1.0.0 // indirect
 	github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e // indirect
-	github.com/gofrs/flock v0.7.3 // indirect
+	github.com/gofrs/flock v0.8.1 // indirect
 	github.com/gogo/googleapis v1.4.0 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect

+ 35 - 1
vendor.sum

@@ -387,6 +387,7 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e h1:P10tZmVD2XclAaT9l7OduMH1OLFzTa1wUuUqHZnEdI0=
@@ -447,8 +448,9 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
 github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofrs/flock v0.7.3 h1:I0EKY9l8HZCXTMYC4F80vwT6KNypV9uYKP3Alm/hjmQ=
 github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
+github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/gogo/googleapis v1.3.2 h1:kX1es4djPJrsDhY7aZKJy7aZasdcB5oSOEphMjSB53c=
 github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
@@ -605,6 +607,7 @@ github.com/hashicorp/serf v0.7.1-0.20160317193612-598c54895cc5/go.mod h1:h/Ru6tm
 github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c h1:nQcv325vxv2fFHJsOt53eSRf1eINt6vOdYUFfXs4rgk=
 github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@@ -615,6 +618,7 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
 github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
 github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ=
 github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee h1:PAXLXk1heNZ5yokbMBpVLZQxo43wCZxRwl00mX+dd44=
 github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
@@ -630,6 +634,10 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
 github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
+github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
+github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
+github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -683,6 +691,13 @@ github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
+github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
+github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
+github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
+github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
+github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
+github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
+github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
 github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
 github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM=
 github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
@@ -724,6 +739,7 @@ github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf/go.mod h1:FBS0z0QWA44HXy
 github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A=
 github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
 github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
+github.com/moby/vpnkit v0.5.0/go.mod h1:KyjUrL9cb6ZSNNAUwZfqRjhwwgJ3BJN+kXh0t43WTUQ=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
@@ -843,8 +859,11 @@ github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rootless-containers/rootlesskit v0.14.6 h1:5kvJK6eeUtWZz1mYegu5S7DHOahq93K+jbc/mz+hbFQ=
+github.com/rootless-containers/rootlesskit v0.14.6/go.mod h1:uHPTRoPO6ZdOl2q99ZKOK14PJAwepfNKh6hV57AOZYQ=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
 github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
@@ -871,6 +890,7 @@ github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:s
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
+github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
@@ -926,6 +946,7 @@ github.com/tonistiigi/go-immutable-radix v0.0.0-20170803185627-826af9ccf0fe/go.m
 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
+github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
 github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
 github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
@@ -934,6 +955,7 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
 github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
 github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
 github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
@@ -1083,6 +1105,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
@@ -1095,6 +1118,7 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1111,6 +1135,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -1126,6 +1151,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
 golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -1166,13 +1192,16 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1187,6 +1216,7 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1224,6 +1254,8 @@ golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1247,6 +1279,7 @@ golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1257,6 +1290,7 @@ golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=

+ 2 - 2
vendor/github.com/gofrs/flock/.travis.yml

@@ -1,7 +1,7 @@
 language: go
 go:
-  - 1.10.x
-  - 1.11.x
+  - 1.14.x
+  - 1.15.x
 script: go test -v -check.vv -race ./...
 sudo: false
 notifications:

+ 1 - 1
vendor/github.com/gofrs/flock/appveyor.yml

@@ -7,7 +7,7 @@ clone_folder: 'c:\gopath\src\github.com\gofrs\flock'
 
 environment:
   GOPATH: 'c:\gopath'
-  GOVERSION: '1.11'
+  GOVERSION: '1.15'
 
 init:
   - git config --global core.autocrlf input

+ 10 - 1
vendor/github.com/gofrs/flock/flock.go

@@ -19,6 +19,7 @@ package flock
 import (
 	"context"
 	"os"
+	"runtime"
 	"sync"
 	"time"
 )
@@ -116,7 +117,15 @@ func tryCtx(ctx context.Context, fn func() (bool, error), retryDelay time.Durati
 func (f *Flock) setFh() error {
 	// open a new os.File instance
 	// create it if it doesn't exist, and open the file read-only.
-	fh, err := os.OpenFile(f.path, os.O_CREATE|os.O_RDONLY, os.FileMode(0600))
+	flags := os.O_CREATE
+	if runtime.GOOS == "aix" {
+		// AIX cannot preform write-lock (ie exclusive) on a
+		// read-only file.
+		flags |= os.O_RDWR
+	} else {
+		flags |= os.O_RDONLY
+	}
+	fh, err := os.OpenFile(f.path, flags, os.FileMode(0600))
 	if err != nil {
 		return err
 	}

+ 281 - 0
vendor/github.com/gofrs/flock/flock_aix.go

@@ -0,0 +1,281 @@
+// Copyright 2019 Tim Heckman. All rights reserved. Use of this source code is
+// governed by the BSD 3-Clause license that can be found in the LICENSE file.
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code implements the filelock API using POSIX 'fcntl' locks, which attach
+// to an (inode, process) pair rather than a file descriptor. To avoid unlocking
+// files prematurely when the same file is opened through different descriptors,
+// we allow only one read-lock at a time.
+//
+// This code is adapted from the Go package:
+// cmd/go/internal/lockedfile/internal/filelock
+
+//+build aix
+
+package flock
+
+import (
+	"errors"
+	"io"
+	"os"
+	"sync"
+	"syscall"
+
+	"golang.org/x/sys/unix"
+)
+
+type lockType int16
+
+const (
+	readLock  lockType = unix.F_RDLCK
+	writeLock lockType = unix.F_WRLCK
+)
+
+type cmdType int
+
+const (
+	tryLock  cmdType = unix.F_SETLK
+	waitLock cmdType = unix.F_SETLKW
+)
+
+type inode = uint64
+
+type inodeLock struct {
+	owner *Flock
+	queue []<-chan *Flock
+}
+
+var (
+	mu     sync.Mutex
+	inodes = map[*Flock]inode{}
+	locks  = map[inode]inodeLock{}
+)
+
+// Lock is a blocking call to try and take an exclusive file lock. It will wait
+// until it is able to obtain the exclusive file lock. It's recommended that
+// TryLock() be used over this function. This function may block the ability to
+// query the current Locked() or RLocked() status due to a RW-mutex lock.
+//
+// If we are already exclusive-locked, this function short-circuits and returns
+// immediately assuming it can take the mutex lock.
+//
+// If the *Flock has a shared lock (RLock), this may transparently replace the
+// shared lock with an exclusive lock on some UNIX-like operating systems. Be
+// careful when using exclusive locks in conjunction with shared locks
+// (RLock()), because calling Unlock() may accidentally release the exclusive
+// lock that was once a shared lock.
+func (f *Flock) Lock() error {
+	return f.lock(&f.l, writeLock)
+}
+
+// RLock is a blocking call to try and take a shared file lock. It will wait
+// until it is able to obtain the shared file lock. It's recommended that
+// TryRLock() be used over this function. This function may block the ability to
+// query the current Locked() or RLocked() status due to a RW-mutex lock.
+//
+// If we are already shared-locked, this function short-circuits and returns
+// immediately assuming it can take the mutex lock.
+func (f *Flock) RLock() error {
+	return f.lock(&f.r, readLock)
+}
+
+func (f *Flock) lock(locked *bool, flag lockType) error {
+	f.m.Lock()
+	defer f.m.Unlock()
+
+	if *locked {
+		return nil
+	}
+
+	if f.fh == nil {
+		if err := f.setFh(); err != nil {
+			return err
+		}
+		defer f.ensureFhState()
+	}
+
+	if _, err := f.doLock(waitLock, flag, true); err != nil {
+		return err
+	}
+
+	*locked = true
+	return nil
+}
+
+func (f *Flock) doLock(cmd cmdType, lt lockType, blocking bool) (bool, error) {
+	// POSIX locks apply per inode and process, and the lock for an inode is
+	// released when *any* descriptor for that inode is closed. So we need to
+	// synchronize access to each inode internally, and must serialize lock and
+	// unlock calls that refer to the same inode through different descriptors.
+	fi, err := f.fh.Stat()
+	if err != nil {
+		return false, err
+	}
+	ino := inode(fi.Sys().(*syscall.Stat_t).Ino)
+
+	mu.Lock()
+	if i, dup := inodes[f]; dup && i != ino {
+		mu.Unlock()
+		return false, &os.PathError{
+			Path: f.Path(),
+			Err:  errors.New("inode for file changed since last Lock or RLock"),
+		}
+	}
+
+	inodes[f] = ino
+
+	var wait chan *Flock
+	l := locks[ino]
+	if l.owner == f {
+		// This file already owns the lock, but the call may change its lock type.
+	} else if l.owner == nil {
+		// No owner: it's ours now.
+		l.owner = f
+	} else if !blocking {
+		// Already owned: cannot take the lock.
+		mu.Unlock()
+		return false, nil
+	} else {
+		// Already owned: add a channel to wait on.
+		wait = make(chan *Flock)
+		l.queue = append(l.queue, wait)
+	}
+	locks[ino] = l
+	mu.Unlock()
+
+	if wait != nil {
+		wait <- f
+	}
+
+	err = setlkw(f.fh.Fd(), cmd, lt)
+
+	if err != nil {
+		f.doUnlock()
+		if cmd == tryLock && err == unix.EACCES {
+			return false, nil
+		}
+		return false, err
+	}
+
+	return true, nil
+}
+
+func (f *Flock) Unlock() error {
+	f.m.Lock()
+	defer f.m.Unlock()
+
+	// if we aren't locked or if the lockfile instance is nil
+	// just return a nil error because we are unlocked
+	if (!f.l && !f.r) || f.fh == nil {
+		return nil
+	}
+
+	if err := f.doUnlock(); err != nil {
+		return err
+	}
+
+	f.fh.Close()
+
+	f.l = false
+	f.r = false
+	f.fh = nil
+
+	return nil
+}
+
+func (f *Flock) doUnlock() (err error) {
+	var owner *Flock
+	mu.Lock()
+	ino, ok := inodes[f]
+	if ok {
+		owner = locks[ino].owner
+	}
+	mu.Unlock()
+
+	if owner == f {
+		err = setlkw(f.fh.Fd(), waitLock, unix.F_UNLCK)
+	}
+
+	mu.Lock()
+	l := locks[ino]
+	if len(l.queue) == 0 {
+		// No waiters: remove the map entry.
+		delete(locks, ino)
+	} else {
+		// The first waiter is sending us their file now.
+		// Receive it and update the queue.
+		l.owner = <-l.queue[0]
+		l.queue = l.queue[1:]
+		locks[ino] = l
+	}
+	delete(inodes, f)
+	mu.Unlock()
+
+	return err
+}
+
+// TryLock is the preferred function for taking an exclusive file lock. This
+// function takes an RW-mutex lock before it tries to lock the file, so there is
+// the possibility that this function may block for a short time if another
+// goroutine is trying to take any action.
+//
+// The actual file lock is non-blocking. If we are unable to get the exclusive
+// file lock, the function will return false instead of waiting for the lock. If
+// we get the lock, we also set the *Flock instance as being exclusive-locked.
+func (f *Flock) TryLock() (bool, error) {
+	return f.try(&f.l, writeLock)
+}
+
+// TryRLock is the preferred function for taking a shared file lock. This
+// function takes an RW-mutex lock before it tries to lock the file, so there is
+// the possibility that this function may block for a short time if another
+// goroutine is trying to take any action.
+//
+// The actual file lock is non-blocking. If we are unable to get the shared file
+// lock, the function will return false instead of waiting for the lock. If we
+// get the lock, we also set the *Flock instance as being share-locked.
+func (f *Flock) TryRLock() (bool, error) {
+	return f.try(&f.r, readLock)
+}
+
+func (f *Flock) try(locked *bool, flag lockType) (bool, error) {
+	f.m.Lock()
+	defer f.m.Unlock()
+
+	if *locked {
+		return true, nil
+	}
+
+	if f.fh == nil {
+		if err := f.setFh(); err != nil {
+			return false, err
+		}
+		defer f.ensureFhState()
+	}
+
+	haslock, err := f.doLock(tryLock, flag, false)
+	if err != nil {
+		return false, err
+	}
+
+	*locked = haslock
+	return haslock, nil
+}
+
+// setlkw calls FcntlFlock with cmd for the entire file indicated by fd.
+func setlkw(fd uintptr, cmd cmdType, lt lockType) error {
+	for {
+		err := unix.FcntlFlock(fd, int(cmd), &unix.Flock_t{
+			Type:   int16(lt),
+			Whence: io.SeekStart,
+			Start:  0,
+			Len:    0, // All bytes.
+		})
+		if err != unix.EINTR {
+			return err
+		}
+	}
+}

+ 1 - 1
vendor/github.com/gofrs/flock/flock_unix.go

@@ -2,7 +2,7 @@
 // Use of this source code is governed by the BSD 3-Clause
 // license that can be found in the LICENSE file.
 
-// +build !windows
+// +build !aix,!windows
 
 package flock
 

+ 202 - 0
vendor/github.com/rootless-containers/rootlesskit/LICENSE

@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 39 - 0
vendor/github.com/rootless-containers/rootlesskit/pkg/api/api.go

@@ -0,0 +1,39 @@
+package api
+
+import "net"
+
+const (
+	// Version of the REST API, not implementation version.
+	// See openapi.yaml for the definition.
+	Version = "1.1.1"
+)
+
+// ErrorJSON is returned with "application/json" content type and non-2XX status code
+type ErrorJSON struct {
+	Message string `json:"message"`
+}
+
+// Info is the structure returned by `GET /info`
+type Info struct {
+	APIVersion    string             `json:"apiVersion"` // REST API version
+	Version       string             `json:"version"`    // Implementation version
+	StateDir      string             `json:"stateDir"`
+	ChildPID      int                `json:"childPID"`
+	NetworkDriver *NetworkDriverInfo `json:"networkDriver,omitempty"`
+	PortDriver    *PortDriverInfo    `json:"portDriver,omitempty"`
+}
+
+// NetworkDriverInfo in Info
+type NetworkDriverInfo struct {
+	Driver         string   `json:"driver"`
+	DNS            []net.IP `json:"dns,omitempty"`
+	ChildIP        net.IP   `json:"childIP,omitempty"`        // since API v1.1.1 (RootlessKit v0.14.1)
+	DynamicChildIP bool     `json:"dynamicChildIP,omitempty"` // since API v1.1.1
+}
+
+// PortDriverInfo in Info
+type PortDriverInfo struct {
+	Driver                  string   `json:"driver"`
+	Protos                  []string `json:"protos"`
+	DisallowLoopbackChildIP bool     `json:"disallowLoopbackChildIP,omitempty"` // since API v1.1.1
+}

+ 212 - 0
vendor/github.com/rootless-containers/rootlesskit/pkg/api/client/client.go

@@ -0,0 +1,212 @@
+package client
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"net/http"
+	"os"
+
+	"github.com/rootless-containers/rootlesskit/pkg/api"
+	"github.com/rootless-containers/rootlesskit/pkg/port"
+)
+
+type Client interface {
+	HTTPClient() *http.Client
+	PortManager() port.Manager
+	Info(context.Context) (*api.Info, error)
+}
+
+// New creates a client.
+// socketPath is a path to the UNIX socket, without unix:// prefix.
+func New(socketPath string) (Client, error) {
+	if _, err := os.Stat(socketPath); err != nil {
+		return nil, err
+	}
+	hc := &http.Client{
+		Transport: &http.Transport{
+			DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
+				var d net.Dialer
+				return d.DialContext(ctx, "unix", socketPath)
+			},
+		},
+	}
+	return NewWithHTTPClient(hc), nil
+}
+
+func NewWithHTTPClient(hc *http.Client) Client {
+	return &client{
+		Client:    hc,
+		version:   "v1",
+		dummyHost: "rootlesskit",
+	}
+}
+
+type client struct {
+	*http.Client
+	// version is always "v1"
+	// TODO(AkihiroSuda): negotiate the version
+	version   string
+	dummyHost string
+}
+
+func (c *client) HTTPClient() *http.Client {
+	return c.Client
+}
+
+func (c *client) PortManager() port.Manager {
+	return &portManager{
+		client: c,
+	}
+}
+
+func (c *client) Info(ctx context.Context) (*api.Info, error) {
+	u := fmt.Sprintf("http://%s/%s/info", c.dummyHost, c.version)
+	req, err := http.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	resp, err := c.HTTPClient().Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if err := successful(resp); err != nil {
+		return nil, err
+	}
+	var info api.Info
+	dec := json.NewDecoder(resp.Body)
+	if err := dec.Decode(&info); err != nil {
+		return nil, err
+	}
+	return &info, nil
+}
+
+func readAtMost(r io.Reader, maxBytes int) ([]byte, error) {
+	lr := &io.LimitedReader{
+		R: r,
+		N: int64(maxBytes),
+	}
+	b, err := io.ReadAll(lr)
+	if err != nil {
+		return b, err
+	}
+	if lr.N == 0 {
+		return b, fmt.Errorf("expected at most %d bytes, got more", maxBytes)
+	}
+	return b, nil
+}
+
+// HTTPStatusErrorBodyMaxLength specifies the maximum length of HTTPStatusError.Body
+const HTTPStatusErrorBodyMaxLength = 64 * 1024
+
+// HTTPStatusError is created from non-2XX HTTP response
+type HTTPStatusError struct {
+	// StatusCode is non-2XX status code
+	StatusCode int
+	// Body is at most HTTPStatusErrorBodyMaxLength
+	Body string
+}
+
+// Error implements error.
+// If e.Body is a marshalled string of api.ErrorJSON, Error returns ErrorJSON.Message .
+// Otherwise Error returns a human-readable string that contains e.StatusCode and e.Body.
+func (e *HTTPStatusError) Error() string {
+	if e.Body != "" && len(e.Body) < HTTPStatusErrorBodyMaxLength {
+		var ej api.ErrorJSON
+		if json.Unmarshal([]byte(e.Body), &ej) == nil {
+			return ej.Message
+		}
+	}
+	return fmt.Sprintf("unexpected HTTP status %s, body=%q", http.StatusText(e.StatusCode), e.Body)
+}
+
+func successful(resp *http.Response) error {
+	if resp == nil {
+		return errors.New("nil response")
+	}
+	if resp.StatusCode/100 != 2 {
+		b, _ := readAtMost(resp.Body, HTTPStatusErrorBodyMaxLength)
+		return &HTTPStatusError{
+			StatusCode: resp.StatusCode,
+			Body:       string(b),
+		}
+	}
+	return nil
+}
+
+type portManager struct {
+	*client
+}
+
+func (pm *portManager) AddPort(ctx context.Context, spec port.Spec) (*port.Status, error) {
+	m, err := json.Marshal(spec)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("http://%s/%s/ports", pm.client.dummyHost, pm.client.version)
+	req, err := http.NewRequest("POST", u, bytes.NewReader(m))
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", "application/json")
+	req = req.WithContext(ctx)
+	resp, err := pm.client.HTTPClient().Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if err := successful(resp); err != nil {
+		return nil, err
+	}
+	dec := json.NewDecoder(resp.Body)
+	var status port.Status
+	if err := dec.Decode(&status); err != nil {
+		return nil, err
+	}
+	return &status, nil
+}
+func (pm *portManager) ListPorts(ctx context.Context) ([]port.Status, error) {
+	u := fmt.Sprintf("http://%s/%s/ports", pm.client.dummyHost, pm.client.version)
+	req, err := http.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, err
+	}
+	req = req.WithContext(ctx)
+	resp, err := pm.client.HTTPClient().Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Body.Close()
+	if err := successful(resp); err != nil {
+		return nil, err
+	}
+	var statuses []port.Status
+	dec := json.NewDecoder(resp.Body)
+	if err := dec.Decode(&statuses); err != nil {
+		return nil, err
+	}
+	return statuses, nil
+}
+func (pm *portManager) RemovePort(ctx context.Context, id int) error {
+	u := fmt.Sprintf("http://%s/%s/ports/%d", pm.client.dummyHost, pm.client.version, id)
+	req, err := http.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return err
+	}
+	req = req.WithContext(ctx)
+	resp, err := pm.client.HTTPClient().Do(req)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	if err := successful(resp); err != nil {
+		return err
+	}
+	return nil
+}

+ 171 - 0
vendor/github.com/rootless-containers/rootlesskit/pkg/api/openapi.yaml

@@ -0,0 +1,171 @@
+# When you made a change to this YAML, please validate with https://editor.swagger.io
+openapi: 3.0.3
+info:
+  version: 1.1.1
+  title: RootlessKit API
+servers:
+  - url: 'http://rootlesskit/v1'
+    description: Local UNIX socket server. The host part of the URL is ignored.
+paths:
+# /info: API >= 1.1.0
+  /info:
+    get:
+      responses:
+        '200':
+          description: Info. Available since API 1.1.0.
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Info'
+  /ports:
+    get:
+      responses:
+        '200':
+          description: An array of PortStatus
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/PortStatuses'
+    post:
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/PortSpec'
+      responses:
+        '201':
+          description: PortStatus with ID
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/PortStatus'
+  '/ports/{id}':
+    delete:
+      parameters:
+        - name: id
+          in: path
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '200':
+          description: Null response
+components:
+  schemas:
+    Proto:
+      type: string
+      description: "protocol for listening. Corresponds to Go's net.Listen. The strings with \"4\" and \"6\" suffixes were introduced in API 1.1.0."
+      enum:
+        - tcp
+        - tcp4
+        - tcp6
+        - udp
+        - udp4
+        - udp6
+        - sctp
+        - sctp4
+        - sctp6
+    PortSpec:
+      required:
+        - proto
+      properties:
+        proto:
+          $ref: '#/components/schemas/Proto'
+        parentIP:
+          type: string
+        parentPort:
+          type: integer
+          format: int32
+          minimum: 1
+          maximum: 65535
+        childIP:
+          type: string
+# future version may support requests with parentPort<=0 for automatic port assignment
+        childPort:
+          type: integer
+          format: int32
+          minimum: 1
+          maximum: 65535
+    PortStatus:
+      required:
+        - id
+      properties:
+        id:
+          type: integer
+          format: int64
+        spec:
+          $ref: '#/components/schemas/PortSpec'
+    PortStatuses:
+      type: array
+      items:
+        $ref: '#/components/schemas/PortStatus'
+# Info: API >= 1.1.0
+    Info:
+      required:
+        - apiVersion
+        - version
+        - stateDir
+        - childPID
+      properties:
+        apiVersion:
+          type: string
+          description: "API version, without \"v\" prefix"
+          example: "1.1.0"
+        version:
+          type: string
+          description: "Implementation version, without \"v\" prefix"
+          example: "0.42.0-beta.1+dev"
+        stateDir:
+          type: string
+          description: "state dir"
+          example: "/run/user/1000/rootlesskit"
+        childPID:
+          type: integer
+          description: "child PID"
+          example: 10042
+        networkDriver:
+          $ref: '#/components/schemas/NetworkDriverInfo'
+        portDriver:
+          $ref: '#/components/schemas/PortDriverInfo'
+    NetworkDriverInfo:
+      required:
+        - driver
+      properties:
+        driver:
+          type: string
+          description: "network driver. Empty when --net=host."
+          example: "slirp4netns"
+# TODO: return TAP info
+        dns:
+          type: array
+          description: "DNS addresses"
+          items:
+            type: string
+          example: ["10.0.2.3"]
+        childIP:
+          type: string
+          description: "Child IP (v4)"
+          example: "10.0.2.100"
+        dynamicChildIP:
+          type: boolean
+          description: "Child IP may change"
+    PortDriverInfo:
+      required:
+        - driver
+        - supportedProtos
+      properties:
+        driver:
+          type: string
+          description: "port driver"
+          example: "builtin"
+        protos:
+          type: array
+          description: "The supported protocol strings for listening ports"
+          example: ["tcp","udp"]
+          items:
+            $ref: '#/components/schemas/Proto'
+        disallowLoopbackChildIP:
+          type: boolean
+          description: "If this field is set to true, loopback IP such as 127.0.0.1 cannot be specified as a child IP"

+ 61 - 0
vendor/github.com/rootless-containers/rootlesskit/pkg/port/port.go

@@ -0,0 +1,61 @@
+package port
+
+import (
+	"context"
+	"net"
+
+	"github.com/rootless-containers/rootlesskit/pkg/api"
+)
+
+type Spec struct {
+	// Proto is one of ["tcp", "tcp4", "tcp6", "udp", "udp4", "udp6"].
+	// "tcp" may cause listening on both IPv4 and IPv6. (Corresponds to Go's net.Listen .)
+	Proto      string `json:"proto,omitempty"`
+	ParentIP   string `json:"parentIP,omitempty"` // IPv4 or IPv6 address. can be empty (0.0.0.0).
+	ParentPort int    `json:"parentPort,omitempty"`
+	ChildPort  int    `json:"childPort,omitempty"`
+	// ChildIP is an IPv4 or IPv6 address.
+	// Default values:
+	// - builtin     driver: 127.0.0.1
+	// - slirp4netns driver: slirp4netns's child IP, e.g., 10.0.2.100
+	ChildIP string `json:"childIP,omitempty"`
+}
+
+type Status struct {
+	ID   int  `json:"id"`
+	Spec Spec `json:"spec"`
+}
+
+// Manager MUST be thread-safe.
+type Manager interface {
+	AddPort(ctx context.Context, spec Spec) (*Status, error)
+	ListPorts(ctx context.Context) ([]Status, error)
+	RemovePort(ctx context.Context, id int) error
+}
+
+// ChildContext is used for RunParentDriver
+type ChildContext struct {
+	// PID of the child, can be used for ns-entering to the child namespaces.
+	PID int
+	// IP of the tap device
+	IP net.IP
+}
+
+// ParentDriver is a driver for the parent process.
+type ParentDriver interface {
+	Manager
+	Info(ctx context.Context) (*api.PortDriverInfo, error)
+	// OpaqueForChild typically consists of socket path
+	// for controlling child from parent
+	OpaqueForChild() map[string]string
+	// RunParentDriver signals initComplete when ParentDriver is ready to
+	// serve as Manager.
+	// RunParentDriver blocks until quit is signaled.
+	//
+	// ChildContext is optional.
+	RunParentDriver(initComplete chan struct{}, quit <-chan struct{}, cctx *ChildContext) error
+}
+
+type ChildDriver interface {
+	RunChildDriver(opaque map[string]string, quit <-chan struct{}) error
+}

+ 6 - 1
vendor/modules.txt

@@ -377,7 +377,7 @@ github.com/fsnotify/fsnotify
 # github.com/godbus/dbus/v5 v5.0.6
 ## explicit; go 1.12
 github.com/godbus/dbus/v5
-# github.com/gofrs/flock v0.7.3
+# github.com/gofrs/flock v0.8.1
 ## explicit
 github.com/gofrs/flock
 # github.com/gogo/googleapis v1.4.0 => github.com/gogo/googleapis v1.3.2
@@ -696,6 +696,11 @@ github.com/prometheus/procfs/internal/fs
 github.com/prometheus/procfs/internal/util
 # github.com/rexray/gocsi v1.2.2 => github.com/dperny/gocsi v1.2.3-pre
 ## explicit; go 1.12
+# github.com/rootless-containers/rootlesskit v0.14.6
+## explicit; go 1.16
+github.com/rootless-containers/rootlesskit/pkg/api
+github.com/rootless-containers/rootlesskit/pkg/api/client
+github.com/rootless-containers/rootlesskit/pkg/port
 # github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
 ## explicit
 github.com/sean-/seed