mirror of
https://github.com/containers/podman.git
synced 2025-05-31 15:42:48 +08:00
bump containers/image to v5.0.0, buildah to v1.11.4
Move to containers/image v5 and containers/buildah to v1.11.4. Replace an equality check with a type assertion when checking for a docker.ErrUnauthorizedForCredentials in `podman login`. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
@ -6,14 +6,15 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/docker"
|
||||
"github.com/containers/image/v4/pkg/docker/config"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/pkg/docker/config"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
"github.com/docker/docker-credential-helpers/credentials"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
@ -134,15 +135,15 @@ func loginCmd(c *cliconfig.LoginValues) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
switch err {
|
||||
case nil:
|
||||
if err == nil {
|
||||
fmt.Println("Login Succeeded!")
|
||||
return nil
|
||||
case docker.ErrUnauthorizedForCredentials:
|
||||
return errors.Errorf("error logging into %q: invalid username/password", server)
|
||||
default:
|
||||
return errors.Wrapf(err, "error authenticating creds for %q", server)
|
||||
}
|
||||
if unauthorizedError, ok := err.(docker.ErrUnauthorizedForCredentials); ok {
|
||||
logrus.Debugf("error logging into %q: %v", server, unauthorizedError)
|
||||
return errors.Errorf("error logging into %q: invalid username/password", server)
|
||||
}
|
||||
return errors.Wrapf(err, "error authenticating creds for %q", server)
|
||||
}
|
||||
|
||||
// getUserAndPass gets the username and password from STDIN if not given
|
||||
|
@ -3,8 +3,8 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/image/v4/docker"
|
||||
"github.com/containers/image/v4/pkg/docker/config"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/pkg/docker/config"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -6,10 +6,10 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/docker"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -6,9 +6,9 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/directory"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/directory"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah/pkg/formats"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/cmd/podman/shared/parse"
|
||||
"github.com/containers/libpod/libpod"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/signature"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod"
|
||||
image2 "github.com/containers/libpod/libpod/image"
|
||||
cc "github.com/containers/libpod/pkg/spec"
|
||||
|
8
go.mod
8
go.mod
@ -11,8 +11,8 @@ require (
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
|
||||
github.com/containernetworking/cni v0.7.1
|
||||
github.com/containernetworking/plugins v0.8.2
|
||||
github.com/containers/buildah v1.11.3
|
||||
github.com/containers/image/v4 v4.0.1
|
||||
github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e
|
||||
github.com/containers/image/v5 v5.0.0
|
||||
github.com/containers/psgo v1.3.2
|
||||
github.com/containers/storage v1.13.5
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
|
||||
@ -21,7 +21,7 @@ require (
|
||||
github.com/cyphar/filepath-securejoin v0.2.2
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b
|
||||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce
|
||||
github.com/docker/docker-credential-helpers v0.6.3
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/docker/go-units v0.4.0
|
||||
@ -64,7 +64,7 @@ require (
|
||||
github.com/varlink/go v0.0.0-20190502142041-0f1d566d194b
|
||||
github.com/vishvananda/netlink v1.0.0
|
||||
go.uber.org/atomic v1.4.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13
|
||||
|
15
go.sum
15
go.sum
@ -43,6 +43,8 @@ github.com/checkpoint-restore/go-criu v0.0.0-20190109184317-bdb7599cd87b/go.mod
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20180216233310-d8fb8589b0e8/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
@ -55,8 +57,12 @@ github.com/containernetworking/plugins v0.8.2 h1:5lnwfsAYO+V7yXhysJKy3E1A2Gy9oVu
|
||||
github.com/containernetworking/plugins v0.8.2/go.mod h1:TxALKWZpWL79BC3GOYKJzzXr7U8R23PdhwaLp6F3adc=
|
||||
github.com/containers/buildah v1.11.3 h1:L5vFj+ao58IGq3G30jN94vRQrIgMU/uTOEKduDr3Nyg=
|
||||
github.com/containers/buildah v1.11.3/go.mod h1:jqZmSU/PhFwTHHlOotnw4bbs1JbkRQLh8dut5DF4Qek=
|
||||
github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e h1:iDavHEx5Yr7o+0l6495Ya6N0YEPplIUZuWC2e14baDM=
|
||||
github.com/containers/buildah v1.11.4-0.20191028173731-21b4778b359e/go.mod h1:Igrk75FAxLnzDaHUbtpWB8pwL+Bv+cnakWMvqAXW2v8=
|
||||
github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ=
|
||||
github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
|
||||
github.com/containers/image/v5 v5.0.0 h1:arnXgbt1ucsC/ndtSpiQY87rA0UjhF+/xQnPzqdBDn4=
|
||||
github.com/containers/image/v5 v5.0.0/go.mod h1:MgiLzCfIeo8lrHi+4Lb8HP+rh513sm0Mlk6RrhjFOLY=
|
||||
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
|
||||
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/psgo v1.3.2 h1:jYfppPih3S/j2Yi5O14AXjd8GfCx1ph9L3YsoK3adko=
|
||||
@ -98,6 +104,8 @@ github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5N
|
||||
github.com/docker/docker v0.0.0-20180522102801-da99009bbb11/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b h1:+Ga+YpCDpcY1fln6GI0fiiirpqHGcob5/Vk3oKNuGdU=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce h1:H3csZuxZESJeeEiOxq4YXPNmLFbjl7u2qVBrAAGX/sA=
|
||||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g=
|
||||
github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
@ -133,6 +141,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsouza/go-dockerclient v1.4.4 h1:Sd5nD4wdAgiPxvrbYUzT2ZZNmPk3z+GGnZ+frvw8z04=
|
||||
github.com/fsouza/go-dockerclient v1.4.4/go.mod h1:PrwszSL5fbmsESocROrOGq/NULMXRw+bajY0ltzD6MA=
|
||||
github.com/fsouza/go-dockerclient v1.5.0 h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVfseKyxbA=
|
||||
github.com/fsouza/go-dockerclient v1.5.0/go.mod h1:AqZZK/zFO3phxYxlTsAaeAMSdQ9mgHuhy+bjN034Qds=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
@ -266,6 +276,7 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM=
|
||||
@ -313,6 +324,8 @@ github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s5
|
||||
github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
|
||||
github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYMeFI18c4=
|
||||
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||
github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I=
|
||||
github.com/openshift/imagebuilder v1.1.1/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
|
||||
@ -433,6 +446,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ=
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
cnitypes "github.com/containernetworking/cni/pkg/types/current"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/lock"
|
||||
"github.com/containers/libpod/pkg/namespaces"
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/util"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/events"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/driver"
|
||||
"github.com/containers/libpod/pkg/util"
|
||||
|
@ -3,8 +3,8 @@ package image
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/types"
|
||||
|
||||
podmanVersion "github.com/containers/libpod/version"
|
||||
)
|
||||
|
@ -12,17 +12,17 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/directory"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
ociarchive "github.com/containers/image/v4/oci/archive"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/tarball"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/directory"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
ociarchive "github.com/containers/image/v5/oci/archive"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/tarball"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod/driver"
|
||||
"github.com/containers/libpod/libpod/events"
|
||||
"github.com/containers/libpod/pkg/inspect"
|
||||
|
@ -3,7 +3,7 @@ package image
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -7,17 +7,17 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/directory"
|
||||
"github.com/containers/image/v4/docker"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
"github.com/containers/image/v4/docker/tarfile"
|
||||
ociarchive "github.com/containers/image/v4/oci/archive"
|
||||
oci "github.com/containers/image/v4/oci/layout"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/directory"
|
||||
"github.com/containers/image/v5/docker"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
"github.com/containers/image/v5/docker/tarfile"
|
||||
ociarchive "github.com/containers/image/v5/oci/archive"
|
||||
oci "github.com/containers/image/v5/oci/layout"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod/events"
|
||||
"github.com/containers/libpod/pkg/registries"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containers/image/v4/docker"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/types"
|
||||
sysreg "github.com/containers/libpod/pkg/registries"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -7,10 +7,10 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/signature"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"regexp"
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/events"
|
||||
"github.com/containers/libpod/pkg/namespaces"
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/types"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/libpod/events"
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
|
@ -17,9 +17,9 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/containers/image/v4/directory"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
ociarchive "github.com/containers/image/v4/oci/archive"
|
||||
"github.com/containers/image/v5/directory"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
ociarchive "github.com/containers/image/v5/oci/archive"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
istorage "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/types"
|
||||
istorage "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/storage"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/cmd/podman/shared/parse"
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod"
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
"github.com/containers/buildah/imagebuildah"
|
||||
"github.com/containers/buildah/pkg/formats"
|
||||
"github.com/containers/buildah/pkg/parse"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
|
@ -17,8 +17,8 @@ import (
|
||||
|
||||
"github.com/containers/buildah/imagebuildah"
|
||||
"github.com/containers/buildah/pkg/formats"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/cmd/podman/remoteclientconfig"
|
||||
iopodman "github.com/containers/libpod/cmd/podman/varlink"
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/pkg/rootless"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/libpod/libpod"
|
||||
"github.com/containers/libpod/libpod/define"
|
||||
"github.com/containers/libpod/pkg/namespaces"
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/cliconfig"
|
||||
"github.com/containers/libpod/pkg/errorhandling"
|
||||
"github.com/containers/libpod/pkg/namespaces"
|
||||
|
@ -16,10 +16,10 @@ import (
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/imagebuildah"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/cmd/podman/varlink"
|
||||
"github.com/containers/libpod/libpod"
|
||||
|
191
vendor/github.com/containerd/containerd/LICENSE
generated
vendored
Normal file
191
vendor/github.com/containerd/containerd/LICENSE
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://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
|
||||
|
||||
Copyright The containerd Authors
|
||||
|
||||
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
|
||||
|
||||
https://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.
|
16
vendor/github.com/containerd/containerd/NOTICE
generated
vendored
Normal file
16
vendor/github.com/containerd/containerd/NOTICE
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
Docker
|
||||
Copyright 2012-2015 Docker, Inc.
|
||||
|
||||
This product includes software developed at Docker, Inc. (https://www.docker.com).
|
||||
|
||||
The following is courtesy of our legal counsel:
|
||||
|
||||
|
||||
Use and transfer of Docker may be subject to certain restrictions by the
|
||||
United States and other governments.
|
||||
It is your responsibility to ensure that your use and/or transfer does not
|
||||
violate applicable laws.
|
||||
|
||||
For more information, please see https://www.bis.doc.gov
|
||||
|
||||
See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.
|
93
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
Normal file
93
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Package errdefs defines the common errors used throughout containerd
|
||||
// packages.
|
||||
//
|
||||
// Use with errors.Wrap and error.Wrapf to add context to an error.
|
||||
//
|
||||
// To detect an error class, use the IsXXX functions to tell whether an error
|
||||
// is of a certain type.
|
||||
//
|
||||
// The functions ToGRPC and FromGRPC can be used to map server-side and
|
||||
// client-side errors to the correct types.
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Definitions of common error types used throughout containerd. All containerd
|
||||
// errors returned by most packages will map into one of these errors classes.
|
||||
// Packages should return errors of these types when they want to instruct a
|
||||
// client to take a particular action.
|
||||
//
|
||||
// For the most part, we just try to provide local grpc errors. Most conditions
|
||||
// map very well to those defined by grpc.
|
||||
var (
|
||||
ErrUnknown = errors.New("unknown") // used internally to represent a missed mapping.
|
||||
ErrInvalidArgument = errors.New("invalid argument")
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrAlreadyExists = errors.New("already exists")
|
||||
ErrFailedPrecondition = errors.New("failed precondition")
|
||||
ErrUnavailable = errors.New("unavailable")
|
||||
ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented
|
||||
)
|
||||
|
||||
// IsInvalidArgument returns true if the error is due to an invalid argument
|
||||
func IsInvalidArgument(err error) bool {
|
||||
return errors.Cause(err) == ErrInvalidArgument
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is due to a missing object
|
||||
func IsNotFound(err error) bool {
|
||||
return errors.Cause(err) == ErrNotFound
|
||||
}
|
||||
|
||||
// IsAlreadyExists returns true if the error is due to an already existing
|
||||
// metadata item
|
||||
func IsAlreadyExists(err error) bool {
|
||||
return errors.Cause(err) == ErrAlreadyExists
|
||||
}
|
||||
|
||||
// IsFailedPrecondition returns true if an operation could not proceed to the
|
||||
// lack of a particular condition
|
||||
func IsFailedPrecondition(err error) bool {
|
||||
return errors.Cause(err) == ErrFailedPrecondition
|
||||
}
|
||||
|
||||
// IsUnavailable returns true if the error is due to a resource being unavailable
|
||||
func IsUnavailable(err error) bool {
|
||||
return errors.Cause(err) == ErrUnavailable
|
||||
}
|
||||
|
||||
// IsNotImplemented returns true if the error is due to not being implemented
|
||||
func IsNotImplemented(err error) bool {
|
||||
return errors.Cause(err) == ErrNotImplemented
|
||||
}
|
||||
|
||||
// IsCanceled returns true if the error is due to `context.Canceled`.
|
||||
func IsCanceled(err error) bool {
|
||||
return errors.Cause(err) == context.Canceled
|
||||
}
|
||||
|
||||
// IsDeadlineExceeded returns true if the error is due to
|
||||
// `context.DeadlineExceeded`.
|
||||
func IsDeadlineExceeded(err error) bool {
|
||||
return errors.Cause(err) == context.DeadlineExceeded
|
||||
}
|
147
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
Normal file
147
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// ToGRPC will attempt to map the backend containerd error into a grpc error,
|
||||
// using the original error message as a description.
|
||||
//
|
||||
// Further information may be extracted from certain errors depending on their
|
||||
// type.
|
||||
//
|
||||
// If the error is unmapped, the original error will be returned to be handled
|
||||
// by the regular grpc error handling stack.
|
||||
func ToGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if isGRPCError(err) {
|
||||
// error has already been mapped to grpc
|
||||
return err
|
||||
}
|
||||
|
||||
switch {
|
||||
case IsInvalidArgument(err):
|
||||
return status.Errorf(codes.InvalidArgument, err.Error())
|
||||
case IsNotFound(err):
|
||||
return status.Errorf(codes.NotFound, err.Error())
|
||||
case IsAlreadyExists(err):
|
||||
return status.Errorf(codes.AlreadyExists, err.Error())
|
||||
case IsFailedPrecondition(err):
|
||||
return status.Errorf(codes.FailedPrecondition, err.Error())
|
||||
case IsUnavailable(err):
|
||||
return status.Errorf(codes.Unavailable, err.Error())
|
||||
case IsNotImplemented(err):
|
||||
return status.Errorf(codes.Unimplemented, err.Error())
|
||||
case IsCanceled(err):
|
||||
return status.Errorf(codes.Canceled, err.Error())
|
||||
case IsDeadlineExceeded(err):
|
||||
return status.Errorf(codes.DeadlineExceeded, err.Error())
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
|
||||
// and combining it with the target error string.
|
||||
//
|
||||
// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
|
||||
func ToGRPCf(err error, format string, args ...interface{}) error {
|
||||
return ToGRPC(errors.Wrapf(err, format, args...))
|
||||
}
|
||||
|
||||
// FromGRPC returns the underlying error from a grpc service based on the grpc error code
|
||||
func FromGRPC(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var cls error // divide these into error classes, becomes the cause
|
||||
|
||||
switch code(err) {
|
||||
case codes.InvalidArgument:
|
||||
cls = ErrInvalidArgument
|
||||
case codes.AlreadyExists:
|
||||
cls = ErrAlreadyExists
|
||||
case codes.NotFound:
|
||||
cls = ErrNotFound
|
||||
case codes.Unavailable:
|
||||
cls = ErrUnavailable
|
||||
case codes.FailedPrecondition:
|
||||
cls = ErrFailedPrecondition
|
||||
case codes.Unimplemented:
|
||||
cls = ErrNotImplemented
|
||||
case codes.Canceled:
|
||||
cls = context.Canceled
|
||||
case codes.DeadlineExceeded:
|
||||
cls = context.DeadlineExceeded
|
||||
default:
|
||||
cls = ErrUnknown
|
||||
}
|
||||
|
||||
msg := rebaseMessage(cls, err)
|
||||
if msg != "" {
|
||||
err = errors.Wrap(cls, msg)
|
||||
} else {
|
||||
err = errors.WithStack(cls)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// rebaseMessage removes the repeats for an error at the end of an error
|
||||
// string. This will happen when taking an error over grpc then remapping it.
|
||||
//
|
||||
// Effectively, we just remove the string of cls from the end of err if it
|
||||
// appears there.
|
||||
func rebaseMessage(cls error, err error) string {
|
||||
desc := errDesc(err)
|
||||
clss := cls.Error()
|
||||
if desc == clss {
|
||||
return ""
|
||||
}
|
||||
|
||||
return strings.TrimSuffix(desc, ": "+clss)
|
||||
}
|
||||
|
||||
func isGRPCError(err error) bool {
|
||||
_, ok := status.FromError(err)
|
||||
return ok
|
||||
}
|
||||
|
||||
func code(err error) codes.Code {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Code()
|
||||
}
|
||||
return codes.Unknown
|
||||
}
|
||||
|
||||
func errDesc(err error) string {
|
||||
if s, ok := status.FromError(err); ok {
|
||||
return s.Message()
|
||||
}
|
||||
return err.Error()
|
||||
}
|
172
vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
Normal file
172
vendor/github.com/containerd/continuity/fs/copy.go
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var bufferPool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
buffer := make([]byte, 32*1024)
|
||||
return &buffer
|
||||
},
|
||||
}
|
||||
|
||||
// XAttrErrorHandlers transform a non-nil xattr error.
|
||||
// Return nil to ignore an error.
|
||||
// xattrKey can be empty for listxattr operation.
|
||||
type XAttrErrorHandler func(dst, src, xattrKey string, err error) error
|
||||
|
||||
type copyDirOpts struct {
|
||||
xeh XAttrErrorHandler
|
||||
}
|
||||
|
||||
type CopyDirOpt func(*copyDirOpts) error
|
||||
|
||||
// WithXAttrErrorHandler allows specifying XAttrErrorHandler
|
||||
// If nil XAttrErrorHandler is specified (default), CopyDir stops
|
||||
// on a non-nil xattr error.
|
||||
func WithXAttrErrorHandler(xeh XAttrErrorHandler) CopyDirOpt {
|
||||
return func(o *copyDirOpts) error {
|
||||
o.xeh = xeh
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllowXAttrErrors allows ignoring xattr errors.
|
||||
func WithAllowXAttrErrors() CopyDirOpt {
|
||||
xeh := func(dst, src, xattrKey string, err error) error {
|
||||
return nil
|
||||
}
|
||||
return WithXAttrErrorHandler(xeh)
|
||||
}
|
||||
|
||||
// CopyDir copies the directory from src to dst.
|
||||
// Most efficient copy of files is attempted.
|
||||
func CopyDir(dst, src string, opts ...CopyDirOpt) error {
|
||||
var o copyDirOpts
|
||||
for _, opt := range opts {
|
||||
if err := opt(&o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
inodes := map[uint64]string{}
|
||||
return copyDirectory(dst, src, inodes, &o)
|
||||
}
|
||||
|
||||
func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) error {
|
||||
stat, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat %s", src)
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
return errors.Errorf("source is not directory")
|
||||
}
|
||||
|
||||
if st, err := os.Stat(dst); err != nil {
|
||||
if err := os.Mkdir(dst, stat.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to mkdir %s", dst)
|
||||
}
|
||||
} else if !st.IsDir() {
|
||||
return errors.Errorf("cannot copy to non-directory: %s", dst)
|
||||
} else {
|
||||
if err := os.Chmod(dst, stat.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to chmod on %s", dst)
|
||||
}
|
||||
}
|
||||
|
||||
fis, err := ioutil.ReadDir(src)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read %s", src)
|
||||
}
|
||||
|
||||
if err := copyFileInfo(stat, dst); err != nil {
|
||||
return errors.Wrapf(err, "failed to copy file info for %s", dst)
|
||||
}
|
||||
|
||||
for _, fi := range fis {
|
||||
source := filepath.Join(src, fi.Name())
|
||||
target := filepath.Join(dst, fi.Name())
|
||||
|
||||
switch {
|
||||
case fi.IsDir():
|
||||
if err := copyDirectory(target, source, inodes, o); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
case (fi.Mode() & os.ModeType) == 0:
|
||||
link, err := getLinkSource(target, fi, inodes)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get hardlink")
|
||||
}
|
||||
if link != "" {
|
||||
if err := os.Link(link, target); err != nil {
|
||||
return errors.Wrap(err, "failed to create hard link")
|
||||
}
|
||||
} else if err := CopyFile(target, source); err != nil {
|
||||
return errors.Wrap(err, "failed to copy files")
|
||||
}
|
||||
case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink:
|
||||
link, err := os.Readlink(source)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read link: %s", source)
|
||||
}
|
||||
if err := os.Symlink(link, target); err != nil {
|
||||
return errors.Wrapf(err, "failed to create symlink: %s", target)
|
||||
}
|
||||
case (fi.Mode() & os.ModeDevice) == os.ModeDevice:
|
||||
if err := copyDevice(target, fi); err != nil {
|
||||
return errors.Wrapf(err, "failed to create device")
|
||||
}
|
||||
default:
|
||||
// TODO: Support pipes and sockets
|
||||
return errors.Wrapf(err, "unsupported mode %s", fi.Mode())
|
||||
}
|
||||
if err := copyFileInfo(fi, target); err != nil {
|
||||
return errors.Wrap(err, "failed to copy file info")
|
||||
}
|
||||
|
||||
if err := copyXAttrs(target, source, o.xeh); err != nil {
|
||||
return errors.Wrap(err, "failed to copy xattrs")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyFile copies the source file to the target.
|
||||
// The most efficient means of copying is used for the platform.
|
||||
func CopyFile(target, source string) error {
|
||||
src, err := os.Open(source)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to open source %s", source)
|
||||
}
|
||||
defer src.Close()
|
||||
tgt, err := os.Create(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to open target %s", target)
|
||||
}
|
||||
defer tgt.Close()
|
||||
|
||||
return copyFileContent(tgt, src)
|
||||
}
|
144
vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
Normal file
144
vendor/github.com/containerd/continuity/fs/copy_linux.go
generated
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func copyFileInfo(fi os.FileInfo, name string) error {
|
||||
st := fi.Sys().(*syscall.Stat_t)
|
||||
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
|
||||
if os.IsPermission(err) {
|
||||
// Normally if uid/gid are the same this would be a no-op, but some
|
||||
// filesystems may still return EPERM... for instance NFS does this.
|
||||
// In such a case, this is not an error.
|
||||
if dstStat, err2 := os.Lstat(name); err2 == nil {
|
||||
st2 := dstStat.Sys().(*syscall.Stat_t)
|
||||
if st.Uid == st2.Uid && st.Gid == st2.Gid {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to chown %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
|
||||
if err := os.Chmod(name, fi.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to chmod %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
timespec := []unix.Timespec{unix.Timespec(StatAtime(st)), unix.Timespec(StatMtime(st))}
|
||||
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
|
||||
return errors.Wrapf(err, "failed to utime %s", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const maxSSizeT = int64(^uint(0) >> 1)
|
||||
|
||||
func copyFileContent(dst, src *os.File) error {
|
||||
st, err := src.Stat()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to stat source")
|
||||
}
|
||||
|
||||
size := st.Size()
|
||||
first := true
|
||||
srcFd := int(src.Fd())
|
||||
dstFd := int(dst.Fd())
|
||||
|
||||
for size > 0 {
|
||||
// Ensure that we are never trying to copy more than SSIZE_MAX at a
|
||||
// time and at the same time avoids overflows when the file is larger
|
||||
// than 4GB on 32-bit systems.
|
||||
var copySize int
|
||||
if size > maxSSizeT {
|
||||
copySize = int(maxSSizeT)
|
||||
} else {
|
||||
copySize = int(size)
|
||||
}
|
||||
n, err := unix.CopyFileRange(srcFd, nil, dstFd, nil, copySize, 0)
|
||||
if err != nil {
|
||||
if (err != unix.ENOSYS && err != unix.EXDEV) || !first {
|
||||
return errors.Wrap(err, "copy file range failed")
|
||||
}
|
||||
|
||||
buf := bufferPool.Get().(*[]byte)
|
||||
_, err = io.CopyBuffer(dst, src, *buf)
|
||||
bufferPool.Put(buf)
|
||||
return errors.Wrap(err, "userspace copy failed")
|
||||
}
|
||||
|
||||
first = false
|
||||
size -= int64(n)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
xattrKeys, err := sysx.LListxattr(src)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||
if xeh != nil {
|
||||
e = xeh(dst, src, "", e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
for _, xattr := range xattrKeys {
|
||||
data, err := sysx.LGetxattr(src, xattr)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyDevice(dst string, fi os.FileInfo) error {
|
||||
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return errors.New("unsupported stat type")
|
||||
}
|
||||
return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
|
||||
}
|
112
vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
Normal file
112
vendor/github.com/containerd/continuity/fs/copy_unix.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
// +build solaris darwin freebsd
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func copyFileInfo(fi os.FileInfo, name string) error {
|
||||
st := fi.Sys().(*syscall.Stat_t)
|
||||
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
|
||||
if os.IsPermission(err) {
|
||||
// Normally if uid/gid are the same this would be a no-op, but some
|
||||
// filesystems may still return EPERM... for instance NFS does this.
|
||||
// In such a case, this is not an error.
|
||||
if dstStat, err2 := os.Lstat(name); err2 == nil {
|
||||
st2 := dstStat.Sys().(*syscall.Stat_t)
|
||||
if st.Uid == st2.Uid && st.Gid == st2.Gid {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to chown %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
|
||||
if err := os.Chmod(name, fi.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to chmod %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
timespec := []syscall.Timespec{StatAtime(st), StatMtime(st)}
|
||||
if err := syscall.UtimesNano(name, timespec); err != nil {
|
||||
return errors.Wrapf(err, "failed to utime %s", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFileContent(dst, src *os.File) error {
|
||||
buf := bufferPool.Get().(*[]byte)
|
||||
_, err := io.CopyBuffer(dst, src, *buf)
|
||||
bufferPool.Put(buf)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
xattrKeys, err := sysx.LListxattr(src)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to list xattrs on %s", src)
|
||||
if xeh != nil {
|
||||
e = xeh(dst, src, "", e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
for _, xattr := range xattrKeys {
|
||||
data, err := sysx.LGetxattr(src, xattr)
|
||||
if err != nil {
|
||||
e := errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
||||
e := errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
||||
if xeh != nil {
|
||||
if e = xeh(dst, src, xattr, e); e == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyDevice(dst string, fi os.FileInfo) error {
|
||||
st, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return errors.New("unsupported stat type")
|
||||
}
|
||||
return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
|
||||
}
|
49
vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
Normal file
49
vendor/github.com/containerd/continuity/fs/copy_windows.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func copyFileInfo(fi os.FileInfo, name string) error {
|
||||
if err := os.Chmod(name, fi.Mode()); err != nil {
|
||||
return errors.Wrapf(err, "failed to chmod %s", name)
|
||||
}
|
||||
|
||||
// TODO: copy windows specific metadata
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFileContent(dst, src *os.File) error {
|
||||
buf := bufferPool.Get().(*[]byte)
|
||||
_, err := io.CopyBuffer(dst, src, *buf)
|
||||
bufferPool.Put(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
func copyXAttrs(dst, src string, xeh XAttrErrorHandler) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyDevice(dst string, fi os.FileInfo) error {
|
||||
return errors.New("device copy not supported")
|
||||
}
|
326
vendor/github.com/containerd/continuity/fs/diff.go
generated
vendored
Normal file
326
vendor/github.com/containerd/continuity/fs/diff.go
generated
vendored
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ChangeKind is the type of modification that
|
||||
// a change is making.
|
||||
type ChangeKind int
|
||||
|
||||
const (
|
||||
// ChangeKindUnmodified represents an unmodified
|
||||
// file
|
||||
ChangeKindUnmodified = iota
|
||||
|
||||
// ChangeKindAdd represents an addition of
|
||||
// a file
|
||||
ChangeKindAdd
|
||||
|
||||
// ChangeKindModify represents a change to
|
||||
// an existing file
|
||||
ChangeKindModify
|
||||
|
||||
// ChangeKindDelete represents a delete of
|
||||
// a file
|
||||
ChangeKindDelete
|
||||
)
|
||||
|
||||
func (k ChangeKind) String() string {
|
||||
switch k {
|
||||
case ChangeKindUnmodified:
|
||||
return "unmodified"
|
||||
case ChangeKindAdd:
|
||||
return "add"
|
||||
case ChangeKindModify:
|
||||
return "modify"
|
||||
case ChangeKindDelete:
|
||||
return "delete"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Change represents single change between a diff and its parent.
|
||||
type Change struct {
|
||||
Kind ChangeKind
|
||||
Path string
|
||||
}
|
||||
|
||||
// ChangeFunc is the type of function called for each change
|
||||
// computed during a directory changes calculation.
|
||||
type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
|
||||
|
||||
// Changes computes changes between two directories calling the
|
||||
// given change function for each computed change. The first
|
||||
// directory is intended to the base directory and second
|
||||
// directory the changed directory.
|
||||
//
|
||||
// The change callback is called by the order of path names and
|
||||
// should be appliable in that order.
|
||||
// Due to this apply ordering, the following is true
|
||||
// - Removed directory trees only create a single change for the root
|
||||
// directory removed. Remaining changes are implied.
|
||||
// - A directory which is modified to become a file will not have
|
||||
// delete entries for sub-path items, their removal is implied
|
||||
// by the removal of the parent directory.
|
||||
//
|
||||
// Opaque directories will not be treated specially and each file
|
||||
// removed from the base directory will show up as a removal.
|
||||
//
|
||||
// File content comparisons will be done on files which have timestamps
|
||||
// which may have been truncated. If either of the files being compared
|
||||
// has a zero value nanosecond value, each byte will be compared for
|
||||
// differences. If 2 files have the same seconds value but different
|
||||
// nanosecond values where one of those values is zero, the files will
|
||||
// be considered unchanged if the content is the same. This behavior
|
||||
// is to account for timestamp truncation during archiving.
|
||||
func Changes(ctx context.Context, a, b string, changeFn ChangeFunc) error {
|
||||
if a == "" {
|
||||
logrus.Debugf("Using single walk diff for %s", b)
|
||||
return addDirChanges(ctx, changeFn, b)
|
||||
} else if diffOptions := detectDirDiff(b, a); diffOptions != nil {
|
||||
logrus.Debugf("Using single walk diff for %s from %s", diffOptions.diffDir, a)
|
||||
return diffDirChanges(ctx, changeFn, a, diffOptions)
|
||||
}
|
||||
|
||||
logrus.Debugf("Using double walk diff for %s from %s", b, a)
|
||||
return doubleWalkDiff(ctx, changeFn, a, b)
|
||||
}
|
||||
|
||||
func addDirChanges(ctx context.Context, changeFn ChangeFunc, root string) error {
|
||||
return filepath.Walk(root, func(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rebase path
|
||||
path, err = filepath.Rel(root, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = filepath.Join(string(os.PathSeparator), path)
|
||||
|
||||
// Skip root
|
||||
if path == string(os.PathSeparator) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return changeFn(ChangeKindAdd, path, f, nil)
|
||||
})
|
||||
}
|
||||
|
||||
// diffDirOptions is used when the diff can be directly calculated from
|
||||
// a diff directory to its base, without walking both trees.
|
||||
type diffDirOptions struct {
|
||||
diffDir string
|
||||
skipChange func(string) (bool, error)
|
||||
deleteChange func(string, string, os.FileInfo) (string, error)
|
||||
}
|
||||
|
||||
// diffDirChanges walks the diff directory and compares changes against the base.
|
||||
func diffDirChanges(ctx context.Context, changeFn ChangeFunc, base string, o *diffDirOptions) error {
|
||||
changedDirs := make(map[string]struct{})
|
||||
return filepath.Walk(o.diffDir, func(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rebase path
|
||||
path, err = filepath.Rel(o.diffDir, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = filepath.Join(string(os.PathSeparator), path)
|
||||
|
||||
// Skip root
|
||||
if path == string(os.PathSeparator) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: handle opaqueness, start new double walker at this
|
||||
// location to get deletes, and skip tree in single walker
|
||||
|
||||
if o.skipChange != nil {
|
||||
if skip, err := o.skipChange(path); skip {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var kind ChangeKind
|
||||
|
||||
deletedFile, err := o.deleteChange(o.diffDir, path, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Find out what kind of modification happened
|
||||
if deletedFile != "" {
|
||||
path = deletedFile
|
||||
kind = ChangeKindDelete
|
||||
f = nil
|
||||
} else {
|
||||
// Otherwise, the file was added
|
||||
kind = ChangeKindAdd
|
||||
|
||||
// ...Unless it already existed in a base, in which case, it's a modification
|
||||
stat, err := os.Stat(filepath.Join(base, path))
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
// The file existed in the base, so that's a modification
|
||||
|
||||
// However, if it's a directory, maybe it wasn't actually modified.
|
||||
// If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar
|
||||
if stat.IsDir() && f.IsDir() {
|
||||
if f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) {
|
||||
// Both directories are the same, don't record the change
|
||||
return nil
|
||||
}
|
||||
}
|
||||
kind = ChangeKindModify
|
||||
}
|
||||
}
|
||||
|
||||
// If /foo/bar/file.txt is modified, then /foo/bar must be part of the changed files.
|
||||
// This block is here to ensure the change is recorded even if the
|
||||
// modify time, mode and size of the parent directory in the rw and ro layers are all equal.
|
||||
// Check https://github.com/docker/docker/pull/13590 for details.
|
||||
if f.IsDir() {
|
||||
changedDirs[path] = struct{}{}
|
||||
}
|
||||
if kind == ChangeKindAdd || kind == ChangeKindDelete {
|
||||
parent := filepath.Dir(path)
|
||||
if _, ok := changedDirs[parent]; !ok && parent != "/" {
|
||||
pi, err := os.Stat(filepath.Join(o.diffDir, parent))
|
||||
if err := changeFn(ChangeKindModify, parent, pi, err); err != nil {
|
||||
return err
|
||||
}
|
||||
changedDirs[parent] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return changeFn(kind, path, f, nil)
|
||||
})
|
||||
}
|
||||
|
||||
// doubleWalkDiff walks both directories to create a diff
|
||||
func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b string) (err error) {
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var (
|
||||
c1 = make(chan *currentPath)
|
||||
c2 = make(chan *currentPath)
|
||||
|
||||
f1, f2 *currentPath
|
||||
rmdir string
|
||||
)
|
||||
g.Go(func() error {
|
||||
defer close(c1)
|
||||
return pathWalk(ctx, a, c1)
|
||||
})
|
||||
g.Go(func() error {
|
||||
defer close(c2)
|
||||
return pathWalk(ctx, b, c2)
|
||||
})
|
||||
g.Go(func() error {
|
||||
for c1 != nil || c2 != nil {
|
||||
if f1 == nil && c1 != nil {
|
||||
f1, err = nextPath(ctx, c1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f1 == nil {
|
||||
c1 = nil
|
||||
}
|
||||
}
|
||||
|
||||
if f2 == nil && c2 != nil {
|
||||
f2, err = nextPath(ctx, c2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f2 == nil {
|
||||
c2 = nil
|
||||
}
|
||||
}
|
||||
if f1 == nil && f2 == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var f os.FileInfo
|
||||
k, p := pathChange(f1, f2)
|
||||
switch k {
|
||||
case ChangeKindAdd:
|
||||
if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f = f2.f
|
||||
f2 = nil
|
||||
case ChangeKindDelete:
|
||||
// Check if this file is already removed by being
|
||||
// under of a removed directory
|
||||
if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
|
||||
f1 = nil
|
||||
continue
|
||||
} else if f1.f.IsDir() {
|
||||
rmdir = f1.path + string(os.PathSeparator)
|
||||
} else if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f1 = nil
|
||||
case ChangeKindModify:
|
||||
same, err := sameFile(f1, f2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f1.f.IsDir() && !f2.f.IsDir() {
|
||||
rmdir = f1.path + string(os.PathSeparator)
|
||||
} else if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f = f2.f
|
||||
f1 = nil
|
||||
f2 = nil
|
||||
if same {
|
||||
if !isLinked(f) {
|
||||
continue
|
||||
}
|
||||
k = ChangeKindUnmodified
|
||||
}
|
||||
}
|
||||
if err := changeFn(k, p, f, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return g.Wait()
|
||||
}
|
74
vendor/github.com/containerd/continuity/fs/diff_unix.go
generated
vendored
Normal file
74
vendor/github.com/containerd/continuity/fs/diff_unix.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/continuity/sysx"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// detectDirDiff returns diff dir options if a directory could
|
||||
// be found in the mount info for upper which is the direct
|
||||
// diff with the provided lower directory
|
||||
func detectDirDiff(upper, lower string) *diffDirOptions {
|
||||
// TODO: get mount options for upper
|
||||
// TODO: detect AUFS
|
||||
// TODO: detect overlay
|
||||
return nil
|
||||
}
|
||||
|
||||
// compareSysStat returns whether the stats are equivalent,
|
||||
// whether the files are considered the same file, and
|
||||
// an error
|
||||
func compareSysStat(s1, s2 interface{}) (bool, error) {
|
||||
ls1, ok := s1.(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
ls2, ok := s2.(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return ls1.Mode == ls2.Mode && ls1.Uid == ls2.Uid && ls1.Gid == ls2.Gid && ls1.Rdev == ls2.Rdev, nil
|
||||
}
|
||||
|
||||
func compareCapabilities(p1, p2 string) (bool, error) {
|
||||
c1, err := sysx.LGetxattr(p1, "security.capability")
|
||||
if err != nil && err != sysx.ENODATA {
|
||||
return false, errors.Wrapf(err, "failed to get xattr for %s", p1)
|
||||
}
|
||||
c2, err := sysx.LGetxattr(p2, "security.capability")
|
||||
if err != nil && err != sysx.ENODATA {
|
||||
return false, errors.Wrapf(err, "failed to get xattr for %s", p2)
|
||||
}
|
||||
return bytes.Equal(c1, c2), nil
|
||||
}
|
||||
|
||||
func isLinked(f os.FileInfo) bool {
|
||||
s, ok := f.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return !f.IsDir() && s.Nlink > 1
|
||||
}
|
48
vendor/github.com/containerd/continuity/fs/diff_windows.go
generated
vendored
Normal file
48
vendor/github.com/containerd/continuity/fs/diff_windows.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func detectDirDiff(upper, lower string) *diffDirOptions {
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareSysStat(s1, s2 interface{}) (bool, error) {
|
||||
f1, ok := s1.(windows.Win32FileAttributeData)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
f2, ok := s2.(windows.Win32FileAttributeData)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
return f1.FileAttributes == f2.FileAttributes, nil
|
||||
}
|
||||
|
||||
func compareCapabilities(p1, p2 string) (bool, error) {
|
||||
// TODO: Use windows equivalent
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func isLinked(os.FileInfo) bool {
|
||||
return false
|
||||
}
|
103
vendor/github.com/containerd/continuity/fs/dtype_linux.go
generated
vendored
Normal file
103
vendor/github.com/containerd/continuity/fs/dtype_linux.go
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
// +build linux
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func locateDummyIfEmpty(path string) (string, error) {
|
||||
children, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(children) != 0 {
|
||||
return "", nil
|
||||
}
|
||||
dummyFile, err := ioutil.TempFile(path, "fsutils-dummy")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
name := dummyFile.Name()
|
||||
err = dummyFile.Close()
|
||||
return name, err
|
||||
}
|
||||
|
||||
// SupportsDType returns whether the filesystem mounted on path supports d_type
|
||||
func SupportsDType(path string) (bool, error) {
|
||||
// locate dummy so that we have at least one dirent
|
||||
dummy, err := locateDummyIfEmpty(path)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if dummy != "" {
|
||||
defer os.Remove(dummy)
|
||||
}
|
||||
|
||||
visited := 0
|
||||
supportsDType := true
|
||||
fn := func(ent *syscall.Dirent) bool {
|
||||
visited++
|
||||
if ent.Type == syscall.DT_UNKNOWN {
|
||||
supportsDType = false
|
||||
// stop iteration
|
||||
return true
|
||||
}
|
||||
// continue iteration
|
||||
return false
|
||||
}
|
||||
if err = iterateReadDir(path, fn); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if visited == 0 {
|
||||
return false, fmt.Errorf("did not hit any dirent during iteration %s", path)
|
||||
}
|
||||
return supportsDType, nil
|
||||
}
|
||||
|
||||
func iterateReadDir(path string, fn func(*syscall.Dirent) bool) error {
|
||||
d, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer d.Close()
|
||||
fd := int(d.Fd())
|
||||
buf := make([]byte, 4096)
|
||||
for {
|
||||
nbytes, err := syscall.ReadDirent(fd, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nbytes == 0 {
|
||||
break
|
||||
}
|
||||
for off := 0; off < nbytes; {
|
||||
ent := (*syscall.Dirent)(unsafe.Pointer(&buf[off]))
|
||||
if stop := fn(ent); stop {
|
||||
return nil
|
||||
}
|
||||
off += int(ent.Reclen)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
38
vendor/github.com/containerd/continuity/fs/du.go
generated
vendored
Normal file
38
vendor/github.com/containerd/continuity/fs/du.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import "context"
|
||||
|
||||
// Usage of disk information
|
||||
type Usage struct {
|
||||
Inodes int64
|
||||
Size int64
|
||||
}
|
||||
|
||||
// DiskUsage counts the number of inodes and disk usage for the resources under
|
||||
// path.
|
||||
func DiskUsage(ctx context.Context, roots ...string) (Usage, error) {
|
||||
return diskUsage(ctx, roots...)
|
||||
}
|
||||
|
||||
// DiffUsage counts the numbers of inodes and disk usage in the
|
||||
// diff between the 2 directories. The first path is intended
|
||||
// as the base directory and the second as the changed directory.
|
||||
func DiffUsage(ctx context.Context, a, b string) (Usage, error) {
|
||||
return diffUsage(ctx, a, b)
|
||||
}
|
110
vendor/github.com/containerd/continuity/fs/du_unix.go
generated
vendored
Normal file
110
vendor/github.com/containerd/continuity/fs/du_unix.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type inode struct {
|
||||
// TODO(stevvooe): Can probably reduce memory usage by not tracking
|
||||
// device, but we can leave this right for now.
|
||||
dev, ino uint64
|
||||
}
|
||||
|
||||
func newInode(stat *syscall.Stat_t) inode {
|
||||
return inode{
|
||||
// Dev is uint32 on darwin/bsd, uint64 on linux/solaris
|
||||
dev: uint64(stat.Dev), // nolint: unconvert
|
||||
// Ino is uint32 on bsd, uint64 on darwin/linux/solaris
|
||||
ino: uint64(stat.Ino), // nolint: unconvert
|
||||
}
|
||||
}
|
||||
|
||||
func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
|
||||
|
||||
var (
|
||||
size int64
|
||||
inodes = map[inode]struct{}{} // expensive!
|
||||
)
|
||||
|
||||
for _, root := range roots {
|
||||
if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
inoKey := newInode(fi.Sys().(*syscall.Stat_t))
|
||||
if _, ok := inodes[inoKey]; !ok {
|
||||
inodes[inoKey] = struct{}{}
|
||||
size += fi.Size()
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return Usage{
|
||||
Inodes: int64(len(inodes)),
|
||||
Size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func diffUsage(ctx context.Context, a, b string) (Usage, error) {
|
||||
var (
|
||||
size int64
|
||||
inodes = map[inode]struct{}{} // expensive!
|
||||
)
|
||||
|
||||
if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if kind == ChangeKindAdd || kind == ChangeKindModify {
|
||||
inoKey := newInode(fi.Sys().(*syscall.Stat_t))
|
||||
if _, ok := inodes[inoKey]; !ok {
|
||||
inodes[inoKey] = struct{}{}
|
||||
size += fi.Size()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
|
||||
return Usage{
|
||||
Inodes: int64(len(inodes)),
|
||||
Size: size,
|
||||
}, nil
|
||||
}
|
82
vendor/github.com/containerd/continuity/fs/du_windows.go
generated
vendored
Normal file
82
vendor/github.com/containerd/continuity/fs/du_windows.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
|
||||
var (
|
||||
size int64
|
||||
)
|
||||
|
||||
// TODO(stevvooe): Support inodes (or equivalent) for windows.
|
||||
|
||||
for _, root := range roots {
|
||||
if err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
size += fi.Size()
|
||||
return nil
|
||||
}); err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return Usage{
|
||||
Size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func diffUsage(ctx context.Context, a, b string) (Usage, error) {
|
||||
var (
|
||||
size int64
|
||||
)
|
||||
|
||||
if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if kind == ChangeKindAdd || kind == ChangeKindModify {
|
||||
size += fi.Size()
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return Usage{}, err
|
||||
}
|
||||
|
||||
return Usage{
|
||||
Size: size,
|
||||
}, nil
|
||||
}
|
43
vendor/github.com/containerd/continuity/fs/hardlink.go
generated
vendored
Normal file
43
vendor/github.com/containerd/continuity/fs/hardlink.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import "os"
|
||||
|
||||
// GetLinkInfo returns an identifier representing the node a hardlink is pointing
|
||||
// to. If the file is not hard linked then 0 will be returned.
|
||||
func GetLinkInfo(fi os.FileInfo) (uint64, bool) {
|
||||
return getLinkInfo(fi)
|
||||
}
|
||||
|
||||
// getLinkSource returns a path for the given name and
|
||||
// file info to its link source in the provided inode
|
||||
// map. If the given file name is not in the map and
|
||||
// has other links, it is added to the inode map
|
||||
// to be a source for other link locations.
|
||||
func getLinkSource(name string, fi os.FileInfo, inodes map[uint64]string) (string, error) {
|
||||
inode, isHardlink := getLinkInfo(fi)
|
||||
if !isHardlink {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
path, ok := inodes[inode]
|
||||
if !ok {
|
||||
inodes[inode] = name
|
||||
}
|
||||
return path, nil
|
||||
}
|
34
vendor/github.com/containerd/continuity/fs/hardlink_unix.go
generated
vendored
Normal file
34
vendor/github.com/containerd/continuity/fs/hardlink_unix.go
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func getLinkInfo(fi os.FileInfo) (uint64, bool) {
|
||||
s, ok := fi.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Ino is uint32 on bsd, uint64 on darwin/linux/solaris
|
||||
return uint64(s.Ino), !fi.IsDir() && s.Nlink > 1 // nolint: unconvert
|
||||
}
|
23
vendor/github.com/containerd/continuity/fs/hardlink_windows.go
generated
vendored
Normal file
23
vendor/github.com/containerd/continuity/fs/hardlink_windows.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import "os"
|
||||
|
||||
func getLinkInfo(fi os.FileInfo) (uint64, bool) {
|
||||
return 0, false
|
||||
}
|
313
vendor/github.com/containerd/continuity/fs/path.go
generated
vendored
Normal file
313
vendor/github.com/containerd/continuity/fs/path.go
generated
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
errTooManyLinks = errors.New("too many links")
|
||||
)
|
||||
|
||||
type currentPath struct {
|
||||
path string
|
||||
f os.FileInfo
|
||||
fullPath string
|
||||
}
|
||||
|
||||
func pathChange(lower, upper *currentPath) (ChangeKind, string) {
|
||||
if lower == nil {
|
||||
if upper == nil {
|
||||
panic("cannot compare nil paths")
|
||||
}
|
||||
return ChangeKindAdd, upper.path
|
||||
}
|
||||
if upper == nil {
|
||||
return ChangeKindDelete, lower.path
|
||||
}
|
||||
|
||||
switch i := directoryCompare(lower.path, upper.path); {
|
||||
case i < 0:
|
||||
// File in lower that is not in upper
|
||||
return ChangeKindDelete, lower.path
|
||||
case i > 0:
|
||||
// File in upper that is not in lower
|
||||
return ChangeKindAdd, upper.path
|
||||
default:
|
||||
return ChangeKindModify, upper.path
|
||||
}
|
||||
}
|
||||
|
||||
func directoryCompare(a, b string) int {
|
||||
l := len(a)
|
||||
if len(b) < l {
|
||||
l = len(b)
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
c1, c2 := a[i], b[i]
|
||||
if c1 == filepath.Separator {
|
||||
c1 = byte(0)
|
||||
}
|
||||
if c2 == filepath.Separator {
|
||||
c2 = byte(0)
|
||||
}
|
||||
if c1 < c2 {
|
||||
return -1
|
||||
}
|
||||
if c1 > c2 {
|
||||
return +1
|
||||
}
|
||||
}
|
||||
if len(a) < len(b) {
|
||||
return -1
|
||||
}
|
||||
if len(a) > len(b) {
|
||||
return +1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func sameFile(f1, f2 *currentPath) (bool, error) {
|
||||
if os.SameFile(f1.f, f2.f) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
equalStat, err := compareSysStat(f1.f.Sys(), f2.f.Sys())
|
||||
if err != nil || !equalStat {
|
||||
return equalStat, err
|
||||
}
|
||||
|
||||
if eq, err := compareCapabilities(f1.fullPath, f2.fullPath); err != nil || !eq {
|
||||
return eq, err
|
||||
}
|
||||
|
||||
// If not a directory also check size, modtime, and content
|
||||
if !f1.f.IsDir() {
|
||||
if f1.f.Size() != f2.f.Size() {
|
||||
return false, nil
|
||||
}
|
||||
t1 := f1.f.ModTime()
|
||||
t2 := f2.f.ModTime()
|
||||
|
||||
if t1.Unix() != t2.Unix() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// If the timestamp may have been truncated in both of the
|
||||
// files, check content of file to determine difference
|
||||
if t1.Nanosecond() == 0 && t2.Nanosecond() == 0 {
|
||||
var eq bool
|
||||
if (f1.f.Mode() & os.ModeSymlink) == os.ModeSymlink {
|
||||
eq, err = compareSymlinkTarget(f1.fullPath, f2.fullPath)
|
||||
} else if f1.f.Size() > 0 {
|
||||
eq, err = compareFileContent(f1.fullPath, f2.fullPath)
|
||||
}
|
||||
if err != nil || !eq {
|
||||
return eq, err
|
||||
}
|
||||
} else if t1.Nanosecond() != t2.Nanosecond() {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func compareSymlinkTarget(p1, p2 string) (bool, error) {
|
||||
t1, err := os.Readlink(p1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
t2, err := os.Readlink(p2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t1 == t2, nil
|
||||
}
|
||||
|
||||
const compareChuckSize = 32 * 1024
|
||||
|
||||
// compareFileContent compares the content of 2 same sized files
|
||||
// by comparing each byte.
|
||||
func compareFileContent(p1, p2 string) (bool, error) {
|
||||
f1, err := os.Open(p1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f1.Close()
|
||||
f2, err := os.Open(p2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer f2.Close()
|
||||
|
||||
b1 := make([]byte, compareChuckSize)
|
||||
b2 := make([]byte, compareChuckSize)
|
||||
for {
|
||||
n1, err1 := f1.Read(b1)
|
||||
if err1 != nil && err1 != io.EOF {
|
||||
return false, err1
|
||||
}
|
||||
n2, err2 := f2.Read(b2)
|
||||
if err2 != nil && err2 != io.EOF {
|
||||
return false, err2
|
||||
}
|
||||
if n1 != n2 || !bytes.Equal(b1[:n1], b2[:n2]) {
|
||||
return false, nil
|
||||
}
|
||||
if err1 == io.EOF && err2 == io.EOF {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func pathWalk(ctx context.Context, root string, pathC chan<- *currentPath) error {
|
||||
return filepath.Walk(root, func(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rebase path
|
||||
path, err = filepath.Rel(root, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = filepath.Join(string(os.PathSeparator), path)
|
||||
|
||||
// Skip root
|
||||
if path == string(os.PathSeparator) {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := ¤tPath{
|
||||
path: path,
|
||||
f: f,
|
||||
fullPath: filepath.Join(root, path),
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case pathC <- p:
|
||||
return nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func nextPath(ctx context.Context, pathC <-chan *currentPath) (*currentPath, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case p := <-pathC:
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
// RootPath joins a path with a root, evaluating and bounding any
|
||||
// symlink to the root directory.
|
||||
func RootPath(root, path string) (string, error) {
|
||||
if path == "" {
|
||||
return root, nil
|
||||
}
|
||||
var linksWalked int // to protect against cycles
|
||||
for {
|
||||
i := linksWalked
|
||||
newpath, err := walkLinks(root, path, &linksWalked)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
path = newpath
|
||||
if i == linksWalked {
|
||||
newpath = filepath.Join("/", newpath)
|
||||
if path == newpath {
|
||||
return filepath.Join(root, newpath), nil
|
||||
}
|
||||
path = newpath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func walkLink(root, path string, linksWalked *int) (newpath string, islink bool, err error) {
|
||||
if *linksWalked > 255 {
|
||||
return "", false, errTooManyLinks
|
||||
}
|
||||
|
||||
path = filepath.Join("/", path)
|
||||
if path == "/" {
|
||||
return path, false, nil
|
||||
}
|
||||
realPath := filepath.Join(root, path)
|
||||
|
||||
fi, err := os.Lstat(realPath)
|
||||
if err != nil {
|
||||
// If path does not yet exist, treat as non-symlink
|
||||
if os.IsNotExist(err) {
|
||||
return path, false, nil
|
||||
}
|
||||
return "", false, err
|
||||
}
|
||||
if fi.Mode()&os.ModeSymlink == 0 {
|
||||
return path, false, nil
|
||||
}
|
||||
newpath, err = os.Readlink(realPath)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
*linksWalked++
|
||||
return newpath, true, nil
|
||||
}
|
||||
|
||||
func walkLinks(root, path string, linksWalked *int) (string, error) {
|
||||
switch dir, file := filepath.Split(path); {
|
||||
case dir == "":
|
||||
newpath, _, err := walkLink(root, file, linksWalked)
|
||||
return newpath, err
|
||||
case file == "":
|
||||
if os.IsPathSeparator(dir[len(dir)-1]) {
|
||||
if dir == "/" {
|
||||
return dir, nil
|
||||
}
|
||||
return walkLinks(root, dir[:len(dir)-1], linksWalked)
|
||||
}
|
||||
newpath, _, err := walkLink(root, dir, linksWalked)
|
||||
return newpath, err
|
||||
default:
|
||||
newdir, err := walkLinks(root, dir, linksWalked)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
newpath, islink, err := walkLink(root, filepath.Join(newdir, file), linksWalked)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !islink {
|
||||
return newpath, nil
|
||||
}
|
||||
if filepath.IsAbs(newpath) {
|
||||
return newpath, nil
|
||||
}
|
||||
return filepath.Join(newdir, newpath), nil
|
||||
}
|
||||
}
|
44
vendor/github.com/containerd/continuity/fs/stat_bsd.go
generated
vendored
Normal file
44
vendor/github.com/containerd/continuity/fs/stat_bsd.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// +build darwin freebsd
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatAtime returns the access time from a stat struct
|
||||
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Atimespec
|
||||
}
|
||||
|
||||
// StatCtime returns the created time from a stat struct
|
||||
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Ctimespec
|
||||
}
|
||||
|
||||
// StatMtime returns the modified time from a stat struct
|
||||
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Mtimespec
|
||||
}
|
||||
|
||||
// StatATimeAsTime returns the access time as a time.Time
|
||||
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
|
||||
return time.Unix(int64(st.Atimespec.Sec), int64(st.Atimespec.Nsec)) // nolint: unconvert
|
||||
}
|
43
vendor/github.com/containerd/continuity/fs/stat_linux.go
generated
vendored
Normal file
43
vendor/github.com/containerd/continuity/fs/stat_linux.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatAtime returns the Atim
|
||||
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Atim
|
||||
}
|
||||
|
||||
// StatCtime returns the Ctim
|
||||
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Ctim
|
||||
}
|
||||
|
||||
// StatMtime returns the Mtim
|
||||
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Mtim
|
||||
}
|
||||
|
||||
// StatATimeAsTime returns st.Atim as a time.Time
|
||||
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
|
||||
// The int64 conversions ensure the line compiles for 32-bit systems as well.
|
||||
return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert
|
||||
}
|
29
vendor/github.com/containerd/continuity/fs/time.go
generated
vendored
Normal file
29
vendor/github.com/containerd/continuity/fs/time.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package fs
|
||||
|
||||
import "time"
|
||||
|
||||
// Gnu tar and the go tar writer don't have sub-second mtime
|
||||
// precision, which is problematic when we apply changes via tar
|
||||
// files, we handle this by comparing for exact times, *or* same
|
||||
// second count and either a or b having exactly 0 nanoseconds
|
||||
func sameFsTime(a, b time.Time) bool {
|
||||
return a == b ||
|
||||
(a.Unix() == b.Unix() &&
|
||||
(a.Nanosecond() == 0 || b.Nanosecond() == 0))
|
||||
}
|
101
vendor/github.com/containerd/continuity/pathdriver/path_driver.go
generated
vendored
101
vendor/github.com/containerd/continuity/pathdriver/path_driver.go
generated
vendored
@ -1,101 +0,0 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package pathdriver
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// PathDriver provides all of the path manipulation functions in a common
|
||||
// interface. The context should call these and never use the `filepath`
|
||||
// package or any other package to manipulate paths.
|
||||
type PathDriver interface {
|
||||
Join(paths ...string) string
|
||||
IsAbs(path string) bool
|
||||
Rel(base, target string) (string, error)
|
||||
Base(path string) string
|
||||
Dir(path string) string
|
||||
Clean(path string) string
|
||||
Split(path string) (dir, file string)
|
||||
Separator() byte
|
||||
Abs(path string) (string, error)
|
||||
Walk(string, filepath.WalkFunc) error
|
||||
FromSlash(path string) string
|
||||
ToSlash(path string) string
|
||||
Match(pattern, name string) (matched bool, err error)
|
||||
}
|
||||
|
||||
// pathDriver is a simple default implementation calls the filepath package.
|
||||
type pathDriver struct{}
|
||||
|
||||
// LocalPathDriver is the exported pathDriver struct for convenience.
|
||||
var LocalPathDriver PathDriver = &pathDriver{}
|
||||
|
||||
func (*pathDriver) Join(paths ...string) string {
|
||||
return filepath.Join(paths...)
|
||||
}
|
||||
|
||||
func (*pathDriver) IsAbs(path string) bool {
|
||||
return filepath.IsAbs(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Rel(base, target string) (string, error) {
|
||||
return filepath.Rel(base, target)
|
||||
}
|
||||
|
||||
func (*pathDriver) Base(path string) string {
|
||||
return filepath.Base(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Dir(path string) string {
|
||||
return filepath.Dir(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Clean(path string) string {
|
||||
return filepath.Clean(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Split(path string) (dir, file string) {
|
||||
return filepath.Split(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Separator() byte {
|
||||
return filepath.Separator
|
||||
}
|
||||
|
||||
func (*pathDriver) Abs(path string) (string, error) {
|
||||
return filepath.Abs(path)
|
||||
}
|
||||
|
||||
// Note that filepath.Walk calls os.Stat, so if the context wants to
|
||||
// to call Driver.Stat() for Walk, they need to create a new struct that
|
||||
// overrides this method.
|
||||
func (*pathDriver) Walk(root string, walkFn filepath.WalkFunc) error {
|
||||
return filepath.Walk(root, walkFn)
|
||||
}
|
||||
|
||||
func (*pathDriver) FromSlash(path string) string {
|
||||
return filepath.FromSlash(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) ToSlash(path string) string {
|
||||
return filepath.ToSlash(path)
|
||||
}
|
||||
|
||||
func (*pathDriver) Match(pattern, name string) (bool, error) {
|
||||
return filepath.Match(pattern, name)
|
||||
}
|
26
vendor/github.com/containerd/continuity/syscallx/syscall_unix.go
generated
vendored
Normal file
26
vendor/github.com/containerd/continuity/syscallx/syscall_unix.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package syscallx
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Readlink returns the destination of the named symbolic link.
|
||||
func Readlink(path string, buf []byte) (n int, err error) {
|
||||
return syscall.Readlink(path, buf)
|
||||
}
|
112
vendor/github.com/containerd/continuity/syscallx/syscall_windows.go
generated
vendored
Normal file
112
vendor/github.com/containerd/continuity/syscallx/syscall_windows.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package syscallx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type reparseDataBuffer struct {
|
||||
ReparseTag uint32
|
||||
ReparseDataLength uint16
|
||||
Reserved uint16
|
||||
|
||||
// GenericReparseBuffer
|
||||
reparseBuffer byte
|
||||
}
|
||||
|
||||
type mountPointReparseBuffer struct {
|
||||
SubstituteNameOffset uint16
|
||||
SubstituteNameLength uint16
|
||||
PrintNameOffset uint16
|
||||
PrintNameLength uint16
|
||||
PathBuffer [1]uint16
|
||||
}
|
||||
|
||||
type symbolicLinkReparseBuffer struct {
|
||||
SubstituteNameOffset uint16
|
||||
SubstituteNameLength uint16
|
||||
PrintNameOffset uint16
|
||||
PrintNameLength uint16
|
||||
Flags uint32
|
||||
PathBuffer [1]uint16
|
||||
}
|
||||
|
||||
const (
|
||||
_IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
|
||||
_SYMLINK_FLAG_RELATIVE = 1
|
||||
)
|
||||
|
||||
// Readlink returns the destination of the named symbolic link.
|
||||
func Readlink(path string, buf []byte) (n int, err error) {
|
||||
fd, err := syscall.CreateFile(syscall.StringToUTF16Ptr(path), syscall.GENERIC_READ, 0, nil, syscall.OPEN_EXISTING,
|
||||
syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
defer syscall.CloseHandle(fd)
|
||||
|
||||
rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
|
||||
var bytesReturned uint32
|
||||
err = syscall.DeviceIoControl(fd, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
|
||||
var s string
|
||||
switch rdb.ReparseTag {
|
||||
case syscall.IO_REPARSE_TAG_SYMLINK:
|
||||
data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
|
||||
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
|
||||
s = syscall.UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
|
||||
if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
|
||||
if len(s) >= 4 && s[:4] == `\??\` {
|
||||
s = s[4:]
|
||||
switch {
|
||||
case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
|
||||
// do nothing
|
||||
case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
|
||||
s = `\\` + s[4:]
|
||||
default:
|
||||
// unexpected; do nothing
|
||||
}
|
||||
} else {
|
||||
// unexpected; do nothing
|
||||
}
|
||||
}
|
||||
case _IO_REPARSE_TAG_MOUNT_POINT:
|
||||
data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
|
||||
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
|
||||
s = syscall.UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
|
||||
if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar
|
||||
if len(s) < 48 || s[:11] != `\??\Volume{` {
|
||||
s = s[4:]
|
||||
}
|
||||
} else {
|
||||
// unexpected; do nothing
|
||||
}
|
||||
default:
|
||||
// the path is not a symlink or junction but another type of reparse
|
||||
// point
|
||||
return -1, syscall.ENOENT
|
||||
}
|
||||
n = copy(buf, []byte(s))
|
||||
|
||||
return n, nil
|
||||
}
|
3
vendor/github.com/containerd/continuity/sysx/README.md
generated
vendored
Normal file
3
vendor/github.com/containerd/continuity/sysx/README.md
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
This package is for internal use only. It is intended to only have
|
||||
temporary changes before they are upstreamed to golang.org/x/sys/
|
||||
(a.k.a. https://github.com/golang/sys).
|
128
vendor/github.com/containerd/continuity/sysx/file_posix.go
generated
vendored
Normal file
128
vendor/github.com/containerd/continuity/sysx/file_posix.go
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containerd/continuity/syscallx"
|
||||
)
|
||||
|
||||
// Readlink returns the destination of the named symbolic link.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func Readlink(name string) (string, error) {
|
||||
for len := 128; ; len *= 2 {
|
||||
b := make([]byte, len)
|
||||
n, e := fixCount(syscallx.Readlink(fixLongPath(name), b))
|
||||
if e != nil {
|
||||
return "", &os.PathError{Op: "readlink", Path: name, Err: e}
|
||||
}
|
||||
if n < len {
|
||||
return string(b[0:n]), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Many functions in package syscall return a count of -1 instead of 0.
|
||||
// Using fixCount(call()) instead of call() corrects the count.
|
||||
func fixCount(n int, err error) (int, error) {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// fixLongPath returns the extended-length (\\?\-prefixed) form of
|
||||
// path when needed, in order to avoid the default 260 character file
|
||||
// path limit imposed by Windows. If path is not easily converted to
|
||||
// the extended-length form (for example, if path is a relative path
|
||||
// or contains .. elements), or is short enough, fixLongPath returns
|
||||
// path unmodified.
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
|
||||
func fixLongPath(path string) string {
|
||||
// Do nothing (and don't allocate) if the path is "short".
|
||||
// Empirically (at least on the Windows Server 2013 builder),
|
||||
// the kernel is arbitrarily okay with < 248 bytes. That
|
||||
// matches what the docs above say:
|
||||
// "When using an API to create a directory, the specified
|
||||
// path cannot be so long that you cannot append an 8.3 file
|
||||
// name (that is, the directory name cannot exceed MAX_PATH
|
||||
// minus 12)." Since MAX_PATH is 260, 260 - 12 = 248.
|
||||
//
|
||||
// The MSDN docs appear to say that a normal path that is 248 bytes long
|
||||
// will work; empirically the path must be less then 248 bytes long.
|
||||
if len(path) < 248 {
|
||||
// Don't fix. (This is how Go 1.7 and earlier worked,
|
||||
// not automatically generating the \\?\ form)
|
||||
return path
|
||||
}
|
||||
|
||||
// The extended form begins with \\?\, as in
|
||||
// \\?\c:\windows\foo.txt or \\?\UNC\server\share\foo.txt.
|
||||
// The extended form disables evaluation of . and .. path
|
||||
// elements and disables the interpretation of / as equivalent
|
||||
// to \. The conversion here rewrites / to \ and elides
|
||||
// . elements as well as trailing or duplicate separators. For
|
||||
// simplicity it avoids the conversion entirely for relative
|
||||
// paths or paths containing .. elements. For now,
|
||||
// \\server\share paths are not converted to
|
||||
// \\?\UNC\server\share paths because the rules for doing so
|
||||
// are less well-specified.
|
||||
if len(path) >= 2 && path[:2] == `\\` {
|
||||
// Don't canonicalize UNC paths.
|
||||
return path
|
||||
}
|
||||
if !filepath.IsAbs(path) {
|
||||
// Relative path
|
||||
return path
|
||||
}
|
||||
|
||||
const prefix = `\\?`
|
||||
|
||||
pathbuf := make([]byte, len(prefix)+len(path)+len(`\`))
|
||||
copy(pathbuf, prefix)
|
||||
n := len(path)
|
||||
r, w := 0, len(prefix)
|
||||
for r < n {
|
||||
switch {
|
||||
case os.IsPathSeparator(path[r]):
|
||||
// empty block
|
||||
r++
|
||||
case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
|
||||
// /./
|
||||
r++
|
||||
case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
|
||||
// /../ is currently unhandled
|
||||
return path
|
||||
default:
|
||||
pathbuf[w] = '\\'
|
||||
w++
|
||||
for ; r < n && !os.IsPathSeparator(path[r]); r++ {
|
||||
pathbuf[w] = path[r]
|
||||
w++
|
||||
}
|
||||
}
|
||||
}
|
||||
// A drive's root directory needs a trailing \
|
||||
if w == len(`\\?\c:`) {
|
||||
pathbuf[w] = '\\'
|
||||
w++
|
||||
}
|
||||
return string(pathbuf[:w])
|
||||
}
|
52
vendor/github.com/containerd/continuity/sysx/generate.sh
generated
vendored
Normal file
52
vendor/github.com/containerd/continuity/sysx/generate.sh
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright The containerd Authors.
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
mksyscall="$(go env GOROOT)/src/syscall/mksyscall.pl"
|
||||
|
||||
fix() {
|
||||
sed 's,^package syscall$,package sysx,' \
|
||||
| sed 's,^import "unsafe"$,import (\n\t"syscall"\n\t"unsafe"\n),' \
|
||||
| gofmt -r='BytePtrFromString -> syscall.BytePtrFromString' \
|
||||
| gofmt -r='Syscall6 -> syscall.Syscall6' \
|
||||
| gofmt -r='Syscall -> syscall.Syscall' \
|
||||
| gofmt -r='SYS_GETXATTR -> syscall.SYS_GETXATTR' \
|
||||
| gofmt -r='SYS_LISTXATTR -> syscall.SYS_LISTXATTR' \
|
||||
| gofmt -r='SYS_SETXATTR -> syscall.SYS_SETXATTR' \
|
||||
| gofmt -r='SYS_REMOVEXATTR -> syscall.SYS_REMOVEXATTR' \
|
||||
| gofmt -r='SYS_LGETXATTR -> syscall.SYS_LGETXATTR' \
|
||||
| gofmt -r='SYS_LLISTXATTR -> syscall.SYS_LLISTXATTR' \
|
||||
| gofmt -r='SYS_LSETXATTR -> syscall.SYS_LSETXATTR' \
|
||||
| gofmt -r='SYS_LREMOVEXATTR -> syscall.SYS_LREMOVEXATTR'
|
||||
}
|
||||
|
||||
if [ "$GOARCH" == "" ] || [ "$GOOS" == "" ]; then
|
||||
echo "Must specify \$GOARCH and \$GOOS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkargs=""
|
||||
|
||||
if [ "$GOARCH" == "386" ] || [ "$GOARCH" == "arm" ]; then
|
||||
mkargs="-l32"
|
||||
fi
|
||||
|
||||
for f in "$@"; do
|
||||
$mksyscall $mkargs "${f}_${GOOS}.go" | fix > "${f}_${GOOS}_${GOARCH}.go"
|
||||
done
|
||||
|
23
vendor/github.com/containerd/continuity/sysx/nodata_linux.go
generated
vendored
Normal file
23
vendor/github.com/containerd/continuity/sysx/nodata_linux.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const ENODATA = syscall.ENODATA
|
24
vendor/github.com/containerd/continuity/sysx/nodata_solaris.go
generated
vendored
Normal file
24
vendor/github.com/containerd/continuity/sysx/nodata_solaris.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// This should actually be a set that contains ENOENT and EPERM
|
||||
const ENODATA = syscall.ENOENT
|
25
vendor/github.com/containerd/continuity/sysx/nodata_unix.go
generated
vendored
Normal file
25
vendor/github.com/containerd/continuity/sysx/nodata_unix.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// +build darwin freebsd
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const ENODATA = syscall.ENOATTR
|
125
vendor/github.com/containerd/continuity/sysx/xattr.go
generated
vendored
Normal file
125
vendor/github.com/containerd/continuity/sysx/xattr.go
generated
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
// +build linux darwin
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Listxattr calls syscall listxattr and reads all content
|
||||
// and returns a string array
|
||||
func Listxattr(path string) ([]string, error) {
|
||||
return listxattrAll(path, unix.Listxattr)
|
||||
}
|
||||
|
||||
// Removexattr calls syscall removexattr
|
||||
func Removexattr(path string, attr string) (err error) {
|
||||
return unix.Removexattr(path, attr)
|
||||
}
|
||||
|
||||
// Setxattr calls syscall setxattr
|
||||
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
return unix.Setxattr(path, attr, data, flags)
|
||||
}
|
||||
|
||||
// Getxattr calls syscall getxattr
|
||||
func Getxattr(path, attr string) ([]byte, error) {
|
||||
return getxattrAll(path, attr, unix.Getxattr)
|
||||
}
|
||||
|
||||
// LListxattr lists xattrs, not following symlinks
|
||||
func LListxattr(path string) ([]string, error) {
|
||||
return listxattrAll(path, unix.Llistxattr)
|
||||
}
|
||||
|
||||
// LRemovexattr removes an xattr, not following symlinks
|
||||
func LRemovexattr(path string, attr string) (err error) {
|
||||
return unix.Lremovexattr(path, attr)
|
||||
}
|
||||
|
||||
// LSetxattr sets an xattr, not following symlinks
|
||||
func LSetxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
return unix.Lsetxattr(path, attr, data, flags)
|
||||
}
|
||||
|
||||
// LGetxattr gets an xattr, not following symlinks
|
||||
func LGetxattr(path, attr string) ([]byte, error) {
|
||||
return getxattrAll(path, attr, unix.Lgetxattr)
|
||||
}
|
||||
|
||||
const defaultXattrBufferSize = 5
|
||||
|
||||
type listxattrFunc func(path string, dest []byte) (int, error)
|
||||
|
||||
func listxattrAll(path string, listFunc listxattrFunc) ([]string, error) {
|
||||
var p []byte // nil on first execution
|
||||
|
||||
for {
|
||||
n, err := listFunc(path, p) // first call gets buffer size.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n > len(p) {
|
||||
p = make([]byte, n)
|
||||
continue
|
||||
}
|
||||
|
||||
p = p[:n]
|
||||
|
||||
ps := bytes.Split(bytes.TrimSuffix(p, []byte{0}), []byte{0})
|
||||
var entries []string
|
||||
for _, p := range ps {
|
||||
s := string(p)
|
||||
if s != "" {
|
||||
entries = append(entries, s)
|
||||
}
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
}
|
||||
|
||||
type getxattrFunc func(string, string, []byte) (int, error)
|
||||
|
||||
func getxattrAll(path, attr string, getFunc getxattrFunc) ([]byte, error) {
|
||||
p := make([]byte, defaultXattrBufferSize)
|
||||
for {
|
||||
n, err := getFunc(path, attr, p)
|
||||
if err != nil {
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERANGE {
|
||||
p = make([]byte, len(p)*2) // this can't be ideal.
|
||||
continue // try again!
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// realloc to correct size and repeat
|
||||
if n > len(p) {
|
||||
p = make([]byte, n)
|
||||
continue
|
||||
}
|
||||
|
||||
return p[:n], nil
|
||||
}
|
||||
}
|
67
vendor/github.com/containerd/continuity/sysx/xattr_unsupported.go
generated
vendored
Normal file
67
vendor/github.com/containerd/continuity/sysx/xattr_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// +build !linux,!darwin
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package sysx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var unsupported = errors.New("extended attributes unsupported on " + runtime.GOOS)
|
||||
|
||||
// Listxattr calls syscall listxattr and reads all content
|
||||
// and returns a string array
|
||||
func Listxattr(path string) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
// Removexattr calls syscall removexattr
|
||||
func Removexattr(path string, attr string) (err error) {
|
||||
return unsupported
|
||||
}
|
||||
|
||||
// Setxattr calls syscall setxattr
|
||||
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
return unsupported
|
||||
}
|
||||
|
||||
// Getxattr calls syscall getxattr
|
||||
func Getxattr(path, attr string) ([]byte, error) {
|
||||
return []byte{}, unsupported
|
||||
}
|
||||
|
||||
// LListxattr lists xattrs, not following symlinks
|
||||
func LListxattr(path string) ([]string, error) {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
// LRemovexattr removes an xattr, not following symlinks
|
||||
func LRemovexattr(path string, attr string) (err error) {
|
||||
return unsupported
|
||||
}
|
||||
|
||||
// LSetxattr sets an xattr, not following symlinks
|
||||
func LSetxattr(path string, attr string, data []byte, flags int) (err error) {
|
||||
return unsupported
|
||||
}
|
||||
|
||||
// LGetxattr gets an xattr, not following symlinks
|
||||
func LGetxattr(path, attr string) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
}
|
26
vendor/github.com/containers/buildah/CHANGELOG.md
generated
vendored
26
vendor/github.com/containers/buildah/CHANGELOG.md
generated
vendored
@ -2,6 +2,32 @@
|
||||
|
||||
# Changelog
|
||||
|
||||
## v1.11.3 (2019-10-04)
|
||||
Update c/image to v4.0.1
|
||||
Bump github.com/spf13/pflag from 1.0.3 to 1.0.5
|
||||
Fix --build-args handling
|
||||
Bump github.com/spf13/cobra from 0.0.3 to 0.0.5
|
||||
Bump github.com/cyphar/filepath-securejoin from 0.2.1 to 0.2.2
|
||||
Bump github.com/onsi/ginkgo from 1.8.0 to 1.10.1
|
||||
Bump github.com/fsouza/go-dockerclient from 1.3.0 to 1.4.4
|
||||
Add support for retrieving context from stdin "-"
|
||||
Ensure bud remote context cleans up on error
|
||||
info: add cgroups2
|
||||
Bump github.com/seccomp/libseccomp-golang from 0.9.0 to 0.9.1
|
||||
Bump github.com/mattn/go-shellwords from 1.0.5 to 1.0.6
|
||||
Bump github.com/stretchr/testify from 1.3.0 to 1.4.0
|
||||
Bump github.com/opencontainers/selinux from 1.2.2 to 1.3.0
|
||||
Bump github.com/etcd-io/bbolt from 1.3.2 to 1.3.3
|
||||
Bump github.com/onsi/gomega from 1.5.0 to 1.7.0
|
||||
update c/storage to v1.13.4
|
||||
Print build 'STEP' line to stdout, not stderr
|
||||
Fix travis-ci on forks
|
||||
Vendor c/storage v1.13.3
|
||||
Use Containerfile by default
|
||||
Added tutorial on how to include Buildah as library
|
||||
util/util: Fix "configuraitno" -> "configuration" log typo
|
||||
Bump back to v1.12.0-dev
|
||||
|
||||
## v1.11.2 (2019-09-13)
|
||||
Add some cleanup code
|
||||
Move devices code to unit specific directory.
|
||||
|
22
vendor/github.com/containers/buildah/OWNERS
generated
vendored
Normal file
22
vendor/github.com/containers/buildah/OWNERS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
approvers:
|
||||
- TomSweeneyRedHat
|
||||
- cevich
|
||||
- giuseppe
|
||||
- nalind
|
||||
- rhatdan
|
||||
- vrothberg
|
||||
reviewers:
|
||||
- QiWang19
|
||||
- TomSweeneyRedHat
|
||||
- baude
|
||||
- cevich
|
||||
- edsantiago
|
||||
- giuseppe
|
||||
- haircommander
|
||||
- jwhonce
|
||||
- mheon
|
||||
- mrunalp
|
||||
- nalind
|
||||
- rhatdan
|
||||
- umohnani8
|
||||
- vrothberg
|
4
vendor/github.com/containers/buildah/buildah.go
generated
vendored
4
vendor/github.com/containers/buildah/buildah.go
generated
vendored
@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
@ -27,7 +27,7 @@ const (
|
||||
Package = "buildah"
|
||||
// Version for the Package. Bump version in contrib/rpm/buildah.spec
|
||||
// too.
|
||||
Version = "1.11.3"
|
||||
Version = "1.11.4"
|
||||
// The value we use to identify what type of information, currently a
|
||||
// serialized Builder structure, we are using as per-container state.
|
||||
// This should only be changed when we make incompatible changes to
|
||||
|
22
vendor/github.com/containers/buildah/changelog.txt
generated
vendored
22
vendor/github.com/containers/buildah/changelog.txt
generated
vendored
@ -1,3 +1,25 @@
|
||||
- Changelog for v1.11.4 (2019-10-28)
|
||||
* buildah: add a "manifest" command
|
||||
* manifests: add the module
|
||||
* pkg/supplemented: add a package for grouping images together
|
||||
* pkg/manifests: add a manifest list build/manipulation API
|
||||
* Update for ErrUnauthorizedForCredentials API change in containers/image
|
||||
* Update for manifest-lists API changes in containers/image
|
||||
* version: also note the version of containers/image
|
||||
* Move to containers/image v5.0.0
|
||||
* Enable --device directory as src device
|
||||
* Fix git build with branch specified
|
||||
* Bump github.com/openshift/imagebuilder from 1.1.0 to 1.1.1
|
||||
* Bump github.com/fsouza/go-dockerclient from 1.4.4 to 1.5.0
|
||||
* Add clarification to the Tutorial for new users
|
||||
* Silence "using cache" to ensure -q is fully quiet
|
||||
* Add OWNERS File to Buildah
|
||||
* Bump github.com/containers/storage from 1.13.4 to 1.13.5
|
||||
* Move runtime flag to bud from common
|
||||
* Commit: check for storage.ErrImageUnknown using errors.Cause()
|
||||
* Fix crash when invalid COPY --from flag is specified.
|
||||
* Bump back to v1.12.0-dev
|
||||
|
||||
- Changelog for v1.11.3 (2019-10-04)
|
||||
* Update c/image to v4.0.1
|
||||
* Bump github.com/spf13/pflag from 1.0.3 to 1.0.5
|
||||
|
20
vendor/github.com/containers/buildah/commit.go
generated
vendored
20
vendor/github.com/containers/buildah/commit.go
generated
vendored
@ -12,14 +12,14 @@ import (
|
||||
|
||||
"github.com/containers/buildah/pkg/blobcache"
|
||||
"github.com/containers/buildah/util"
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/docker"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/signature"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/signature"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
@ -96,7 +96,7 @@ type PushOptions struct {
|
||||
// github.com/containers/image/types SystemContext to hold credentials
|
||||
// and other authentication/authorization information.
|
||||
SystemContext *types.SystemContext
|
||||
// ManifestType is the format to use when saving the imge using the 'dir' transport
|
||||
// ManifestType is the format to use when saving the image using the 'dir' transport
|
||||
// possible options are oci, v2s1, and v2s2
|
||||
ManifestType string
|
||||
// BlobDirectory is the name of a directory in which we'll look for
|
||||
@ -309,7 +309,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
||||
}
|
||||
|
||||
img, err := is.Transport.GetStoreImage(b.store, dest)
|
||||
if err != nil && err != storage.ErrImageUnknown {
|
||||
if err != nil && errors.Cause(err) != storage.ErrImageUnknown {
|
||||
return imgID, nil, "", errors.Wrapf(err, "error locating image %q in local storage", transports.ImageName(dest))
|
||||
}
|
||||
if err == nil {
|
||||
|
4
vendor/github.com/containers/buildah/common.go
generated
vendored
4
vendor/github.com/containers/buildah/common.go
generated
vendored
@ -6,8 +6,8 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/buildah/pkg/unshare"
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
)
|
||||
|
||||
|
6
vendor/github.com/containers/buildah/config.go
generated
vendored
6
vendor/github.com/containers/buildah/config.go
generated
vendored
@ -8,9 +8,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
|
2
vendor/github.com/containers/buildah/docker/types.go
generated
vendored
2
vendor/github.com/containers/buildah/docker/types.go
generated
vendored
@ -7,7 +7,7 @@ package docker
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/pkg/strslice"
|
||||
"github.com/containers/image/v5/pkg/strslice"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
|
10
vendor/github.com/containers/buildah/go.mod
generated
vendored
10
vendor/github.com/containers/buildah/go.mod
generated
vendored
@ -5,8 +5,8 @@ go 1.12
|
||||
require (
|
||||
github.com/blang/semver v3.5.0+incompatible // indirect
|
||||
github.com/containernetworking/cni v0.7.1
|
||||
github.com/containers/image/v4 v4.0.1
|
||||
github.com/containers/storage v1.13.4
|
||||
github.com/containers/image/v5 v5.0.0
|
||||
github.com/containers/storage v1.13.5
|
||||
github.com/cyphar/filepath-securejoin v0.2.2
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/docker-credential-helpers v0.6.1 // indirect
|
||||
@ -14,7 +14,7 @@ require (
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20190625141545-5a177b73e316
|
||||
github.com/etcd-io/bbolt v1.3.3
|
||||
github.com/fsouza/go-dockerclient v1.4.4
|
||||
github.com/fsouza/go-dockerclient v1.5.0
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/imdario/mergo v0.3.6 // indirect
|
||||
@ -30,7 +30,7 @@ require (
|
||||
github.com/opencontainers/runtime-tools v0.9.0
|
||||
github.com/opencontainers/selinux v1.3.0
|
||||
github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible
|
||||
github.com/openshift/imagebuilder v1.1.0
|
||||
github.com/openshift/imagebuilder v1.1.1
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/seccomp/containers-golang v0.0.0-20180629143253-cdfdaa7543f4
|
||||
github.com/seccomp/libseccomp-golang v0.9.1
|
||||
@ -42,7 +42,7 @@ require (
|
||||
github.com/vishvananda/netlink v1.0.0 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.1.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad
|
||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13
|
||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
|
||||
google.golang.org/grpc v1.24.0 // indirect
|
||||
|
29
vendor/github.com/containers/buildah/go.sum
generated
vendored
29
vendor/github.com/containers/buildah/go.sum
generated
vendored
@ -28,21 +28,23 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/containerd/containerd v1.3.0 h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20180216233310-d8fb8589b0e8/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882bXEDKfWIf0wa8HRvpnBoPszJJXL+TVbBw4M=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/containers/image v3.0.2+incompatible h1:B1lqAE8MUPCrsBLE86J0gnXleeRq8zJnQryhiiGQNyE=
|
||||
github.com/containers/image v3.0.2+incompatible/go.mod h1:8Vtij257IWSanUQKe1tAeNOm2sRVkSqQTVQ1IlwI3+M=
|
||||
github.com/containers/image v4.0.0+incompatible h1:CfKbemfowbIg3nhq8rvtI+sdU9QbvODkiD+JLpOJMiQ=
|
||||
github.com/containers/image v4.0.0+incompatible/go.mod h1:Td6tqqQu0miIBO8mauyzsVqBbv5WhKSE4pH2ZwslVp0=
|
||||
github.com/containers/image/v4 v4.0.1 h1:idNGHChj0Pyv3vLrxul2oSVMZLeFqpoq3CjLeVgapSQ=
|
||||
github.com/containers/image/v4 v4.0.1/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
|
||||
github.com/containers/image/v5 v5.0.0 h1:arnXgbt1ucsC/ndtSpiQY87rA0UjhF+/xQnPzqdBDn4=
|
||||
github.com/containers/image/v5 v5.0.0/go.mod h1:MgiLzCfIeo8lrHi+4Lb8HP+rh513sm0Mlk6RrhjFOLY=
|
||||
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
|
||||
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
|
||||
github.com/containers/storage v1.13.4/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
|
||||
github.com/containers/storage v1.13.5 h1:/SUzGeOP2HDijpF7Yur21Ch6WTZC1BNeZF917CWcp5c=
|
||||
github.com/containers/storage v1.13.5/go.mod h1:HELz8Sn+UVbPaUZMI8RvIG9doD4y4z6Gtg4k7xdd2ZY=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@ -60,6 +62,8 @@ github.com/docker/docker v0.0.0-20171019062838-86f080cff091/go.mod h1:eEKB0N0r5N
|
||||
github.com/docker/docker v0.0.0-20180522102801-da99009bbb11/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b h1:+Ga+YpCDpcY1fln6GI0fiiirpqHGcob5/Vk3oKNuGdU=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce h1:H3csZuxZESJeeEiOxq4YXPNmLFbjl7u2qVBrAAGX/sA=
|
||||
github.com/docker/docker v1.4.2-0.20190927142053-ada3c14355ce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/docker-credential-helpers v0.6.1 h1:Dq4iIfcM7cNtddhLVWe9h4QDjsi4OER3Z8voPu/I52g=
|
||||
github.com/docker/docker-credential-helpers v0.6.1/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
@ -84,6 +88,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsouza/go-dockerclient v1.4.4 h1:Sd5nD4wdAgiPxvrbYUzT2ZZNmPk3z+GGnZ+frvw8z04=
|
||||
github.com/fsouza/go-dockerclient v1.4.4/go.mod h1:PrwszSL5fbmsESocROrOGq/NULMXRw+bajY0ltzD6MA=
|
||||
github.com/fsouza/go-dockerclient v1.5.0 h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVfseKyxbA=
|
||||
github.com/fsouza/go-dockerclient v1.5.0/go.mod h1:AqZZK/zFO3phxYxlTsAaeAMSdQ9mgHuhy+bjN034Qds=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
@ -101,6 +107,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@ -190,16 +197,11 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c h1:xa+eQWKuJ9MbB9FBL/eoNvDFvveAkz2LQoz8PzX7Q/4=
|
||||
github.com/mtrmac/gpgme v0.0.0-20170102180018-b2432428689c/go.mod h1:GhAqVMEWnTcW2dxoD/SO3n2enrgWl3y6Dnx4m59GvcA=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191001213151-121ffca6db69 h1:TVWS7od6UeGhdYqgXn/+EIDlulkGGV+r6FnjoxRJAl0=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191001213151-121ffca6db69/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191002203927-a64d9d2717f4 h1:AE5cilZfrGtAgMg5Ed4c2Y2KczlOsMVZAK055sSq+gc=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191002203927-a64d9d2717f4/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191003181245-f4c983e93262 h1:HMUEnWU3OPT09JRFQLn8VTp3GfdfiEhDMAEhkdX8QnA=
|
||||
github.com/mtrmac/image/v4 v4.0.0-20191003181245-f4c983e93262/go.mod h1:0ASJH1YgJiX/eqFZObqepgsvIA4XjCgpyfwn9pDGafA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
@ -238,6 +240,8 @@ github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible h1:s5
|
||||
github.com/openshift/api v3.9.1-0.20190810003144-27fb16909b15+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
|
||||
github.com/openshift/imagebuilder v1.1.0 h1:oT704SkwMEzmIMU/+Uv1Wmvt+p10q3v2WuYMeFI18c4=
|
||||
github.com/openshift/imagebuilder v1.1.0/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||
github.com/openshift/imagebuilder v1.1.1 h1:KAUR31p8UBJdfVO42azWgb+LeMAed2zaKQ19e0C0X2I=
|
||||
github.com/openshift/imagebuilder v1.1.1/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
@ -299,8 +303,6 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG
|
||||
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
|
||||
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
|
||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
|
||||
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
|
||||
@ -329,6 +331,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90Pveol
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ=
|
||||
golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -390,6 +394,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
12
vendor/github.com/containers/buildah/image.go
generated
vendored
12
vendor/github.com/containers/buildah/image.go
generated
vendored
@ -13,11 +13,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/image"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/image"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
@ -596,7 +596,7 @@ func (i *containerImageSource) GetManifest(ctx context.Context, instanceDigest *
|
||||
return i.manifest, i.manifestType, nil
|
||||
}
|
||||
|
||||
func (i *containerImageSource) LayerInfosForCopy(ctx context.Context) ([]types.BlobInfo, error) {
|
||||
func (i *containerImageSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
4
vendor/github.com/containers/buildah/imagebuildah/build.go
generated
vendored
@ -13,8 +13,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
|
10
vendor/github.com/containers/buildah/imagebuildah/executor.go
generated
vendored
10
vendor/github.com/containers/buildah/imagebuildah/executor.go
generated
vendored
@ -12,11 +12,11 @@ import (
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
23
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
23
vendor/github.com/containers/buildah/imagebuildah/stage_executor.go
generated
vendored
@ -13,12 +13,12 @@ import (
|
||||
"github.com/containers/buildah"
|
||||
buildahdocker "github.com/containers/buildah/docker"
|
||||
"github.com/containers/buildah/util"
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
securejoin "github.com/cyphar/filepath-securejoin"
|
||||
@ -759,6 +759,12 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
|
||||
s.executor.log(commitMessage)
|
||||
}
|
||||
}
|
||||
logCacheHit := func(cacheID string) {
|
||||
if !s.executor.quiet {
|
||||
cacheHitMessage := "--> Using cache"
|
||||
fmt.Fprintf(s.executor.out, "%s %s\n", cacheHitMessage, cacheID)
|
||||
}
|
||||
}
|
||||
logImageID := func(imgID string) {
|
||||
if s.executor.iidfile == "" {
|
||||
fmt.Fprintf(s.executor.out, "%s\n", imgID)
|
||||
@ -816,6 +822,9 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
|
||||
if strings.Contains(n, "--from") && (command == "COPY" || command == "ADD") {
|
||||
var mountPoint string
|
||||
arr := strings.Split(n, "=")
|
||||
if len(arr) != 2 {
|
||||
return "", nil, errors.Errorf("%s: invalid --from flag, should be --from=<name|index>", command)
|
||||
}
|
||||
otherStage, ok := s.executor.stages[arr[1]]
|
||||
if !ok {
|
||||
if mountPoint, err = s.getImageRootfs(ctx, stage, arr[1]); err != nil {
|
||||
@ -906,7 +915,7 @@ func (s *StageExecutor) Execute(ctx context.Context, stage imagebuilder.Stage, b
|
||||
}
|
||||
if cacheID != "" {
|
||||
// Note the cache hit.
|
||||
fmt.Fprintf(s.executor.out, "--> Using cache %s\n", cacheID)
|
||||
logCacheHit(cacheID)
|
||||
} else {
|
||||
// We're not going to find any more cache hits.
|
||||
checkForLayers = false
|
||||
|
11
vendor/github.com/containers/buildah/imagebuildah/util.go
generated
vendored
11
vendor/github.com/containers/buildah/imagebuildah/util.go
generated
vendored
@ -23,8 +23,15 @@ func cloneToDirectory(url, dir string) error {
|
||||
if !strings.HasPrefix(url, "git://") && !strings.HasSuffix(url, ".git") {
|
||||
url = "git://" + url
|
||||
}
|
||||
logrus.Debugf("cloning %q to %q", url, dir)
|
||||
cmd := exec.Command("git", "clone", url, dir)
|
||||
gitBranch := strings.Split(url, "#")
|
||||
var cmd *exec.Cmd
|
||||
if len(gitBranch) < 2 {
|
||||
logrus.Debugf("cloning %q to %q", url, dir)
|
||||
cmd = exec.Command("git", "clone", url, dir)
|
||||
} else {
|
||||
logrus.Debugf("cloning repo %q and branch %q to %q", gitBranch[0], gitBranch[1], dir)
|
||||
cmd = exec.Command("git", "clone", "-b", gitBranch[1], gitBranch[0], dir)
|
||||
}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/containers/buildah/import.go
generated
vendored
6
vendor/github.com/containers/buildah/import.go
generated
vendored
@ -5,9 +5,9 @@ import (
|
||||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
|
12
vendor/github.com/containers/buildah/new.go
generated
vendored
12
vendor/github.com/containers/buildah/new.go
generated
vendored
@ -7,12 +7,12 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/pkg/sysregistriesv2"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/transports/alltransports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/pkg/sysregistriesv2"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/transports/alltransports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/openshift/imagebuilder"
|
||||
"github.com/pkg/errors"
|
||||
|
28
vendor/github.com/containers/buildah/pkg/blobcache/blobcache.go
generated
vendored
28
vendor/github.com/containers/buildah/pkg/blobcache/blobcache.go
generated
vendored
@ -10,11 +10,11 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/containers/buildah/docker"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/image"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/image"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
@ -263,14 +263,14 @@ func (s *blobCacheSource) GetSignatures(ctx context.Context, instanceDigest *dig
|
||||
return s.source.GetSignatures(ctx, instanceDigest)
|
||||
}
|
||||
|
||||
func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context) ([]types.BlobInfo, error) {
|
||||
signatures, err := s.source.GetSignatures(ctx, nil)
|
||||
func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) {
|
||||
signatures, err := s.source.GetSignatures(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error checking if image %q has signatures", transports.ImageName(s.reference))
|
||||
}
|
||||
canReplaceBlobs := !(len(signatures) > 0 && len(signatures[0]) > 0)
|
||||
|
||||
infos, err := s.source.LayerInfosForCopy(ctx)
|
||||
infos, err := s.source.LayerInfosForCopy(ctx, instanceDigest)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting layer infos for copying image %q through cache", transports.ImageName(s.reference))
|
||||
}
|
||||
@ -515,7 +515,7 @@ func (d *blobCacheDestination) TryReusingBlob(ctx context.Context, info types.Bl
|
||||
return false, types.BlobInfo{}, nil
|
||||
}
|
||||
|
||||
func (d *blobCacheDestination) PutManifest(ctx context.Context, manifestBytes []byte) error {
|
||||
func (d *blobCacheDestination) PutManifest(ctx context.Context, manifestBytes []byte, instanceDigest *digest.Digest) error {
|
||||
manifestDigest, err := manifest.Digest(manifestBytes)
|
||||
if err != nil {
|
||||
logrus.Warnf("error digesting manifest %q: %v", string(manifestBytes), err)
|
||||
@ -525,13 +525,13 @@ func (d *blobCacheDestination) PutManifest(ctx context.Context, manifestBytes []
|
||||
logrus.Warnf("error saving manifest as %q: %v", filename, err)
|
||||
}
|
||||
}
|
||||
return d.destination.PutManifest(ctx, manifestBytes)
|
||||
return d.destination.PutManifest(ctx, manifestBytes, instanceDigest)
|
||||
}
|
||||
|
||||
func (d *blobCacheDestination) PutSignatures(ctx context.Context, signatures [][]byte) error {
|
||||
return d.destination.PutSignatures(ctx, signatures)
|
||||
func (d *blobCacheDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error {
|
||||
return d.destination.PutSignatures(ctx, signatures, instanceDigest)
|
||||
}
|
||||
|
||||
func (d *blobCacheDestination) Commit(ctx context.Context) error {
|
||||
return d.destination.Commit(ctx)
|
||||
func (d *blobCacheDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error {
|
||||
return d.destination.Commit(ctx, unparsedToplevel)
|
||||
}
|
||||
|
13
vendor/github.com/containers/buildah/pkg/cli/common.go
generated
vendored
13
vendor/github.com/containers/buildah/pkg/cli/common.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
@ -95,6 +96,8 @@ type FromAndBudResults struct {
|
||||
Isolation string
|
||||
Memory string
|
||||
MemorySwap string
|
||||
OverrideArch string
|
||||
OverrideOS string
|
||||
SecurityOpt []string
|
||||
ShmSize string
|
||||
Ulimit []string
|
||||
@ -161,7 +164,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
|
||||
fs.BoolVar(&flags.PullAlways, "pull-always", false, "pull the image, even if a version is present")
|
||||
fs.BoolVarP(&flags.Quiet, "quiet", "q", false, "refrain from announcing build instructions and image read/write progress")
|
||||
fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build")
|
||||
fs.StringVar(&flags.Runtime, "runtime", util.Runtime(), "`path` to an alternate runtime. Use BUILDAH_RUNTIME environment variable to override.")
|
||||
// "runtime" definition moved to avoid name collision in podman build. Defined in cmd/buildah/bud.go.
|
||||
fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
|
||||
fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
|
||||
fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer.")
|
||||
@ -194,6 +197,14 @@ func GetFromAndBudFlags(flags *FromAndBudResults, usernsResults *UserNSResults,
|
||||
fs.StringVar(&flags.Isolation, "isolation", DefaultIsolation(), "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.")
|
||||
fs.StringVarP(&flags.Memory, "memory", "m", "", "memory limit (format: <number>[<unit>], where unit = b, k, m or g)")
|
||||
fs.StringVar(&flags.MemorySwap, "memory-swap", "", "swap limit equal to memory plus swap: '-1' to enable unlimited swap")
|
||||
fs.StringVar(&flags.OverrideOS, "override-os", runtime.GOOS, "prefer `OS` instead of the running OS when pulling images")
|
||||
if err := fs.MarkHidden("override-os"); err != nil {
|
||||
panic(fmt.Sprintf("error marking override-os as hidden: %v", err))
|
||||
}
|
||||
fs.StringVar(&flags.OverrideArch, "override-arch", runtime.GOARCH, "prefer `ARCH` instead of the architecture of the machine when pulling images")
|
||||
if err := fs.MarkHidden("override-arch"); err != nil {
|
||||
panic(fmt.Sprintf("error marking override-arch as hidden: %v", err))
|
||||
}
|
||||
fs.StringArrayVar(&flags.SecurityOpt, "security-opt", []string{}, "security options (default [])")
|
||||
fs.StringVar(&flags.ShmSize, "shm-size", "65536k", "size of '/dev/shm'. The format is `<number><unit>`.")
|
||||
fs.StringSliceVar(&flags.Ulimit, "ulimit", []string{}, "ulimit options (default [])")
|
||||
|
8
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
8
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
@ -14,7 +14,7 @@ import (
|
||||
"unicode"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
units "github.com/docker/go-units"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -583,6 +583,12 @@ func SystemContextFromOptions(c *cobra.Command) (*types.SystemContext, error) {
|
||||
ctx.RegistriesDirPath = regConfDir
|
||||
}
|
||||
ctx.DockerRegistryUserAgent = fmt.Sprintf("Buildah/%s", buildah.Version)
|
||||
if os, err := c.Flags().GetString("override-os"); err == nil {
|
||||
ctx.OSChoice = os
|
||||
}
|
||||
if arch, err := c.Flags().GetString("override-arch"); err == nil {
|
||||
ctx.ArchitectureChoice = arch
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
|
38
vendor/github.com/containers/buildah/pkg/parse/parse_unix.go
generated
vendored
38
vendor/github.com/containers/buildah/pkg/parse/parse_unix.go
generated
vendored
@ -4,6 +4,8 @@ package parse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/buildah/pkg/unshare"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
@ -24,18 +26,40 @@ func getDefaultProcessLimits() []string {
|
||||
return defaultLimits
|
||||
}
|
||||
|
||||
func DeviceFromPath(device string) (configs.Device, error) {
|
||||
func DeviceFromPath(device string) ([]configs.Device, error) {
|
||||
var devs []configs.Device
|
||||
src, dst, permissions, err := Device(device)
|
||||
if err != nil {
|
||||
return configs.Device{}, err
|
||||
return nil, err
|
||||
}
|
||||
if unshare.IsRootless() {
|
||||
return configs.Device{}, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst)
|
||||
return nil, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst)
|
||||
}
|
||||
dev, err := devices.DeviceFromPath(src, permissions)
|
||||
srcInfo, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return configs.Device{}, errors.Wrapf(err, "%s is not a valid device", src)
|
||||
return nil, errors.Wrapf(err, "error getting info of source device %s", src)
|
||||
}
|
||||
dev.Path = dst
|
||||
return *dev, nil
|
||||
|
||||
if !srcInfo.IsDir() {
|
||||
|
||||
dev, err := devices.DeviceFromPath(src, permissions)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "%s is not a valid device", src)
|
||||
}
|
||||
dev.Path = dst
|
||||
devs = append(devs, *dev)
|
||||
return devs, nil
|
||||
}
|
||||
|
||||
// If source device is a directory
|
||||
srcDevices, err := devices.GetDevices(src)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error getting source devices from directory %s", src)
|
||||
}
|
||||
for _, d := range srcDevices {
|
||||
d.Path = filepath.Join(dst, filepath.Base(d.Path))
|
||||
d.Permissions = permissions
|
||||
devs = append(devs, *d)
|
||||
}
|
||||
return devs, nil
|
||||
}
|
||||
|
24
vendor/github.com/containers/buildah/pull.go
generated
vendored
24
vendor/github.com/containers/buildah/pull.go
generated
vendored
@ -8,18 +8,18 @@ import (
|
||||
|
||||
"github.com/containers/buildah/pkg/blobcache"
|
||||
"github.com/containers/buildah/util"
|
||||
cp "github.com/containers/image/v4/copy"
|
||||
"github.com/containers/image/v4/directory"
|
||||
"github.com/containers/image/v4/docker"
|
||||
dockerarchive "github.com/containers/image/v4/docker/archive"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
tarfile "github.com/containers/image/v4/docker/tarfile"
|
||||
ociarchive "github.com/containers/image/v4/oci/archive"
|
||||
oci "github.com/containers/image/v4/oci/layout"
|
||||
"github.com/containers/image/v4/signature"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
cp "github.com/containers/image/v5/copy"
|
||||
"github.com/containers/image/v5/directory"
|
||||
"github.com/containers/image/v5/docker"
|
||||
dockerarchive "github.com/containers/image/v5/docker/archive"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
tarfile "github.com/containers/image/v5/docker/tarfile"
|
||||
ociarchive "github.com/containers/image/v5/oci/archive"
|
||||
oci "github.com/containers/image/v5/oci/layout"
|
||||
"github.com/containers/image/v5/signature"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
|
6
vendor/github.com/containers/buildah/util.go
generated
vendored
6
vendor/github.com/containers/buildah/util.go
generated
vendored
@ -8,9 +8,9 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/buildah/util"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/chrootarchive"
|
||||
|
12
vendor/github.com/containers/buildah/util/util.go
generated
vendored
12
vendor/github.com/containers/buildah/util/util.go
generated
vendored
@ -10,12 +10,12 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/buildah/pkg/cgroups"
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v4/signature"
|
||||
is "github.com/containers/image/v4/storage"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/pkg/sysregistriesv2"
|
||||
"github.com/containers/image/v5/signature"
|
||||
is "github.com/containers/image/v5/storage"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/containers/storage"
|
||||
"github.com/docker/distribution/registry/api/errcode"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
|
94
vendor/github.com/containers/image/v4/image/docker_list.go
generated
vendored
94
vendor/github.com/containers/image/v4/image/docker_list.go
generated
vendored
@ -1,94 +0,0 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type platformSpec struct {
|
||||
Architecture string `json:"architecture"`
|
||||
OS string `json:"os"`
|
||||
OSVersion string `json:"os.version,omitempty"`
|
||||
OSFeatures []string `json:"os.features,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
Features []string `json:"features,omitempty"` // removed in OCI
|
||||
}
|
||||
|
||||
// A manifestDescriptor references a platform-specific manifest.
|
||||
type manifestDescriptor struct {
|
||||
manifest.Schema2Descriptor
|
||||
Platform platformSpec `json:"platform"`
|
||||
}
|
||||
|
||||
type manifestList struct {
|
||||
SchemaVersion int `json:"schemaVersion"`
|
||||
MediaType string `json:"mediaType"`
|
||||
Manifests []manifestDescriptor `json:"manifests"`
|
||||
}
|
||||
|
||||
// chooseDigestFromManifestList parses blob as a schema2 manifest list,
|
||||
// and returns the digest of the image appropriate for the current environment.
|
||||
func chooseDigestFromManifestList(sys *types.SystemContext, blob []byte) (digest.Digest, error) {
|
||||
wantedArch := runtime.GOARCH
|
||||
if sys != nil && sys.ArchitectureChoice != "" {
|
||||
wantedArch = sys.ArchitectureChoice
|
||||
}
|
||||
wantedOS := runtime.GOOS
|
||||
if sys != nil && sys.OSChoice != "" {
|
||||
wantedOS = sys.OSChoice
|
||||
}
|
||||
|
||||
list := manifestList{}
|
||||
if err := json.Unmarshal(blob, &list); err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, d := range list.Manifests {
|
||||
if d.Platform.Architecture == wantedArch && d.Platform.OS == wantedOS {
|
||||
return d.Digest, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no image found in manifest list for architecture %s, OS %s", wantedArch, wantedOS)
|
||||
}
|
||||
|
||||
func manifestSchema2FromManifestList(ctx context.Context, sys *types.SystemContext, src types.ImageSource, manblob []byte) (genericManifest, error) {
|
||||
targetManifestDigest, err := chooseDigestFromManifestList(sys, manblob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
manblob, mt, err := src.GetManifest(ctx, &targetManifestDigest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
matches, err := manifest.MatchesDigest(manblob, targetManifestDigest)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error computing manifest digest")
|
||||
}
|
||||
if !matches {
|
||||
return nil, errors.Errorf("Manifest image does not match selected manifest digest %s", targetManifestDigest)
|
||||
}
|
||||
|
||||
return manifestInstanceFromBlob(ctx, sys, src, manblob, mt)
|
||||
}
|
||||
|
||||
// ChooseManifestInstanceFromManifestList returns a digest of a manifest appropriate
|
||||
// for the current system from the manifest available from src.
|
||||
func ChooseManifestInstanceFromManifestList(ctx context.Context, sys *types.SystemContext, src types.UnparsedImage) (digest.Digest, error) {
|
||||
// For now this only handles manifest.DockerV2ListMediaType; we can generalize it later,
|
||||
// probably along with manifest list editing.
|
||||
blob, mt, err := src.Manifest(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if mt != manifest.DockerV2ListMediaType {
|
||||
return "", fmt.Errorf("Internal error: Trying to select an image from a non-manifest-list manifest type %s", mt)
|
||||
}
|
||||
return chooseDigestFromManifestList(sys, blob)
|
||||
}
|
@ -13,15 +13,16 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/docker/reference"
|
||||
"github.com/containers/image/v4/image"
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/pkg/blobinfocache"
|
||||
"github.com/containers/image/v4/pkg/compression"
|
||||
"github.com/containers/image/v4/signature"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/image"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/pkg/blobinfocache"
|
||||
"github.com/containers/image/v5/pkg/compression"
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/containers/image/v5/types"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vbauerster/mpb"
|
||||
@ -110,6 +111,37 @@ type imageCopier struct {
|
||||
canSubstituteBlobs bool
|
||||
}
|
||||
|
||||
const (
|
||||
// CopySystemImage is the default value which, when set in
|
||||
// Options.ImageListSelection, indicates that the caller expects only one
|
||||
// image to be copied, so if the source reference refers to a list of
|
||||
// images, one that matches the current system will be selected.
|
||||
CopySystemImage ImageListSelection = iota
|
||||
// CopyAllImages is a value which, when set in Options.ImageListSelection,
|
||||
// indicates that the caller expects to copy multiple images, and if
|
||||
// the source reference refers to a list, that the list and every image
|
||||
// to which it refers will be copied. If the source reference refers
|
||||
// to a list, the target reference can not accept lists, an error
|
||||
// should be returned.
|
||||
CopyAllImages
|
||||
// CopySpecificImages is a value which, when set in
|
||||
// Options.ImageListSelection, indicates that the caller expects the
|
||||
// source reference to be either a single image or a list of images,
|
||||
// and if the source reference is a list, wants only specific instances
|
||||
// from it copied (or none of them, if the list of instances to copy is
|
||||
// empty), along with the list itself. If the target reference can
|
||||
// only accept one image (i.e., it cannot accept lists), an error
|
||||
// should be returned.
|
||||
CopySpecificImages
|
||||
)
|
||||
|
||||
// ImageListSelection is one of CopySystemImage, CopyAllImages, or
|
||||
// CopySpecificImages, to control whether, when the source reference is a list,
|
||||
// copy.Image() copies only an image which matches the current runtime
|
||||
// environment, or all images which match the supplied reference, or only
|
||||
// specific images from the source reference.
|
||||
type ImageListSelection int
|
||||
|
||||
// Options allows supplying non-default configuration modifying the behavior of CopyImage.
|
||||
type Options struct {
|
||||
RemoveSignatures bool // Remove any pre-existing signatures. SignBy will still add a new signature.
|
||||
@ -121,12 +153,24 @@ type Options struct {
|
||||
Progress chan types.ProgressProperties // Reported to when ProgressInterval has arrived for a single artifact+offset.
|
||||
// manifest MIME type of image set by user. "" is default and means use the autodetection to the the manifest MIME type
|
||||
ForceManifestMIMEType string
|
||||
ImageListSelection ImageListSelection // set to either CopySystemImage (the default), CopyAllImages, or CopySpecificImages to control which instances we copy when the source reference is a list; ignored if the source reference is not a list
|
||||
Instances []digest.Digest // if ImageListSelection is CopySpecificImages, copy only these instances and the list itself
|
||||
}
|
||||
|
||||
// validateImageListSelection returns an error if the passed-in value is not one that we recognize as a valid ImageListSelection value
|
||||
func validateImageListSelection(selection ImageListSelection) error {
|
||||
switch selection {
|
||||
case CopySystemImage, CopyAllImages, CopySpecificImages:
|
||||
return nil
|
||||
default:
|
||||
return errors.Errorf("Invalid value for options.ImageListSelection: %d", selection)
|
||||
}
|
||||
}
|
||||
|
||||
// Image copies image from srcRef to destRef, using policyContext to validate
|
||||
// source image admissibility. It returns the manifest which was written to
|
||||
// the new copy of the image.
|
||||
func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, srcRef types.ImageReference, options *Options) (manifest []byte, retErr error) {
|
||||
func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, srcRef types.ImageReference, options *Options) (copiedManifest []byte, retErr error) {
|
||||
// NOTE this function uses an output parameter for the error return value.
|
||||
// Setting this and returning is the ideal way to return an error.
|
||||
//
|
||||
@ -136,6 +180,10 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
|
||||
options = &Options{}
|
||||
}
|
||||
|
||||
if err := validateImageListSelection(options.ImageListSelection); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reportWriter := ioutil.Discard
|
||||
|
||||
if options.ReportWriter != nil {
|
||||
@ -206,79 +254,278 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef,
|
||||
}
|
||||
|
||||
if !multiImage {
|
||||
// The simple case: Just copy a single image.
|
||||
if manifest, err = c.copyOneImage(ctx, policyContext, options, unparsedToplevel); err != nil {
|
||||
// The simple case: just copy a single image.
|
||||
if copiedManifest, _, _, err = c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedToplevel, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// This is a manifest list. Choose a single image and copy it.
|
||||
// FIXME: Copy to destinations which support manifest lists, one image at a time.
|
||||
instanceDigest, err := image.ChooseManifestInstanceFromManifestList(ctx, options.SourceCtx, unparsedToplevel)
|
||||
} else if options.ImageListSelection == CopySystemImage {
|
||||
// This is a manifest list, and we weren't asked to copy multiple images. Choose a single image that
|
||||
// matches the current system to copy, and copy it.
|
||||
mfest, manifestType, err := unparsedToplevel.Manifest(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error reading manifest for %s", transports.ImageName(srcRef))
|
||||
}
|
||||
manifestList, err := manifest.ListFromBlob(mfest, manifestType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error parsing primary manifest as list for %s", transports.ImageName(srcRef))
|
||||
}
|
||||
instanceDigest, err := manifestList.ChooseInstance(options.SourceCtx) // try to pick one that matches options.SourceCtx
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error choosing an image from manifest list %s", transports.ImageName(srcRef))
|
||||
}
|
||||
logrus.Debugf("Source is a manifest list; copying (only) instance %s", instanceDigest)
|
||||
logrus.Debugf("Source is a manifest list; copying (only) instance %s for current system", instanceDigest)
|
||||
unparsedInstance := image.UnparsedInstance(rawSource, &instanceDigest)
|
||||
|
||||
if manifest, err = c.copyOneImage(ctx, policyContext, options, unparsedInstance); err != nil {
|
||||
if copiedManifest, _, _, err = c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedInstance, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else { /* options.ImageListSelection == CopyAllImages or options.ImageListSelection == CopySpecificImages, */
|
||||
// If we were asked to copy multiple images and can't, that's an error.
|
||||
if !supportsMultipleImages(c.dest) {
|
||||
return nil, errors.Errorf("Error copying multiple images: destination transport %q does not support copying multiple images as a group", destRef.Transport().Name())
|
||||
}
|
||||
// Copy some or all of the images.
|
||||
switch options.ImageListSelection {
|
||||
case CopyAllImages:
|
||||
logrus.Debugf("Source is a manifest list; copying all instances")
|
||||
case CopySpecificImages:
|
||||
logrus.Debugf("Source is a manifest list; copying some instances")
|
||||
}
|
||||
if copiedManifest, _, err = c.copyMultipleImages(ctx, policyContext, options, unparsedToplevel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.dest.Commit(ctx); err != nil {
|
||||
if err := c.dest.Commit(ctx, unparsedToplevel); err != nil {
|
||||
return nil, errors.Wrap(err, "Error committing the finished image")
|
||||
}
|
||||
|
||||
return manifest, nil
|
||||
return copiedManifest, nil
|
||||
}
|
||||
|
||||
// Image copies a single (on-manifest-list) image unparsedImage, using policyContext to validate
|
||||
// Checks if the destination supports accepting multiple images by checking if it can support
|
||||
// manifest types that are lists of other manifests.
|
||||
func supportsMultipleImages(dest types.ImageDestination) bool {
|
||||
mtypes := dest.SupportedManifestMIMETypes()
|
||||
if len(mtypes) == 0 {
|
||||
// Anything goes!
|
||||
return true
|
||||
}
|
||||
for _, mtype := range mtypes {
|
||||
if manifest.MIMETypeIsMultiImage(mtype) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// copyMultipleImages copies some or all of an image list's instances, using
|
||||
// policyContext to validate source image admissibility.
|
||||
func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedToplevel *image.UnparsedImage) (copiedManifest []byte, copiedManifestType string, retErr error) {
|
||||
// Parse the list and get a copy of the original value after it's re-encoded.
|
||||
manifestList, manifestType, err := unparsedToplevel.Manifest(ctx)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error reading manifest list")
|
||||
}
|
||||
list, err := manifest.ListFromBlob(manifestList, manifestType)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error parsing manifest list %q", string(manifestList))
|
||||
}
|
||||
originalList := list.Clone()
|
||||
|
||||
// Read and/or clear the set of signatures for this list.
|
||||
var sigs [][]byte
|
||||
if options.RemoveSignatures {
|
||||
sigs = [][]byte{}
|
||||
} else {
|
||||
c.Printf("Getting image list signatures\n")
|
||||
s, err := c.rawSource.GetSignatures(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrap(err, "Error reading signatures")
|
||||
}
|
||||
sigs = s
|
||||
}
|
||||
if len(sigs) != 0 {
|
||||
c.Printf("Checking if image list destination supports signatures\n")
|
||||
if err := c.dest.SupportsSignatures(ctx); err != nil {
|
||||
return nil, "", errors.Wrap(err, "Can not copy signatures")
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if we'll need to convert the manifest list to a different format.
|
||||
forceListMIMEType := options.ForceManifestMIMEType
|
||||
switch forceListMIMEType {
|
||||
case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema2MediaType:
|
||||
forceListMIMEType = manifest.DockerV2ListMediaType
|
||||
case imgspecv1.MediaTypeImageManifest:
|
||||
forceListMIMEType = imgspecv1.MediaTypeImageIndex
|
||||
}
|
||||
selectedListType, err := c.determineListConversion(manifestType, c.dest.SupportedManifestMIMETypes(), forceListMIMEType)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error determining manifest list type to write to destination")
|
||||
}
|
||||
if selectedListType != list.MIMEType() {
|
||||
canModifyManifestList := (len(sigs) == 0)
|
||||
if !canModifyManifestList {
|
||||
return nil, "", errors.Errorf("Error: manifest list must be converted to type %q to be written to destination, but that would invalidate signatures", selectedListType)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy each image, or just the ones we want to copy, in turn.
|
||||
instanceDigests := list.Instances()
|
||||
imagesToCopy := len(instanceDigests)
|
||||
if options.ImageListSelection == CopySpecificImages {
|
||||
imagesToCopy = len(options.Instances)
|
||||
}
|
||||
c.Printf("Copying %d of %d images in list\n", imagesToCopy, len(instanceDigests))
|
||||
updates := make([]manifest.ListUpdate, len(instanceDigests))
|
||||
instancesCopied := 0
|
||||
for i, instanceDigest := range instanceDigests {
|
||||
if options.ImageListSelection == CopySpecificImages {
|
||||
skip := true
|
||||
for _, instance := range options.Instances {
|
||||
if instance == instanceDigest {
|
||||
skip = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
update, err := list.Instance(instanceDigest)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
logrus.Debugf("Skipping instance %s (%d/%d)", instanceDigest, i+1, len(instanceDigests))
|
||||
// Record the digest/size/type of the manifest that we didn't copy.
|
||||
updates[i] = update
|
||||
continue
|
||||
}
|
||||
}
|
||||
logrus.Debugf("Copying instance %s (%d/%d)", instanceDigest, i+1, len(instanceDigests))
|
||||
c.Printf("Copying image %s (%d/%d)\n", instanceDigest, instancesCopied+1, imagesToCopy)
|
||||
unparsedInstance := image.UnparsedInstance(c.rawSource, &instanceDigest)
|
||||
updatedManifest, updatedManifestType, updatedManifestDigest, err := c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedInstance, &instanceDigest)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
instancesCopied++
|
||||
// Record the result of a possible conversion here.
|
||||
update := manifest.ListUpdate{
|
||||
Digest: updatedManifestDigest,
|
||||
Size: int64(len(updatedManifest)),
|
||||
MediaType: updatedManifestType,
|
||||
}
|
||||
updates[i] = update
|
||||
}
|
||||
|
||||
// Now reset the digest/size/types of the manifests in the list to account for any conversions that we made.
|
||||
if err = list.UpdateInstances(updates); err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error updating manifest list")
|
||||
}
|
||||
|
||||
// Check if the updates meaningfully changed the list of images.
|
||||
listIsModified := false
|
||||
if !reflect.DeepEqual(list.Instances(), originalList.Instances()) {
|
||||
listIsModified = true
|
||||
}
|
||||
|
||||
// Perform the list conversion.
|
||||
if selectedListType != list.MIMEType() {
|
||||
list, err = list.ConvertToMIMEType(selectedListType)
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error converting manifest list to list with MIME type %q", selectedListType)
|
||||
}
|
||||
}
|
||||
|
||||
// If we can't use the original value, but we have to change it, flag an error.
|
||||
if listIsModified {
|
||||
manifestList, err = list.Serialize()
|
||||
if err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error encoding updated manifest list (%q: %#v)", list.MIMEType(), list.Instances())
|
||||
}
|
||||
logrus.Debugf("Manifest list has been updated")
|
||||
}
|
||||
|
||||
// Save the manifest list.
|
||||
c.Printf("Writing manifest list to image destination\n")
|
||||
if err = c.dest.PutManifest(ctx, manifestList, nil); err != nil {
|
||||
return nil, "", errors.Wrapf(err, "Error writing manifest list %q", string(manifestList))
|
||||
}
|
||||
|
||||
// Sign the manifest list.
|
||||
if options.SignBy != "" {
|
||||
newSig, err := c.createSignature(manifestList, options.SignBy)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
sigs = append(sigs, newSig)
|
||||
}
|
||||
|
||||
c.Printf("Storing list signatures\n")
|
||||
if err := c.dest.PutSignatures(ctx, sigs, nil); err != nil {
|
||||
return nil, "", errors.Wrap(err, "Error writing signatures")
|
||||
}
|
||||
|
||||
return manifestList, selectedListType, nil
|
||||
}
|
||||
|
||||
// copyOneImage copies a single (non-manifest-list) image unparsedImage, using policyContext to validate
|
||||
// source image admissibility.
|
||||
func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedImage *image.UnparsedImage) (manifestBytes []byte, retErr error) {
|
||||
func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedToplevel, unparsedImage *image.UnparsedImage, targetInstance *digest.Digest) (retManifest []byte, retManifestType string, retManifestDigest digest.Digest, retErr error) {
|
||||
// The caller is handling manifest lists; this could happen only if a manifest list contains a manifest list.
|
||||
// Make sure we fail cleanly in such cases.
|
||||
multiImage, err := isMultiImage(ctx, unparsedImage)
|
||||
if err != nil {
|
||||
// FIXME FIXME: How to name a reference for the sub-image?
|
||||
return nil, errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference()))
|
||||
return nil, "", "", errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference()))
|
||||
}
|
||||
if multiImage {
|
||||
return nil, fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image")
|
||||
return nil, "", "", fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image")
|
||||
}
|
||||
|
||||
// Please keep this policy check BEFORE reading any other information about the image.
|
||||
// (the multiImage check above only matches the MIME type, which we have received anyway.
|
||||
// (The multiImage check above only matches the MIME type, which we have received anyway.
|
||||
// Actual parsing of anything should be deferred.)
|
||||
if allowed, err := policyContext.IsRunningImageAllowed(ctx, unparsedImage); !allowed || err != nil { // Be paranoid and fail if either return value indicates so.
|
||||
return nil, errors.Wrap(err, "Source image rejected")
|
||||
return nil, "", "", errors.Wrap(err, "Source image rejected")
|
||||
}
|
||||
src, err := image.FromUnparsedImage(ctx, options.SourceCtx, unparsedImage)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(c.rawSource.Reference()))
|
||||
return nil, "", "", errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(c.rawSource.Reference()))
|
||||
}
|
||||
|
||||
// If the destination is a digested reference, make a note of that, determine what digest value we're
|
||||
// expecting, and check that the source manifest matches it.
|
||||
// expecting, and check that the source manifest matches it. If the source manifest doesn't, but it's
|
||||
// one item from a manifest list that matches it, accept that as a match.
|
||||
destIsDigestedReference := false
|
||||
if named := c.dest.Reference().DockerReference(); named != nil {
|
||||
if digested, ok := named.(reference.Digested); ok {
|
||||
destIsDigestedReference = true
|
||||
sourceManifest, _, err := src.Manifest(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error reading manifest from source image")
|
||||
return nil, "", "", errors.Wrapf(err, "Error reading manifest from source image")
|
||||
}
|
||||
matches, err := manifest.MatchesDigest(sourceManifest, digested.Digest())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Error computing digest of source image's manifest")
|
||||
return nil, "", "", errors.Wrapf(err, "Error computing digest of source image's manifest")
|
||||
}
|
||||
if !matches {
|
||||
return nil, errors.New("Digest of source image's manifest would not match destination reference")
|
||||
manifestList, _, err := unparsedToplevel.Manifest(ctx)
|
||||
if err != nil {
|
||||
return nil, "", "", errors.Wrapf(err, "Error reading manifest from source image")
|
||||
}
|
||||
matches, err = manifest.MatchesDigest(manifestList, digested.Digest())
|
||||
if err != nil {
|
||||
return nil, "", "", errors.Wrapf(err, "Error computing digest of source image's manifest")
|
||||
}
|
||||
if !matches {
|
||||
return nil, "", "", errors.New("Digest of source image's manifest would not match destination reference")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkImageDestinationForCurrentRuntimeOS(ctx, options.DestinationCtx, src, c.dest); err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
var sigs [][]byte
|
||||
@ -288,14 +535,14 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
|
||||
c.Printf("Getting image source signatures\n")
|
||||
s, err := src.Signatures(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error reading signatures")
|
||||
return nil, "", "", errors.Wrap(err, "Error reading signatures")
|
||||
}
|
||||
sigs = s
|
||||
}
|
||||
if len(sigs) != 0 {
|
||||
c.Printf("Checking if image destination supports signatures\n")
|
||||
if err := c.dest.SupportsSignatures(ctx); err != nil {
|
||||
return nil, errors.Wrap(err, "Can not copy signatures")
|
||||
return nil, "", "", errors.Wrap(err, "Can not copy signatures")
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,28 +562,29 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
|
||||
ic.canSubstituteBlobs = ic.canModifyManifest && options.SignBy == ""
|
||||
|
||||
if err := ic.updateEmbeddedDockerReference(); err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
// We compute preferredManifestMIMEType only to show it in error messages.
|
||||
// Without having to add this context in an error message, we would be happy enough to know only that no conversion is needed.
|
||||
preferredManifestMIMEType, otherManifestMIMETypeCandidates, err := ic.determineManifestConversion(ctx, c.dest.SupportedManifestMIMETypes(), options.ForceManifestMIMEType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
// If src.UpdatedImageNeedsLayerDiffIDs(ic.manifestUpdates) will be true, it needs to be true by the time we get here.
|
||||
ic.diffIDsAreNeeded = src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates)
|
||||
|
||||
if err := ic.copyLayers(ctx); err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
// With docker/distribution registries we do not know whether the registry accepts schema2 or schema1 only;
|
||||
// and at least with the OpenShift registry "acceptschema2" option, there is no way to detect the support
|
||||
// without actually trying to upload something and getting a types.ManifestTypeRejectedError.
|
||||
// So, try the preferred manifest MIME type. If the process succeeds, fine…
|
||||
manifestBytes, err = ic.copyUpdatedConfigAndManifest(ctx)
|
||||
manifestBytes, retManifestDigest, err := ic.copyUpdatedConfigAndManifest(ctx, targetInstance)
|
||||
retManifestType = preferredManifestMIMEType
|
||||
if err != nil {
|
||||
logrus.Debugf("Writing manifest using preferred type %s failed: %v", preferredManifestMIMEType, err)
|
||||
// … if it fails, _and_ the failure is because the manifest is rejected, we may have other options.
|
||||
@ -344,14 +592,14 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
|
||||
// We don’t have other options.
|
||||
// In principle the code below would handle this as well, but the resulting error message is fairly ugly.
|
||||
// Don’t bother the user with MIME types if we have no choice.
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
// If the original MIME type is acceptable, determineManifestConversion always uses it as preferredManifestMIMEType.
|
||||
// So if we are here, we will definitely be trying to convert the manifest.
|
||||
// With !ic.canModifyManifest, that would just be a string of repeated failures for the same reason,
|
||||
// so let’s bail out early and with a better error message.
|
||||
if !ic.canModifyManifest {
|
||||
return nil, errors.Wrap(err, "Writing manifest failed (and converting it is not possible)")
|
||||
return nil, "", "", errors.Wrap(err, "Writing manifest failed (and converting it is not possible)")
|
||||
}
|
||||
|
||||
// errs is a list of errors when trying various manifest types. Also serves as an "upload succeeded" flag when set to nil.
|
||||
@ -359,7 +607,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
|
||||
for _, manifestMIMEType := range otherManifestMIMETypeCandidates {
|
||||
logrus.Debugf("Trying to use manifest type %s…", manifestMIMEType)
|
||||
ic.manifestUpdates.ManifestMIMEType = manifestMIMEType
|
||||
attemptedManifest, err := ic.copyUpdatedConfigAndManifest(ctx)
|
||||
attemptedManifest, attemptedManifestDigest, err := ic.copyUpdatedConfigAndManifest(ctx, targetInstance)
|
||||
if err != nil {
|
||||
logrus.Debugf("Upload of manifest type %s failed: %v", manifestMIMEType, err)
|
||||
errs = append(errs, fmt.Sprintf("%s(%v)", manifestMIMEType, err))
|
||||
@ -368,28 +616,30 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli
|
||||
|
||||
// We have successfully uploaded a manifest.
|
||||
manifestBytes = attemptedManifest
|
||||
retManifestDigest = attemptedManifestDigest
|
||||
retManifestType = manifestMIMEType
|
||||
errs = nil // Mark this as a success so that we don't abort below.
|
||||
break
|
||||
}
|
||||
if errs != nil {
|
||||
return nil, fmt.Errorf("Uploading manifest failed, attempted the following formats: %s", strings.Join(errs, ", "))
|
||||
return nil, "", "", fmt.Errorf("Uploading manifest failed, attempted the following formats: %s", strings.Join(errs, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
if options.SignBy != "" {
|
||||
newSig, err := c.createSignature(manifestBytes, options.SignBy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, "", "", err
|
||||
}
|
||||
sigs = append(sigs, newSig)
|
||||
}
|
||||
|
||||
c.Printf("Storing signatures\n")
|
||||
if err := c.dest.PutSignatures(ctx, sigs); err != nil {
|
||||
return nil, errors.Wrap(err, "Error writing signatures")
|
||||
if err := c.dest.PutSignatures(ctx, sigs, targetInstance); err != nil {
|
||||
return nil, "", "", errors.Wrap(err, "Error writing signatures")
|
||||
}
|
||||
|
||||
return manifestBytes, nil
|
||||
return manifestBytes, retManifestType, retManifestDigest, nil
|
||||
}
|
||||
|
||||
// Printf writes a formatted string to c.reportWriter.
|
||||
@ -554,12 +804,13 @@ func layerDigestsDiffer(a, b []types.BlobInfo) bool {
|
||||
}
|
||||
|
||||
// copyUpdatedConfigAndManifest updates the image per ic.manifestUpdates, if necessary,
|
||||
// stores the resulting config and manifest to the destination, and returns the stored manifest.
|
||||
func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context) ([]byte, error) {
|
||||
// stores the resulting config and manifest to the destination, and returns the stored manifest
|
||||
// and its digest.
|
||||
func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, digest.Digest, error) {
|
||||
pendingImage := ic.src
|
||||
if !reflect.DeepEqual(*ic.manifestUpdates, types.ManifestUpdateOptions{InformationOnly: ic.manifestUpdates.InformationOnly}) {
|
||||
if !ic.canModifyManifest {
|
||||
return nil, errors.Errorf("Internal error: copy needs an updated manifest but that was known to be forbidden")
|
||||
return nil, "", errors.Errorf("Internal error: copy needs an updated manifest but that was known to be forbidden")
|
||||
}
|
||||
if !ic.diffIDsAreNeeded && ic.src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates) {
|
||||
// We have set ic.diffIDsAreNeeded based on the preferred MIME type returned by determineManifestConversion.
|
||||
@ -568,28 +819,35 @@ func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context) ([]byte
|
||||
// when ic.c.dest.SupportedManifestMIMETypes() includes both s1 and s2, the upload using s1 failed, and we are now trying s2.
|
||||
// Supposedly s2-only registries do not exist or are extremely rare, so failing with this error message is good enough for now.
|
||||
// If handling such registries turns out to be necessary, we could compute ic.diffIDsAreNeeded based on the full list of manifest MIME type candidates.
|
||||
return nil, errors.Errorf("Can not convert image to %s, preparing DiffIDs for this case is not supported", ic.manifestUpdates.ManifestMIMEType)
|
||||
return nil, "", errors.Errorf("Can not convert image to %s, preparing DiffIDs for this case is not supported", ic.manifestUpdates.ManifestMIMEType)
|
||||
}
|
||||
pi, err := ic.src.UpdatedImage(ctx, *ic.manifestUpdates)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error creating an updated image manifest")
|
||||
return nil, "", errors.Wrap(err, "Error creating an updated image manifest")
|
||||
}
|
||||
pendingImage = pi
|
||||
}
|
||||
manifest, _, err := pendingImage.Manifest(ctx)
|
||||
man, _, err := pendingImage.Manifest(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error reading manifest")
|
||||
return nil, "", errors.Wrap(err, "Error reading manifest")
|
||||
}
|
||||
|
||||
if err := ic.c.copyConfig(ctx, pendingImage); err != nil {
|
||||
return nil, err
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
ic.c.Printf("Writing manifest to image destination\n")
|
||||
if err := ic.c.dest.PutManifest(ctx, manifest); err != nil {
|
||||
return nil, errors.Wrap(err, "Error writing manifest")
|
||||
manifestDigest, err := manifest.Digest(man)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return manifest, nil
|
||||
if instanceDigest != nil {
|
||||
instanceDigest = &manifestDigest
|
||||
}
|
||||
if err := ic.c.dest.PutManifest(ctx, man, instanceDigest); err != nil {
|
||||
return nil, "", errors.Wrap(err, "Error writing manifest")
|
||||
}
|
||||
return man, manifestDigest, nil
|
||||
}
|
||||
|
||||
// newProgressPool creates a *mpb.Progress and a cleanup function.
|
@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -119,3 +119,36 @@ func isMultiImage(ctx context.Context, img types.UnparsedImage) (bool, error) {
|
||||
}
|
||||
return manifest.MIMETypeIsMultiImage(mt), nil
|
||||
}
|
||||
|
||||
// determineListConversion takes the current MIME type of a list of manifests,
|
||||
// the list of MIME types supported for a given destination, and a possible
|
||||
// forced value, and returns the MIME type to which we should convert the list
|
||||
// of manifests, whether we are converting to it or using it unmodified.
|
||||
func (c *copier) determineListConversion(currentListMIMEType string, destSupportedMIMETypes []string, forcedListMIMEType string) (string, error) {
|
||||
// If we're forcing it, we prefer the forced value over everything else.
|
||||
if forcedListMIMEType != "" {
|
||||
return forcedListMIMEType, nil
|
||||
}
|
||||
// If there's no list of supported types, then anything we support is expected to be supported.
|
||||
if len(destSupportedMIMETypes) == 0 {
|
||||
destSupportedMIMETypes = manifest.SupportedListMIMETypes
|
||||
}
|
||||
var selectedType string
|
||||
for i := range destSupportedMIMETypes {
|
||||
// The second priority is the first member of the list of acceptable types that is a list,
|
||||
// but keep going in case current type occurs later in the list.
|
||||
if selectedType == "" && manifest.MIMETypeIsMultiImage(destSupportedMIMETypes[i]) {
|
||||
selectedType = destSupportedMIMETypes[i]
|
||||
}
|
||||
// The first priority is the current type, if it's in the list, since that lets us avoid a
|
||||
// conversion that isn't strictly necessary.
|
||||
if destSupportedMIMETypes[i] == currentListMIMEType {
|
||||
selectedType = destSupportedMIMETypes[i]
|
||||
}
|
||||
}
|
||||
if selectedType == "" {
|
||||
return "", errors.Errorf("destination does not support any supported manifest list types (%v)", manifest.SupportedListMIMETypes)
|
||||
}
|
||||
// Done.
|
||||
return selectedType, nil
|
||||
}
|
@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
)
|
||||
|
||||
// progressReader is a reader that reports its progress on an interval.
|
@ -1,8 +1,8 @@
|
||||
package copy
|
||||
|
||||
import (
|
||||
"github.com/containers/image/v4/signature"
|
||||
"github.com/containers/image/v4/transports"
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/containers/image/v5/transports"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -199,16 +199,23 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo
|
||||
}
|
||||
|
||||
// PutManifest writes manifest to the destination.
|
||||
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to write the manifest for (when
|
||||
// the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list.
|
||||
// It is expected but not enforced that the instanceDigest, when specified, matches the digest of `manifest` as generated
|
||||
// by `manifest.Digest()`.
|
||||
// FIXME? This should also receive a MIME type if known, to differentiate between schema versions.
|
||||
// If the destination is in principle available, refuses this manifest type (e.g. it does not recognize the schema),
|
||||
// but may accept a different manifest type, the returned error must be an ManifestTypeRejectedError.
|
||||
func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte) error {
|
||||
return ioutil.WriteFile(d.ref.manifestPath(), manifest, 0644)
|
||||
func (d *dirImageDestination) PutManifest(ctx context.Context, manifest []byte, instanceDigest *digest.Digest) error {
|
||||
return ioutil.WriteFile(d.ref.manifestPath(instanceDigest), manifest, 0644)
|
||||
}
|
||||
|
||||
func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]byte) error {
|
||||
// PutSignatures writes a set of signatures to the destination.
|
||||
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to write or overwrite the signatures for
|
||||
// (when the primary manifest is a manifest list); this should always be nil if the primary manifest is not a manifest list.
|
||||
func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]byte, instanceDigest *digest.Digest) error {
|
||||
for i, sig := range signatures {
|
||||
if err := ioutil.WriteFile(d.ref.signaturePath(i), sig, 0644); err != nil {
|
||||
if err := ioutil.WriteFile(d.ref.signaturePath(i, instanceDigest), sig, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -219,7 +226,7 @@ func (d *dirImageDestination) PutSignatures(ctx context.Context, signatures [][]
|
||||
// WARNING: This does not have any transactional semantics:
|
||||
// - Uploaded data MAY be visible to others before Commit() is called
|
||||
// - Uploaded data MAY be removed or MAY remain around if Close() is called without Commit() (i.e. rollback is allowed but not guaranteed)
|
||||
func (d *dirImageDestination) Commit(ctx context.Context) error {
|
||||
func (d *dirImageDestination) Commit(context.Context, types.UnparsedImage) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -6,10 +6,9 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/containers/image/v4/manifest"
|
||||
"github.com/containers/image/v4/types"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type dirImageSource struct {
|
||||
@ -38,10 +37,7 @@ func (s *dirImageSource) Close() error {
|
||||
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve (when the primary manifest is a manifest list);
|
||||
// this never happens if the primary manifest is not a manifest list (e.g. if the source never returns manifest lists).
|
||||
func (s *dirImageSource) GetManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, string, error) {
|
||||
if instanceDigest != nil {
|
||||
return nil, "", errors.Errorf(`Getting target manifest not supported by "dir:"`)
|
||||
}
|
||||
m, err := ioutil.ReadFile(s.ref.manifestPath())
|
||||
m, err := ioutil.ReadFile(s.ref.manifestPath(instanceDigest))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@ -73,12 +69,9 @@ func (s *dirImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache
|
||||
// (when the primary manifest is a manifest list); this never happens if the primary manifest is not a manifest list
|
||||
// (e.g. if the source never returns manifest lists).
|
||||
func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) {
|
||||
if instanceDigest != nil {
|
||||
return nil, errors.Errorf(`Manifests lists are not supported by "dir:"`)
|
||||
}
|
||||
signatures := [][]byte{}
|
||||
for i := 0; ; i++ {
|
||||
signature, err := ioutil.ReadFile(s.ref.signaturePath(i))
|
||||
signature, err := ioutil.ReadFile(s.ref.signaturePath(i, instanceDigest))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
break
|
||||
@ -90,7 +83,14 @@ func (s *dirImageSource) GetSignatures(ctx context.Context, instanceDigest *dige
|
||||
return signatures, nil
|
||||
}
|
||||
|
||||
// LayerInfosForCopy() returns updated layer info that should be used when copying, in preference to values in the manifest, if specified.
|
||||
func (s *dirImageSource) LayerInfosForCopy(ctx context.Context) ([]types.BlobInfo, error) {
|
||||
// LayerInfosForCopy returns either nil (meaning the values in the manifest are fine), or updated values for the layer
|
||||
// blobsums that are listed in the image's manifest. If values are returned, they should be used when using GetBlob()
|
||||
// to read the image's layers.
|
||||
// If instanceDigest is not nil, it contains a digest of the specific manifest instance to retrieve BlobInfos for
|
||||
// (when the primary manifest is a manifest list); this never happens if the primary manifest is not a manifest list
|
||||
// (e.g. if the source never returns manifest lists).
|
||||
// The Digest field is guaranteed to be provided; Size may be -1.
|
||||
// WARNING: The list may contain duplicates, and they are semantically relevant.
|
||||
func (s *dirImageSource) LayerInfosForCopy(context.Context, *digest.Digest) ([]types.BlobInfo, error) {
|
||||
return nil, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user