vendor: github.com/docker/cli v28.2.1
full diff: https://github.com/docker/cli/compare/v28.1.1...v28.2.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -16,7 +16,7 @@ require (
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/cli v28.1.1+incompatible
|
||||
github.com/docker/cli v28.2.1+incompatible
|
||||
github.com/docker/cli-docs-tool v0.10.0
|
||||
github.com/docker/docker v28.2.1+incompatible
|
||||
github.com/docker/go-units v0.5.0
|
||||
|
||||
@@ -108,8 +108,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v28.1.1+incompatible h1:eyUemzeI45DY7eDPuwUcmDyDj1pM98oD5MdSpiItp8k=
|
||||
github.com/docker/cli v28.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v28.2.1+incompatible h1:AYyTcuwvhl9dXdyCiXlOGXiIqSNYzTmaDNpxIISPGsM=
|
||||
github.com/docker/cli v28.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli-docs-tool v0.10.0 h1:bOD6mKynPQgojQi3s2jgcUWGp/Ebqy1SeCr9VfKQLLU=
|
||||
github.com/docker/cli-docs-tool v0.10.0/go.mod h1:5EM5zPnT2E7yCLERZmrDA234Vwn09fzRHP4aX1qwp1U=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
|
||||
+29
-2
@@ -48,6 +48,7 @@ Alfred Landrum <alfred.landrum@docker.com>
|
||||
Ali Rostami <rostami.ali@gmail.com>
|
||||
Alicia Lauerman <alicia@eta.im>
|
||||
Allen Sun <allensun.shl@alibaba-inc.com>
|
||||
Allie Sadler <allie.sadler@docker.com>
|
||||
Alvin Deng <alvin.q.deng@utexas.edu>
|
||||
Amen Belayneh <amenbelayneh@gmail.com>
|
||||
Amey Shrivastava <72866602+AmeyShrivastava@users.noreply.github.com>
|
||||
@@ -81,6 +82,7 @@ Antonis Kalipetis <akalipetis@gmail.com>
|
||||
Anusha Ragunathan <anusha.ragunathan@docker.com>
|
||||
Ao Li <la9249@163.com>
|
||||
Arash Deshmeh <adeshmeh@ca.ibm.com>
|
||||
Archimedes Trajano <developer@trajano.net>
|
||||
Arko Dasgupta <arko@tetrate.io>
|
||||
Arnaud Porterie <icecrime@gmail.com>
|
||||
Arnaud Rebillout <elboulangero@gmail.com>
|
||||
@@ -88,6 +90,7 @@ Arthur Peka <arthur.peka@outlook.com>
|
||||
Ashly Mathew <ashly.mathew@sap.com>
|
||||
Ashwini Oruganti <ashwini.oruganti@gmail.com>
|
||||
Aslam Ahemad <aslamahemad@gmail.com>
|
||||
Austin Vazquez <austin.vazquez.dev@gmail.com>
|
||||
Azat Khuyiyakhmetov <shadow_uz@mail.ru>
|
||||
Bardia Keyoumarsi <bkeyouma@ucsc.edu>
|
||||
Barnaby Gray <barnaby@pickle.me.uk>
|
||||
@@ -132,6 +135,7 @@ Cao Weiwei <cao.weiwei30@zte.com.cn>
|
||||
Carlo Mion <mion00@gmail.com>
|
||||
Carlos Alexandro Becker <caarlos0@gmail.com>
|
||||
Carlos de Paula <me@carlosedp.com>
|
||||
Carston Schilds <Carston.Schilds@visier.com>
|
||||
Casey Korver <casey@korver.dev>
|
||||
Ce Gao <ce.gao@outlook.com>
|
||||
Cedric Davies <cedricda@microsoft.com>
|
||||
@@ -189,6 +193,7 @@ Daisuke Ito <itodaisuke00@gmail.com>
|
||||
dalanlan <dalanlan925@gmail.com>
|
||||
Damien Nadé <github@livna.org>
|
||||
Dan Cotora <dan@bluevision.ro>
|
||||
Dan Wallis <dan@wallis.nz>
|
||||
Danial Gharib <danial.mail.gh@gmail.com>
|
||||
Daniel Artine <daniel.artine@ufrj.br>
|
||||
Daniel Cassidy <mail@danielcassidy.me.uk>
|
||||
@@ -237,6 +242,7 @@ Deshi Xiao <dxiao@redhat.com>
|
||||
Dharmit Shah <shahdharmit@gmail.com>
|
||||
Dhawal Yogesh Bhanushali <dbhanushali@vmware.com>
|
||||
Dieter Reuter <dieter.reuter@me.com>
|
||||
Dilep Dev <34891655+DilepDev@users.noreply.github.com>
|
||||
Dima Stopel <dima@twistlock.com>
|
||||
Dimitry Andric <d.andric@activevideo.com>
|
||||
Ding Fei <dingfei@stars.org.cn>
|
||||
@@ -308,6 +314,8 @@ George MacRorie <gmacr31@gmail.com>
|
||||
George Margaritis <gmargaritis@protonmail.com>
|
||||
George Xie <georgexsh@gmail.com>
|
||||
Gianluca Borello <g.borello@gmail.com>
|
||||
Giau. Tran Minh <hello@giautm.dev>
|
||||
Giedrius Jonikas <giedriusj1@gmail.com>
|
||||
Gildas Cuisinier <gildas.cuisinier@gcuisinier.net>
|
||||
Gio d'Amelio <giodamelio@gmail.com>
|
||||
Gleb Stsenov <gleb.stsenov@gmail.com>
|
||||
@@ -344,6 +352,7 @@ Hugo Gabriel Eyherabide <hugogabriel.eyherabide@gmail.com>
|
||||
huqun <huqun@zju.edu.cn>
|
||||
Huu Nguyen <huu@prismskylabs.com>
|
||||
Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com>
|
||||
Iain MacDonald <IJMacD@gmail.com>
|
||||
Iain Samuel McLean Elder <iain@isme.es>
|
||||
Ian Campbell <ian.campbell@docker.com>
|
||||
Ian Philpot <ian.philpot@microsoft.com>
|
||||
@@ -393,6 +402,7 @@ Jesse Adametz <jesseadametz@gmail.com>
|
||||
Jessica Frazelle <jess@oxide.computer>
|
||||
Jezeniel Zapanta <jpzapanta22@gmail.com>
|
||||
Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
|
||||
Jianyong Wu <wujianyong@hygon.cn>
|
||||
Jie Luo <luo612@zju.edu.cn>
|
||||
Jilles Oldenbeuving <ojilles@gmail.com>
|
||||
Jim Chen <njucjc@gmail.com>
|
||||
@@ -446,6 +456,7 @@ Julian <gitea+julian@ic.thejulian.uk>
|
||||
Julien Barbier <write0@gmail.com>
|
||||
Julien Kassar <github@kassisol.com>
|
||||
Julien Maitrehenry <julien.maitrehenry@me.com>
|
||||
Julio Cesar Garcia <juliogarciamelgarejo@gmail.com>
|
||||
Justas Brazauskas <brazauskasjustas@gmail.com>
|
||||
Justin Chadwell <me@jedevc.com>
|
||||
Justin Cormack <justin.cormack@docker.com>
|
||||
@@ -490,19 +501,22 @@ Kunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>
|
||||
Kyle Mitofsky <Kylemit@gmail.com>
|
||||
Lachlan Cooper <lachlancooper@gmail.com>
|
||||
Lai Jiangshan <jiangshanlai@gmail.com>
|
||||
Lajos Papp <lajos.papp@sequenceiq.com>
|
||||
Lars Kellogg-Stedman <lars@redhat.com>
|
||||
Laura Brehm <laurabrehm@hey.com>
|
||||
Laura Frank <ljfrank@gmail.com>
|
||||
Laurent Erignoux <lerignoux@gmail.com>
|
||||
Laurent Goderre <laurent.goderre@docker.com>
|
||||
Lee Gaines <eightlimbed@gmail.com>
|
||||
Lei Jitang <leijitang@huawei.com>
|
||||
Lennie <github@consolejunkie.net>
|
||||
lentil32 <lentil32@icloud.com>
|
||||
Leo Gallucci <elgalu3@gmail.com>
|
||||
Leonid Skorospelov <leosko94@gmail.com>
|
||||
Lewis Daly <lewisdaly@me.com>
|
||||
Li Fu Bang <lifubang@acmcoder.com>
|
||||
Li Yi <denverdino@gmail.com>
|
||||
Li Yi <weiyuan.yl@alibaba-inc.com>
|
||||
Li Zeghong <zeghong@hotmail.com>
|
||||
Liang-Chi Hsieh <viirya@gmail.com>
|
||||
Lihua Tang <lhtang@alauda.io>
|
||||
Lily Guo <lily.guo@docker.com>
|
||||
@@ -515,6 +529,7 @@ lixiaobing10051267 <li.xiaobing1@zte.com.cn>
|
||||
Lloyd Dewolf <foolswisdom@gmail.com>
|
||||
Lorenzo Fontana <lo@linux.com>
|
||||
Louis Opter <kalessin@kalessin.fr>
|
||||
Lovekesh Kumar <lovekesh.kumar@rtcamp.com>
|
||||
Luca Favatella <luca.favatella@erlang-solutions.com>
|
||||
Luca Marturana <lucamarturana@gmail.com>
|
||||
Lucas Chan <lucas-github@lucaschan.com>
|
||||
@@ -559,6 +574,7 @@ Matt Robenolt <matt@ydekproductions.com>
|
||||
Matteo Orefice <matteo.orefice@bites4bits.software>
|
||||
Matthew Heon <mheon@redhat.com>
|
||||
Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
|
||||
Matthieu MOREL <matthieu.morel35@gmail.com>
|
||||
Mauro Porras P <mauroporrasp@gmail.com>
|
||||
Max Shytikov <mshytikov@gmail.com>
|
||||
Max-Julian Pogner <max-julian@pogner.at>
|
||||
@@ -566,6 +582,7 @@ Maxime Petazzoni <max@signalfuse.com>
|
||||
Maximillian Fan Xavier <maximillianfx@gmail.com>
|
||||
Mei ChunTao <mei.chuntao@zte.com.cn>
|
||||
Melroy van den Berg <melroy@melroy.org>
|
||||
Mert Şişmanoğlu <mert190737fb@gmail.com>
|
||||
Metal <2466052+tedhexaflow@users.noreply.github.com>
|
||||
Micah Zoltu <micah@newrelic.com>
|
||||
Michael A. Smith <michael@smith-li.com>
|
||||
@@ -598,7 +615,9 @@ Mindaugas Rukas <momomg@gmail.com>
|
||||
Miroslav Gula <miroslav.gula@naytrolabs.com>
|
||||
Misty Stanley-Jones <misty@docker.com>
|
||||
Mohammad Banikazemi <mb@us.ibm.com>
|
||||
Mohammad Hossein <mhm98035@gmail.com>
|
||||
Mohammed Aaqib Ansari <maaquib@gmail.com>
|
||||
Mohammed Aminu Futa <mohammedfuta2000@gmail.com>
|
||||
Mohini Anne Dsouza <mohini3917@gmail.com>
|
||||
Moorthy RS <rsmoorthy@gmail.com>
|
||||
Morgan Bauer <mbauer@us.ibm.com>
|
||||
@@ -633,9 +652,11 @@ Nicolas De Loof <nicolas.deloof@gmail.com>
|
||||
Nikhil Chawla <chawlanikhil24@gmail.com>
|
||||
Nikolas Garofil <nikolas.garofil@uantwerpen.be>
|
||||
Nikolay Milovanov <nmil@itransformers.net>
|
||||
NinaLua <iturf@sina.cn>
|
||||
Nir Soffer <nsoffer@redhat.com>
|
||||
Nishant Totla <nishanttotla@gmail.com>
|
||||
NIWA Hideyuki <niwa.niwa@nifty.ne.jp>
|
||||
Noah Silas <noah@hustle.com>
|
||||
Noah Treuhaft <noah.treuhaft@docker.com>
|
||||
O.S. Tezer <ostezer@gmail.com>
|
||||
Oded Arbel <oded@geek.co.il>
|
||||
@@ -653,10 +674,12 @@ Patrick Böänziger <patrick.baenziger@bsi-software.com>
|
||||
Patrick Daigle <114765035+pdaig@users.noreply.github.com>
|
||||
Patrick Hemmer <patrick.hemmer@gmail.com>
|
||||
Patrick Lang <plang@microsoft.com>
|
||||
Patrick St. laurent <patrick@saint-laurent.us>
|
||||
Paul <paul9869@gmail.com>
|
||||
Paul Kehrer <paul.l.kehrer@gmail.com>
|
||||
Paul Lietar <paul@lietar.net>
|
||||
Paul Mulders <justinkb@gmail.com>
|
||||
Paul Rogalski <mail@paul-rogalski.de>
|
||||
Paul Seyfert <pseyfert.mathphys@gmail.com>
|
||||
Paul Weaver <pauweave@cisco.com>
|
||||
Pavel Pospisil <pospispa@gmail.com>
|
||||
@@ -678,7 +701,6 @@ Philip Alexander Etling <paetling@gmail.com>
|
||||
Philipp Gillé <philipp.gille@gmail.com>
|
||||
Philipp Schmied <pschmied@schutzwerk.com>
|
||||
Phong Tran <tran.pho@northeastern.edu>
|
||||
pidster <pid@pidster.com>
|
||||
Pieter E Smit <diepes@github.com>
|
||||
pixelistik <pixelistik@users.noreply.github.com>
|
||||
Pratik Karki <prertik@outlook.com>
|
||||
@@ -738,6 +760,7 @@ Samuel Cochran <sj26@sj26.com>
|
||||
Samuel Karp <skarp@amazon.com>
|
||||
Sandro Jäckel <sandro.jaeckel@gmail.com>
|
||||
Santhosh Manohar <santhosh@docker.com>
|
||||
Sarah Sanders <sarah.sanders@docker.com>
|
||||
Sargun Dhillon <sargun@netflix.com>
|
||||
Saswat Bhattacharya <sas.saswat@gmail.com>
|
||||
Saurabh Kumar <saurabhkumar0184@gmail.com>
|
||||
@@ -770,6 +793,7 @@ Spencer Brown <spencer@spencerbrown.org>
|
||||
Spring Lee <xi.shuai@outlook.com>
|
||||
squeegels <lmscrewy@gmail.com>
|
||||
Srini Brahmaroutu <srbrahma@us.ibm.com>
|
||||
Stavros Panakakis <stavrospanakakis@gmail.com>
|
||||
Stefan S. <tronicum@user.github.com>
|
||||
Stefan Scherer <stefan.scherer@docker.com>
|
||||
Stefan Weil <sw@weilnetz.de>
|
||||
@@ -780,6 +804,7 @@ Steve Durrheimer <s.durrheimer@gmail.com>
|
||||
Steve Richards <steve.richards@docker.com>
|
||||
Steven Burgess <steven.a.burgess@hotmail.com>
|
||||
Stoica-Marcu Floris-Andrei <floris.sm@gmail.com>
|
||||
Stuart Williams <pid@pidster.com>
|
||||
Subhajit Ghosh <isubuz.g@gmail.com>
|
||||
Sun Jianbo <wonderflow.sun@gmail.com>
|
||||
Sune Keller <absukl@almbrand.dk>
|
||||
@@ -867,6 +892,7 @@ Wang Yumu <37442693@qq.com>
|
||||
Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
|
||||
Wayne Song <wsong@docker.com>
|
||||
Wen Cheng Ma <wenchma@cn.ibm.com>
|
||||
Wenlong Zhang <zhangwenlong@loongson.cn>
|
||||
Wenzhi Liang <wenzhi.liang@gmail.com>
|
||||
Wes Morgan <cap10morgan@gmail.com>
|
||||
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
|
||||
@@ -908,3 +934,4 @@ Zhuo Zhi <h.dwwwwww@gmail.com>
|
||||
Átila Camurça Alves <camurca.home@gmail.com>
|
||||
Александр Менщиков <__Singleton__@hackerdom.ru>
|
||||
徐俊杰 <paco.xu@daocloud.io>
|
||||
林博仁 Buo-ren Lin <Buo.Ren.Lin@gmail.com>
|
||||
|
||||
+8
-5
@@ -109,7 +109,7 @@ func Run(makeCmd func(command.Cli) *cobra.Command, meta metadata.Metadata) {
|
||||
}
|
||||
|
||||
func withPluginClientConn(name string) command.CLIOption {
|
||||
return command.WithInitializeClient(func(dockerCli *command.DockerCli) (client.APIClient, error) {
|
||||
return func(cli *command.DockerCli) error {
|
||||
cmd := "docker"
|
||||
if x := os.Getenv(metadata.ReexecEnvvar); x != "" {
|
||||
cmd = x
|
||||
@@ -133,11 +133,14 @@ func withPluginClientConn(name string) command.CLIOption {
|
||||
|
||||
helper, err := connhelper.GetCommandConnectionHelper(cmd, flags...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
return client.NewClientWithOpts(client.WithDialContext(helper.Dialer))
|
||||
})
|
||||
apiClient, err := client.NewClientWithOpts(client.WithDialContext(helper.Dialer))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return command.WithAPIClient(apiClient)(cli)
|
||||
}
|
||||
}
|
||||
|
||||
func newPluginCommand(dockerCli *command.DockerCli, plugin *cobra.Command, meta metadata.Metadata) *cli.TopLevelCommand {
|
||||
|
||||
+3
-12
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/docker/cli/cli/version"
|
||||
dopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
@@ -180,7 +180,7 @@ func (cli *DockerCli) BuildKitEnabled() (bool, error) {
|
||||
}
|
||||
|
||||
si := cli.ServerInfo()
|
||||
if si.BuildkitVersion == types.BuilderBuildKit {
|
||||
if si.BuildkitVersion == build.BuilderBuildKit {
|
||||
// The daemon advertised BuildKit as the preferred builder; this may
|
||||
// be either a Linux daemon or a Windows daemon with experimental
|
||||
// BuildKit support enabled.
|
||||
@@ -222,15 +222,6 @@ func (cli *DockerCli) HooksEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// WithInitializeClient is passed to DockerCli.Initialize by callers who wish to set a particular API Client for use by the CLI.
|
||||
func WithInitializeClient(makeClient func(dockerCli *DockerCli) (client.APIClient, error)) CLIOption {
|
||||
return func(dockerCli *DockerCli) error {
|
||||
var err error
|
||||
dockerCli.client, err = makeClient(dockerCli)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the dockerCli runs initialization that must happen after command
|
||||
// line flags are parsed.
|
||||
func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption) error {
|
||||
@@ -519,7 +510,7 @@ func (cli *DockerCli) Apply(ops ...CLIOption) error {
|
||||
type ServerInfo struct {
|
||||
HasExperimental bool
|
||||
OSType string
|
||||
BuildkitVersion types.BuilderVersion
|
||||
BuildkitVersion build.BuilderVersion
|
||||
|
||||
// SwarmStatus provides information about the current swarm status of the
|
||||
// engine, obtained from the "Swarm" header in the API response.
|
||||
|
||||
+15
-4
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/moby/term"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -115,6 +114,18 @@ func WithAPIClient(c client.APIClient) CLIOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithInitializeClient is passed to [DockerCli.Initialize] to initialize
|
||||
// an API Client for use by the CLI.
|
||||
func WithInitializeClient(makeClient func(*DockerCli) (client.APIClient, error)) CLIOption {
|
||||
return func(cli *DockerCli) error {
|
||||
c, err := makeClient(cli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return WithAPIClient(c)(cli)
|
||||
}
|
||||
}
|
||||
|
||||
// envOverrideHTTPHeaders is the name of the environment-variable that can be
|
||||
// used to set custom HTTP headers to be sent by the client. This environment
|
||||
// variable is the equivalent to the HttpHeaders field in the configuration
|
||||
@@ -178,7 +189,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||
csvReader := csv.NewReader(strings.NewReader(value))
|
||||
fields, err := csvReader.Read()
|
||||
if err != nil {
|
||||
return errdefs.InvalidParameter(errors.Errorf(
|
||||
return invalidParameter(errors.Errorf(
|
||||
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
|
||||
envOverrideHTTPHeaders,
|
||||
))
|
||||
@@ -195,7 +206,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||
k = strings.TrimSpace(k)
|
||||
|
||||
if k == "" {
|
||||
return errdefs.InvalidParameter(errors.Errorf(
|
||||
return invalidParameter(errors.Errorf(
|
||||
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
@@ -206,7 +217,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||
// from an environment variable with the same name). In the meantime,
|
||||
// produce an error to prevent users from depending on this.
|
||||
if !hasValue {
|
||||
return errdefs.InvalidParameter(errors.Errorf(
|
||||
return invalidParameter(errors.Errorf(
|
||||
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
|
||||
envOverrideHTTPHeaders, kv,
|
||||
))
|
||||
|
||||
+5
-6
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/docker/cli/cli/context/docker"
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
cliflags "github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -117,7 +116,7 @@ func (s *ContextStoreWithDefault) List() ([]store.Metadata, error) {
|
||||
// CreateOrUpdate is not allowed for the default context and fails
|
||||
func (s *ContextStoreWithDefault) CreateOrUpdate(meta store.Metadata) error {
|
||||
if meta.Name == DefaultContextName {
|
||||
return errdefs.InvalidParameter(errors.New("default context cannot be created nor updated"))
|
||||
return invalidParameter(errors.New("default context cannot be created nor updated"))
|
||||
}
|
||||
return s.Store.CreateOrUpdate(meta)
|
||||
}
|
||||
@@ -125,7 +124,7 @@ func (s *ContextStoreWithDefault) CreateOrUpdate(meta store.Metadata) error {
|
||||
// Remove is not allowed for the default context and fails
|
||||
func (s *ContextStoreWithDefault) Remove(name string) error {
|
||||
if name == DefaultContextName {
|
||||
return errdefs.InvalidParameter(errors.New("default context cannot be removed"))
|
||||
return invalidParameter(errors.New("default context cannot be removed"))
|
||||
}
|
||||
return s.Store.Remove(name)
|
||||
}
|
||||
@@ -145,7 +144,7 @@ func (s *ContextStoreWithDefault) GetMetadata(name string) (store.Metadata, erro
|
||||
// ResetTLSMaterial is not implemented for default context and fails
|
||||
func (s *ContextStoreWithDefault) ResetTLSMaterial(name string, data *store.ContextTLSData) error {
|
||||
if name == DefaultContextName {
|
||||
return errdefs.InvalidParameter(errors.New("default context cannot be edited"))
|
||||
return invalidParameter(errors.New("default context cannot be edited"))
|
||||
}
|
||||
return s.Store.ResetTLSMaterial(name, data)
|
||||
}
|
||||
@@ -153,7 +152,7 @@ func (s *ContextStoreWithDefault) ResetTLSMaterial(name string, data *store.Cont
|
||||
// ResetEndpointTLSMaterial is not implemented for default context and fails
|
||||
func (s *ContextStoreWithDefault) ResetEndpointTLSMaterial(contextName string, endpointName string, data *store.EndpointTLSData) error {
|
||||
if contextName == DefaultContextName {
|
||||
return errdefs.InvalidParameter(errors.New("default context cannot be edited"))
|
||||
return invalidParameter(errors.New("default context cannot be edited"))
|
||||
}
|
||||
return s.Store.ResetEndpointTLSMaterial(contextName, endpointName, data)
|
||||
}
|
||||
@@ -186,7 +185,7 @@ func (s *ContextStoreWithDefault) GetTLSData(contextName, endpointName, fileName
|
||||
return nil, err
|
||||
}
|
||||
if defaultContext.TLS.Endpoints[endpointName].Files[fileName] == nil {
|
||||
return nil, errdefs.NotFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
||||
return nil, notFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
||||
}
|
||||
return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil
|
||||
}
|
||||
|
||||
+4
-4
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
@@ -52,7 +52,7 @@ shared: {{.Shared}}
|
||||
return Format(source)
|
||||
}
|
||||
|
||||
func buildCacheSort(buildCache []*types.BuildCache) {
|
||||
func buildCacheSort(buildCache []*build.CacheRecord) {
|
||||
sort.Slice(buildCache, func(i, j int) bool {
|
||||
lui, luj := buildCache[i].LastUsedAt, buildCache[j].LastUsedAt
|
||||
switch {
|
||||
@@ -71,7 +71,7 @@ func buildCacheSort(buildCache []*types.BuildCache) {
|
||||
}
|
||||
|
||||
// BuildCacheWrite renders the context for a list of containers
|
||||
func BuildCacheWrite(ctx Context, buildCaches []*types.BuildCache) error {
|
||||
func BuildCacheWrite(ctx Context, buildCaches []*build.CacheRecord) error {
|
||||
render := func(format func(subContext SubContext) error) error {
|
||||
buildCacheSort(buildCaches)
|
||||
for _, bc := range buildCaches {
|
||||
@@ -88,7 +88,7 @@ func BuildCacheWrite(ctx Context, buildCaches []*types.BuildCache) error {
|
||||
type buildCacheContext struct {
|
||||
HeaderContext
|
||||
trunc bool
|
||||
v *types.BuildCache
|
||||
v *build.CacheRecord
|
||||
}
|
||||
|
||||
func newBuildCacheContext() *buildCacheContext {
|
||||
|
||||
+29
-6
@@ -11,10 +11,12 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/go-units"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,8 +28,18 @@ const (
|
||||
mountsHeader = "MOUNTS"
|
||||
localVolumes = "LOCAL VOLUMES"
|
||||
networksHeader = "NETWORKS"
|
||||
platformHeader = "PLATFORM"
|
||||
)
|
||||
|
||||
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
|
||||
type Platform struct {
|
||||
ocispec.Platform
|
||||
}
|
||||
|
||||
func (p Platform) String() string {
|
||||
return platforms.FormatAll(p.Platform)
|
||||
}
|
||||
|
||||
// NewContainerFormat returns a Format for rendering using a Context
|
||||
func NewContainerFormat(source string, quiet bool, size bool) Format {
|
||||
switch source {
|
||||
@@ -68,16 +80,14 @@ ports: {{- pad .Ports 1 0}}
|
||||
|
||||
// ContainerWrite renders the context for a list of containers
|
||||
func ContainerWrite(ctx Context, containers []container.Summary) error {
|
||||
render := func(format func(subContext SubContext) error) error {
|
||||
return ctx.Write(NewContainerContext(), func(format func(subContext SubContext) error) error {
|
||||
for _, ctr := range containers {
|
||||
err := format(&ContainerContext{trunc: ctx.Trunc, c: ctr})
|
||||
if err != nil {
|
||||
if err := format(&ContainerContext{trunc: ctx.Trunc, c: ctr}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return ctx.Write(NewContainerContext(), render)
|
||||
})
|
||||
}
|
||||
|
||||
// ContainerContext is a struct used for rendering a list of containers in a Go template.
|
||||
@@ -111,6 +121,7 @@ func NewContainerContext() *ContainerContext {
|
||||
"Mounts": mountsHeader,
|
||||
"LocalVolumes": localVolumes,
|
||||
"Networks": networksHeader,
|
||||
"Platform": platformHeader,
|
||||
}
|
||||
return &containerCtx
|
||||
}
|
||||
@@ -210,6 +221,16 @@ func (c *ContainerContext) RunningFor() string {
|
||||
return units.HumanDuration(time.Now().UTC().Sub(createdAt)) + " ago"
|
||||
}
|
||||
|
||||
// Platform returns a human-readable representation of the container's
|
||||
// platform if it is available.
|
||||
func (c *ContainerContext) Platform() *Platform {
|
||||
p := c.c.ImageManifestDescriptor
|
||||
if p == nil || p.Platform == nil {
|
||||
return nil
|
||||
}
|
||||
return &Platform{*p.Platform}
|
||||
}
|
||||
|
||||
// Ports returns a comma-separated string representing open ports of the container
|
||||
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
|
||||
// it's used by command 'docker ps'
|
||||
@@ -218,7 +239,8 @@ func (c *ContainerContext) Ports() string {
|
||||
return DisplayablePorts(c.c.Ports)
|
||||
}
|
||||
|
||||
// State returns the container's current state (e.g. "running" or "paused")
|
||||
// State returns the container's current state (e.g. "running" or "paused").
|
||||
// Refer to [container.ContainerState] for possible states.
|
||||
func (c *ContainerContext) State() string {
|
||||
return c.c.State
|
||||
}
|
||||
@@ -255,6 +277,7 @@ func (c *ContainerContext) Labels() string {
|
||||
for k, v := range c.c.Labels {
|
||||
joinLabels = append(joinLabels, k+"="+v)
|
||||
}
|
||||
sort.Strings(joinLabels)
|
||||
return strings.Join(joinLabels, ",")
|
||||
}
|
||||
|
||||
|
||||
+14
-9
@@ -4,11 +4,10 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
@@ -39,12 +38,12 @@ type DiskUsageContext struct {
|
||||
Images []*image.Summary
|
||||
Containers []*container.Summary
|
||||
Volumes []*volume.Volume
|
||||
BuildCache []*types.BuildCache
|
||||
BuildCache []*build.CacheRecord
|
||||
BuilderSize int64
|
||||
}
|
||||
|
||||
func (ctx *DiskUsageContext) startSubsection(format string) (*template.Template, error) {
|
||||
ctx.buffer = bytes.NewBufferString("")
|
||||
ctx.buffer = &bytes.Buffer{}
|
||||
ctx.header = ""
|
||||
ctx.Format = Format(format)
|
||||
ctx.preFormat()
|
||||
@@ -88,7 +87,7 @@ func (ctx *DiskUsageContext) Write() (err error) {
|
||||
if ctx.Verbose {
|
||||
return ctx.verboseWrite()
|
||||
}
|
||||
ctx.buffer = bytes.NewBufferString("")
|
||||
ctx.buffer = &bytes.Buffer{}
|
||||
ctx.preFormat()
|
||||
|
||||
tmpl, err := ctx.parseFormat()
|
||||
@@ -330,9 +329,15 @@ func (c *diskUsageContainersContext) TotalCount() string {
|
||||
}
|
||||
|
||||
func (*diskUsageContainersContext) isActive(ctr container.Summary) bool {
|
||||
return strings.Contains(ctr.State, "running") ||
|
||||
strings.Contains(ctr.State, "paused") ||
|
||||
strings.Contains(ctr.State, "restarting")
|
||||
switch ctr.State {
|
||||
case container.StateRunning, container.StatePaused, container.StateRestarting:
|
||||
return true
|
||||
case container.StateCreated, container.StateRemoving, container.StateExited, container.StateDead:
|
||||
return false
|
||||
default:
|
||||
// Unknown state (should never happen).
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (c *diskUsageContainersContext) Active() string {
|
||||
@@ -436,7 +441,7 @@ func (c *diskUsageVolumesContext) Reclaimable() string {
|
||||
type diskUsageBuilderContext struct {
|
||||
HeaderContext
|
||||
builderSize int64
|
||||
buildCache []*types.BuildCache
|
||||
buildCache []*build.CacheRecord
|
||||
}
|
||||
|
||||
func (c *diskUsageBuilderContext) MarshalJSON() ([]byte, error) {
|
||||
|
||||
+2
@@ -20,6 +20,8 @@ func charWidth(r rune) int {
|
||||
switch width.LookupRune(r).Kind() {
|
||||
case width.EastAsianWide, width.EastAsianFullwidth:
|
||||
return 2
|
||||
case width.Neutral, width.EastAsianAmbiguous, width.EastAsianNarrow, width.EastAsianHalfwidth:
|
||||
return 1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
|
||||
+4
-1
@@ -82,6 +82,9 @@ func (c *Context) parseFormat() (*template.Template, error) {
|
||||
}
|
||||
|
||||
func (c *Context) postFormat(tmpl *template.Template, subContext SubContext) {
|
||||
if c.Output == nil {
|
||||
c.Output = io.Discard
|
||||
}
|
||||
if c.Format.IsTable() {
|
||||
t := tabwriter.NewWriter(c.Output, 10, 1, 3, ' ', 0)
|
||||
buffer := bytes.NewBufferString("")
|
||||
@@ -111,7 +114,7 @@ type SubFormat func(func(SubContext) error) error
|
||||
|
||||
// Write the template to the buffer using this Context
|
||||
func (c *Context) Write(sub SubContext, f SubFormat) error {
|
||||
c.buffer = bytes.NewBufferString("")
|
||||
c.buffer = &bytes.Buffer{}
|
||||
c.preFormat()
|
||||
|
||||
tmpl, err := c.parseFormat()
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
|
||||
// based on https://github.com/golang/go/blob/master/src/text/tabwriter/tabwriter.go Last modified 690ac40 on 31 Jan
|
||||
|
||||
//nolint:gocyclo,nakedret,stylecheck,unused // ignore linting errors, so that we can stick close to upstream
|
||||
//nolint:gocyclo,nakedret,unused // ignore linting errors, so that we can stick close to upstream
|
||||
package tabwriter
|
||||
|
||||
import (
|
||||
|
||||
+19
@@ -151,3 +151,22 @@ func ValidateOutputPathFileMode(fileMode os.FileMode) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func invalidParameter(err error) error {
|
||||
return invalidParameterErr{err}
|
||||
}
|
||||
|
||||
type invalidParameterErr struct{ error }
|
||||
|
||||
func (invalidParameterErr) InvalidParameter() {}
|
||||
|
||||
func notFound(err error) error {
|
||||
return notFoundErr{err}
|
||||
}
|
||||
|
||||
type notFoundErr struct{ error }
|
||||
|
||||
func (notFoundErr) NotFound() {}
|
||||
func (e notFoundErr) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
+10
-3
@@ -152,7 +152,8 @@ func (configFile *ConfigFile) Save() (retErr error) {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
temp.Close()
|
||||
// ignore error as the file may already be closed when we reach this.
|
||||
_ = temp.Close()
|
||||
if retErr != nil {
|
||||
if err := os.Remove(temp.Name()); err != nil {
|
||||
logrus.WithError(err).WithField("file", temp.Name()).Debug("Error cleaning up temp file")
|
||||
@@ -169,10 +170,16 @@ func (configFile *ConfigFile) Save() (retErr error) {
|
||||
return errors.Wrap(err, "error closing temp file")
|
||||
}
|
||||
|
||||
// Handle situation where the configfile is a symlink
|
||||
// Handle situation where the configfile is a symlink, and allow for dangling symlinks
|
||||
cfgFile := configFile.Filename
|
||||
if f, err := os.Readlink(cfgFile); err == nil {
|
||||
if f, err := filepath.EvalSymlinks(cfgFile); err == nil {
|
||||
cfgFile = f
|
||||
} else if os.IsNotExist(err) {
|
||||
// extract the path from the error if the configfile does not exist or is a dangling symlink
|
||||
var pathError *os.PathError
|
||||
if errors.As(err, &pathError) {
|
||||
cfgFile = pathError.Path
|
||||
}
|
||||
}
|
||||
|
||||
// Try copying the current config file (if any) ownership and permissions
|
||||
|
||||
+2
-3
@@ -28,7 +28,6 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -149,7 +148,7 @@ func (c *commandConn) handleEOF(err error) error {
|
||||
c.stderrMu.Lock()
|
||||
stderr := c.stderr.String()
|
||||
c.stderrMu.Unlock()
|
||||
return errors.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, err, stderr)
|
||||
return fmt.Errorf("command %v did not exit after %v: stderr=%q", c.cmd.Args, err, stderr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +158,7 @@ func (c *commandConn) handleEOF(err error) error {
|
||||
c.stderrMu.Lock()
|
||||
stderr := c.stderr.String()
|
||||
c.stderrMu.Unlock()
|
||||
return errors.Errorf("command %v has exited with %v, make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr)
|
||||
return fmt.Errorf("command %v has exited with %v, make sure the URL is valid, and Docker 18.09 or later is installed on the remote host: stderr=%s", c.cmd.Args, werr, stderr)
|
||||
}
|
||||
|
||||
func ignorableCloseError(err error) bool {
|
||||
|
||||
+3
-3
@@ -3,13 +3,13 @@ package connhelper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/connhelper/commandconn"
|
||||
"github.com/docker/cli/cli/connhelper/ssh"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ConnectionHelper allows to connect to a remote host with custom stream provider binary.
|
||||
@@ -41,9 +41,9 @@ func getConnectionHelper(daemonURL string, sshFlags []string) (*ConnectionHelper
|
||||
return nil, err
|
||||
}
|
||||
if u.Scheme == "ssh" {
|
||||
sp, err := ssh.ParseURL(daemonURL)
|
||||
sp, err := ssh.NewSpec(u)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ssh host connection is not valid")
|
||||
return nil, fmt.Errorf("ssh host connection is not valid: %w", err)
|
||||
}
|
||||
sshFlags = addSSHTimeout(sshFlags)
|
||||
sshFlags = disablePseudoTerminalAllocation(sshFlags)
|
||||
|
||||
+37
-9
@@ -2,19 +2,46 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ParseURL parses URL
|
||||
// ParseURL creates a [Spec] from the given ssh URL. It returns an error if
|
||||
// the URL is using the wrong scheme, contains fragments, query-parameters,
|
||||
// or contains a password.
|
||||
func ParseURL(daemonURL string) (*Spec, error) {
|
||||
u, err := url.Parse(daemonURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var urlErr *url.Error
|
||||
if errors.As(err, &urlErr) {
|
||||
err = urlErr.Unwrap()
|
||||
}
|
||||
return nil, fmt.Errorf("invalid SSH URL: %w", err)
|
||||
}
|
||||
return NewSpec(u)
|
||||
}
|
||||
|
||||
// NewSpec creates a [Spec] from the given ssh URL's properties. It returns
|
||||
// an error if the URL is using the wrong scheme, contains fragments,
|
||||
// query-parameters, or contains a password.
|
||||
func NewSpec(sshURL *url.URL) (*Spec, error) {
|
||||
s, err := newSpec(sshURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid SSH URL: %w", err)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func newSpec(u *url.URL) (*Spec, error) {
|
||||
if u == nil {
|
||||
return nil, errors.New("URL is nil")
|
||||
}
|
||||
if u.Scheme == "" {
|
||||
return nil, errors.New("no scheme provided")
|
||||
}
|
||||
if u.Scheme != "ssh" {
|
||||
return nil, errors.Errorf("expected scheme ssh, got %q", u.Scheme)
|
||||
return nil, errors.New("incorrect scheme: " + u.Scheme)
|
||||
}
|
||||
|
||||
var sp Spec
|
||||
@@ -27,17 +54,18 @@ func ParseURL(daemonURL string) (*Spec, error) {
|
||||
}
|
||||
sp.Host = u.Hostname()
|
||||
if sp.Host == "" {
|
||||
return nil, errors.Errorf("no host specified")
|
||||
return nil, errors.New("hostname is empty")
|
||||
}
|
||||
sp.Port = u.Port()
|
||||
sp.Path = u.Path
|
||||
if u.RawQuery != "" {
|
||||
return nil, errors.Errorf("extra query after the host: %q", u.RawQuery)
|
||||
return nil, fmt.Errorf("query parameters are not allowed: %q", u.RawQuery)
|
||||
}
|
||||
if u.Fragment != "" {
|
||||
return nil, errors.Errorf("extra fragment after the host: %q", u.Fragment)
|
||||
return nil, fmt.Errorf("fragments are not allowed: %q", u.Fragment)
|
||||
}
|
||||
return &sp, err
|
||||
|
||||
return &sp, nil
|
||||
}
|
||||
|
||||
// Spec of SSH URL
|
||||
|
||||
+24
-7
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/pem"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/cli/cli/connhelper"
|
||||
@@ -90,14 +91,19 @@ func (ep *Endpoint) ClientOpts() ([]client.Opt, error) {
|
||||
return nil, err
|
||||
}
|
||||
if helper == nil {
|
||||
tlsConfig, err := ep.tlsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// Check if we're connecting over a socket, because there's no
|
||||
// need to configure TLS for a socket connection.
|
||||
//
|
||||
// TODO(thaJeztah); make resolveDockerEndpoint and resolveDefaultDockerEndpoint not load TLS data,
|
||||
// and load TLS files lazily; see https://github.com/docker/cli/pull/1581
|
||||
if !isSocket(ep.Host) {
|
||||
tlsConfig, err := ep.tlsConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, withHTTPClient(tlsConfig))
|
||||
}
|
||||
result = append(result,
|
||||
withHTTPClient(tlsConfig),
|
||||
client.WithHost(ep.Host),
|
||||
)
|
||||
result = append(result, client.WithHost(ep.Host))
|
||||
} else {
|
||||
result = append(result,
|
||||
client.WithHTTPClient(&http.Client{
|
||||
@@ -116,6 +122,17 @@ func (ep *Endpoint) ClientOpts() ([]client.Opt, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// isSocket checks if the given address is a Unix-socket (linux),
|
||||
// named pipe (Windows), or file-descriptor.
|
||||
func isSocket(addr string) bool {
|
||||
switch proto, _, _ := strings.Cut(addr, "://"); proto {
|
||||
case "unix", "npipe", "fd":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func withHTTPClient(tlsConfig *tls.Config) func(*client.Client) error {
|
||||
return func(c *client.Client) error {
|
||||
if tlsConfig == nil {
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package store
|
||||
|
||||
import cerrdefs "github.com/containerd/errdefs"
|
||||
|
||||
func invalidParameter(err error) error {
|
||||
if err == nil || cerrdefs.IsInvalidArgument(err) {
|
||||
return err
|
||||
}
|
||||
return invalidParameterErr{err}
|
||||
}
|
||||
|
||||
type invalidParameterErr struct{ error }
|
||||
|
||||
func (invalidParameterErr) InvalidParameter() {}
|
||||
|
||||
func notFound(err error) error {
|
||||
if err == nil || cerrdefs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return notFoundErr{err}
|
||||
}
|
||||
|
||||
type notFoundErr struct{ error }
|
||||
|
||||
func (notFoundErr) NotFound() {}
|
||||
func (e notFoundErr) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
+5
-6
@@ -5,16 +5,15 @@ package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/moby/sys/atomicwriter"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,7 +63,7 @@ func parseTypedOrMap(payload []byte, getter TypeGetter) (any, error) {
|
||||
func (s *metadataStore) get(name string) (Metadata, error) {
|
||||
m, err := s.getByID(contextdirOf(name))
|
||||
if err != nil {
|
||||
return m, errors.Wrapf(err, "context %q", name)
|
||||
return m, fmt.Errorf("context %q: %w", name, err)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
@@ -74,7 +73,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
|
||||
bytes, err := os.ReadFile(fileName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return Metadata{}, errdefs.NotFound(errors.Wrap(err, "context not found"))
|
||||
return Metadata{}, notFound(fmt.Errorf("context not found: %w", err))
|
||||
}
|
||||
return Metadata{}, err
|
||||
}
|
||||
@@ -99,7 +98,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
|
||||
|
||||
func (s *metadataStore) remove(name string) error {
|
||||
if err := os.RemoveAll(s.contextDir(contextdirOf(name))); err != nil {
|
||||
return errors.Wrapf(err, "failed to remove metadata")
|
||||
return fmt.Errorf("failed to remove metadata: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -119,7 +118,7 @@ func (s *metadataStore) list() ([]Metadata, error) {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
return nil, errors.Wrap(err, "failed to read metadata")
|
||||
return nil, fmt.Errorf("failed to read metadata: %w", err)
|
||||
}
|
||||
res = append(res, c)
|
||||
}
|
||||
|
||||
+9
-9
@@ -10,6 +10,8 @@ import (
|
||||
"bytes"
|
||||
_ "crypto/sha256" // ensure ids can be computed
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
@@ -17,9 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
@@ -146,10 +146,10 @@ func (s *ContextStore) CreateOrUpdate(meta Metadata) error {
|
||||
// Remove deletes the context with the given name, if found.
|
||||
func (s *ContextStore) Remove(name string) error {
|
||||
if err := s.meta.remove(name); err != nil {
|
||||
return errors.Wrapf(err, "failed to remove context %s", name)
|
||||
return fmt.Errorf("failed to remove context %s: %w", name, err)
|
||||
}
|
||||
if err := s.tls.remove(name); err != nil {
|
||||
return errors.Wrapf(err, "failed to remove context %s", name)
|
||||
return fmt.Errorf("failed to remove context %s: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func ValidateContextName(name string) error {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return errors.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -374,7 +374,7 @@ func importTar(name string, s Writer, reader io.Reader) error {
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(hdr.Name); err != nil {
|
||||
return errors.Wrap(err, hdr.Name)
|
||||
return fmt.Errorf("%s: %w", hdr.Name, err)
|
||||
}
|
||||
if hdr.Name == metaFile {
|
||||
data, err := io.ReadAll(tr)
|
||||
@@ -400,7 +400,7 @@ func importTar(name string, s Writer, reader io.Reader) error {
|
||||
}
|
||||
}
|
||||
if !importedMetaFile {
|
||||
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
|
||||
return invalidParameter(errors.New("invalid context: no metadata found"))
|
||||
}
|
||||
return s.ResetTLSMaterial(name, &tlsData)
|
||||
}
|
||||
@@ -426,7 +426,7 @@ func importZip(name string, s Writer, reader io.Reader) error {
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(zf.Name); err != nil {
|
||||
return errors.Wrap(err, zf.Name)
|
||||
return fmt.Errorf("%s: %w", zf.Name, err)
|
||||
}
|
||||
if zf.Name == metaFile {
|
||||
f, err := zf.Open()
|
||||
@@ -464,7 +464,7 @@ func importZip(name string, s Writer, reader io.Reader) error {
|
||||
}
|
||||
}
|
||||
if !importedMetaFile {
|
||||
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
|
||||
return invalidParameter(errors.New("invalid context: no metadata found"))
|
||||
}
|
||||
return s.ResetTLSMaterial(name, &tlsData)
|
||||
}
|
||||
|
||||
+7
-8
@@ -1,12 +1,11 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/moby/sys/atomicwriter"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const tlsDir = "tls"
|
||||
@@ -39,9 +38,9 @@ func (s *tlsStore) getData(name, endpointName, filename string) ([]byte, error)
|
||||
data, err := os.ReadFile(filepath.Join(s.endpointDir(name, endpointName), filename))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, errdefs.NotFound(errors.Errorf("TLS data for %s/%s/%s does not exist", name, endpointName, filename))
|
||||
return nil, notFound(fmt.Errorf("TLS data for %s/%s/%s does not exist", name, endpointName, filename))
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to read TLS data for endpoint %s", endpointName)
|
||||
return nil, fmt.Errorf("failed to read TLS data for endpoint %s: %w", endpointName, err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
@@ -49,14 +48,14 @@ func (s *tlsStore) getData(name, endpointName, filename string) ([]byte, error)
|
||||
// remove deletes all TLS data for the given context.
|
||||
func (s *tlsStore) remove(name string) error {
|
||||
if err := os.RemoveAll(s.contextDir(name)); err != nil {
|
||||
return errors.Wrapf(err, "failed to remove TLS data")
|
||||
return fmt.Errorf("failed to remove TLS data: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *tlsStore) removeEndpoint(name, endpointName string) error {
|
||||
if err := os.RemoveAll(s.endpointDir(name, endpointName)); err != nil {
|
||||
return errors.Wrapf(err, "failed to remove TLS data for endpoint %s", endpointName)
|
||||
return fmt.Errorf("failed to remove TLS data for endpoint %s: %w", endpointName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -68,7 +67,7 @@ func (s *tlsStore) listContextData(name string) (map[string]EndpointFiles, error
|
||||
if os.IsNotExist(err) {
|
||||
return map[string]EndpointFiles{}, nil
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to list TLS files for context %s", name)
|
||||
return nil, fmt.Errorf("failed to list TLS files for context %s: %w", name, err)
|
||||
}
|
||||
r := make(map[string]EndpointFiles)
|
||||
for _, epFS := range epFSs {
|
||||
@@ -78,7 +77,7 @@ func (s *tlsStore) listContextData(name string) (map[string]EndpointFiles, error
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to list TLS files for endpoint %s", epFS.Name())
|
||||
return nil, fmt.Errorf("failed to list TLS files for endpoint %s: %w", epFS.Name(), err)
|
||||
}
|
||||
var files EndpointFiles
|
||||
for _, fs := range fss {
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ func (m *MountOpt) Set(value string) error {
|
||||
mount.Type = mounttypes.Type(strings.ToLower(val))
|
||||
case "source", "src":
|
||||
mount.Source = val
|
||||
if strings.HasPrefix(val, "."+string(filepath.Separator)) || val == "." {
|
||||
if !filepath.IsAbs(val) && strings.HasPrefix(val, ".") {
|
||||
if abs, err := filepath.Abs(val); err == nil {
|
||||
mount.Source = abs
|
||||
}
|
||||
|
||||
+12
@@ -80,10 +80,22 @@ func (opts *ListOpts) GetMap() map[string]struct{} {
|
||||
}
|
||||
|
||||
// GetAll returns the values of slice.
|
||||
//
|
||||
// Deprecated: use [ListOpts.GetSlice] instead. This method will be removed in a future release.
|
||||
func (opts *ListOpts) GetAll() []string {
|
||||
return *opts.values
|
||||
}
|
||||
|
||||
// GetSlice returns the values of slice.
|
||||
//
|
||||
// It implements [cobra.SliceValue] to allow shell completion to be provided
|
||||
// multiple times.
|
||||
//
|
||||
// [cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
|
||||
func (opts *ListOpts) GetSlice() []string {
|
||||
return *opts.values
|
||||
}
|
||||
|
||||
// GetAllOrEmpty returns the values of the slice
|
||||
// or an empty slice when there are no values.
|
||||
func (opts *ListOpts) GetAllOrEmpty() []string {
|
||||
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package errdefs
|
||||
|
||||
// ErrNotFound signals that the requested object doesn't exist
|
||||
type ErrNotFound interface {
|
||||
NotFound()
|
||||
}
|
||||
|
||||
// ErrInvalidParameter signals that the user input is invalid
|
||||
type ErrInvalidParameter interface {
|
||||
InvalidParameter()
|
||||
}
|
||||
|
||||
// ErrConflict signals that some internal state conflicts with the requested action and can't be performed.
|
||||
// A change in state should be able to clear this error.
|
||||
type ErrConflict interface {
|
||||
Conflict()
|
||||
}
|
||||
|
||||
// ErrUnauthorized is used to signify that the user is not authorized to perform a specific action
|
||||
type ErrUnauthorized interface {
|
||||
Unauthorized()
|
||||
}
|
||||
|
||||
// ErrUnavailable signals that the requested action/subsystem is not available.
|
||||
type ErrUnavailable interface {
|
||||
Unavailable()
|
||||
}
|
||||
|
||||
// ErrForbidden signals that the requested action cannot be performed under any circumstances.
|
||||
// When a ErrForbidden is returned, the caller should never retry the action.
|
||||
type ErrForbidden interface {
|
||||
Forbidden()
|
||||
}
|
||||
|
||||
// ErrSystem signals that some internal error occurred.
|
||||
// An example of this would be a failed mount request.
|
||||
type ErrSystem interface {
|
||||
System()
|
||||
}
|
||||
|
||||
// ErrNotModified signals that an action can't be performed because it's already in the desired state
|
||||
type ErrNotModified interface {
|
||||
NotModified()
|
||||
}
|
||||
|
||||
// ErrNotImplemented signals that the requested action/feature is not implemented on the system as configured.
|
||||
type ErrNotImplemented interface {
|
||||
NotImplemented()
|
||||
}
|
||||
|
||||
// ErrUnknown signals that the kind of error that occurred is not known.
|
||||
type ErrUnknown interface {
|
||||
Unknown()
|
||||
}
|
||||
|
||||
// ErrCancelled signals that the action was cancelled.
|
||||
type ErrCancelled interface {
|
||||
Cancelled()
|
||||
}
|
||||
|
||||
// ErrDeadline signals that the deadline was reached before the action completed.
|
||||
type ErrDeadline interface {
|
||||
DeadlineExceeded()
|
||||
}
|
||||
|
||||
// ErrDataLoss indicates that data was lost or there is data corruption.
|
||||
type ErrDataLoss interface {
|
||||
DataLoss()
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
// Package errdefs defines a set of error interfaces that packages should use for communicating classes of errors.
|
||||
// Errors that cross the package boundary should implement one (and only one) of these interfaces.
|
||||
//
|
||||
// Packages should not reference these interfaces directly, only implement them.
|
||||
// To check if a particular error implements one of these interfaces, there are helper
|
||||
// functions provided (e.g. `Is<SomeError>`) which can be used rather than asserting the interfaces directly.
|
||||
// If you must assert on these interfaces, be sure to check the causal chain (`err.Unwrap()`).
|
||||
package errdefs // import "github.com/docker/docker/errdefs"
|
||||
-309
@@ -1,309 +0,0 @@
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
)
|
||||
|
||||
type errNotFound struct{ error }
|
||||
|
||||
func (errNotFound) NotFound() {}
|
||||
|
||||
func (e errNotFound) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errNotFound) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// NotFound creates an [ErrNotFound] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrNotFound],
|
||||
func NotFound(err error) error {
|
||||
if err == nil || cerrdefs.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return errNotFound{err}
|
||||
}
|
||||
|
||||
type errInvalidParameter struct{ error }
|
||||
|
||||
func (errInvalidParameter) InvalidParameter() {}
|
||||
|
||||
func (e errInvalidParameter) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errInvalidParameter) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// InvalidParameter creates an [ErrInvalidParameter] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrInvalidParameter],
|
||||
func InvalidParameter(err error) error {
|
||||
if err == nil || cerrdefs.IsInvalidArgument(err) {
|
||||
return err
|
||||
}
|
||||
return errInvalidParameter{err}
|
||||
}
|
||||
|
||||
type errConflict struct{ error }
|
||||
|
||||
func (errConflict) Conflict() {}
|
||||
|
||||
func (e errConflict) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errConflict) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Conflict creates an [ErrConflict] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrConflict],
|
||||
func Conflict(err error) error {
|
||||
if err == nil || cerrdefs.IsConflict(err) {
|
||||
return err
|
||||
}
|
||||
return errConflict{err}
|
||||
}
|
||||
|
||||
type errUnauthorized struct{ error }
|
||||
|
||||
func (errUnauthorized) Unauthorized() {}
|
||||
|
||||
func (e errUnauthorized) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errUnauthorized) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Unauthorized creates an [ErrUnauthorized] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrUnauthorized],
|
||||
func Unauthorized(err error) error {
|
||||
if err == nil || cerrdefs.IsUnauthorized(err) {
|
||||
return err
|
||||
}
|
||||
return errUnauthorized{err}
|
||||
}
|
||||
|
||||
type errUnavailable struct{ error }
|
||||
|
||||
func (errUnavailable) Unavailable() {}
|
||||
|
||||
func (e errUnavailable) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errUnavailable) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Unavailable creates an [ErrUnavailable] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrUnavailable],
|
||||
func Unavailable(err error) error {
|
||||
if err == nil || cerrdefs.IsUnavailable(err) {
|
||||
return err
|
||||
}
|
||||
return errUnavailable{err}
|
||||
}
|
||||
|
||||
type errForbidden struct{ error }
|
||||
|
||||
func (errForbidden) Forbidden() {}
|
||||
|
||||
func (e errForbidden) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errForbidden) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Forbidden creates an [ErrForbidden] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrForbidden],
|
||||
func Forbidden(err error) error {
|
||||
if err == nil || cerrdefs.IsPermissionDenied(err) {
|
||||
return err
|
||||
}
|
||||
return errForbidden{err}
|
||||
}
|
||||
|
||||
type errSystem struct{ error }
|
||||
|
||||
func (errSystem) System() {}
|
||||
|
||||
func (e errSystem) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errSystem) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// System creates an [ErrSystem] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrSystem],
|
||||
func System(err error) error {
|
||||
if err == nil || cerrdefs.IsInternal(err) {
|
||||
return err
|
||||
}
|
||||
return errSystem{err}
|
||||
}
|
||||
|
||||
type errNotModified struct{ error }
|
||||
|
||||
func (errNotModified) NotModified() {}
|
||||
|
||||
func (e errNotModified) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errNotModified) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// NotModified creates an [ErrNotModified] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [NotModified],
|
||||
func NotModified(err error) error {
|
||||
if err == nil || cerrdefs.IsNotModified(err) {
|
||||
return err
|
||||
}
|
||||
return errNotModified{err}
|
||||
}
|
||||
|
||||
type errNotImplemented struct{ error }
|
||||
|
||||
func (errNotImplemented) NotImplemented() {}
|
||||
|
||||
func (e errNotImplemented) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errNotImplemented) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// NotImplemented creates an [ErrNotImplemented] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrNotImplemented],
|
||||
func NotImplemented(err error) error {
|
||||
if err == nil || cerrdefs.IsNotImplemented(err) {
|
||||
return err
|
||||
}
|
||||
return errNotImplemented{err}
|
||||
}
|
||||
|
||||
type errUnknown struct{ error }
|
||||
|
||||
func (errUnknown) Unknown() {}
|
||||
|
||||
func (e errUnknown) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errUnknown) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Unknown creates an [ErrUnknown] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrUnknown],
|
||||
func Unknown(err error) error {
|
||||
if err == nil || cerrdefs.IsUnknown(err) {
|
||||
return err
|
||||
}
|
||||
return errUnknown{err}
|
||||
}
|
||||
|
||||
type errCancelled struct{ error }
|
||||
|
||||
func (errCancelled) Cancelled() {}
|
||||
|
||||
func (e errCancelled) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errCancelled) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Cancelled creates an [ErrCancelled] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrCancelled],
|
||||
func Cancelled(err error) error {
|
||||
if err == nil || cerrdefs.IsCanceled(err) {
|
||||
return err
|
||||
}
|
||||
return errCancelled{err}
|
||||
}
|
||||
|
||||
type errDeadline struct{ error }
|
||||
|
||||
func (errDeadline) DeadlineExceeded() {}
|
||||
|
||||
func (e errDeadline) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errDeadline) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Deadline creates an [ErrDeadline] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrDeadline],
|
||||
func Deadline(err error) error {
|
||||
if err == nil || cerrdefs.IsDeadlineExceeded(err) {
|
||||
return err
|
||||
}
|
||||
return errDeadline{err}
|
||||
}
|
||||
|
||||
type errDataLoss struct{ error }
|
||||
|
||||
func (errDataLoss) DataLoss() {}
|
||||
|
||||
func (e errDataLoss) Cause() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
func (e errDataLoss) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// DataLoss creates an [ErrDataLoss] error from the given error.
|
||||
// It returns the error as-is if it is either nil (no error) or already implements
|
||||
// [ErrDataLoss],
|
||||
func DataLoss(err error) error {
|
||||
if err == nil || cerrdefs.IsDataLoss(err) {
|
||||
return err
|
||||
}
|
||||
return errDataLoss{err}
|
||||
}
|
||||
|
||||
// FromContext returns the error class from the passed in context
|
||||
func FromContext(ctx context.Context) error {
|
||||
e := ctx.Err()
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if e == context.Canceled {
|
||||
return Cancelled(e)
|
||||
}
|
||||
if e == context.DeadlineExceeded {
|
||||
return Deadline(e)
|
||||
}
|
||||
return Unknown(e)
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// FromStatusCode creates an errdef error, based on the provided HTTP status-code
|
||||
//
|
||||
// Deprecated: Use [cerrdefs.ToNative] instead
|
||||
func FromStatusCode(err error, statusCode int) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
switch statusCode {
|
||||
case http.StatusNotFound:
|
||||
return NotFound(err)
|
||||
case http.StatusBadRequest:
|
||||
return InvalidParameter(err)
|
||||
case http.StatusConflict:
|
||||
return Conflict(err)
|
||||
case http.StatusUnauthorized:
|
||||
return Unauthorized(err)
|
||||
case http.StatusServiceUnavailable:
|
||||
return Unavailable(err)
|
||||
case http.StatusForbidden:
|
||||
return Forbidden(err)
|
||||
case http.StatusNotModified:
|
||||
return NotModified(err)
|
||||
case http.StatusNotImplemented:
|
||||
return NotImplemented(err)
|
||||
case http.StatusInternalServerError:
|
||||
if IsCancelled(err) || IsSystem(err) || IsUnknown(err) || IsDataLoss(err) || IsDeadline(err) {
|
||||
return err
|
||||
}
|
||||
return System(err)
|
||||
default:
|
||||
switch {
|
||||
case statusCode >= http.StatusOK && statusCode < http.StatusBadRequest:
|
||||
// it's a client error
|
||||
return err
|
||||
case statusCode >= http.StatusBadRequest && statusCode < http.StatusInternalServerError:
|
||||
return InvalidParameter(err)
|
||||
case statusCode >= http.StatusInternalServerError && statusCode < 600:
|
||||
return System(err)
|
||||
default:
|
||||
return Unknown(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package errdefs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
)
|
||||
|
||||
// IsNotFound returns if the passed in error is an [ErrNotFound],
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsNotFound]
|
||||
var IsNotFound = cerrdefs.IsNotFound
|
||||
|
||||
// IsInvalidParameter returns if the passed in error is an [ErrInvalidParameter].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsInvalidArgument]
|
||||
var IsInvalidParameter = cerrdefs.IsInvalidArgument
|
||||
|
||||
// IsConflict returns if the passed in error is an [ErrConflict].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsConflict]
|
||||
var IsConflict = cerrdefs.IsConflict
|
||||
|
||||
// IsUnauthorized returns if the passed in error is an [ErrUnauthorized].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsUnauthorized]
|
||||
var IsUnauthorized = cerrdefs.IsUnauthorized
|
||||
|
||||
// IsUnavailable returns if the passed in error is an [ErrUnavailable].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsUnavailable]
|
||||
var IsUnavailable = cerrdefs.IsUnavailable
|
||||
|
||||
// IsForbidden returns if the passed in error is an [ErrForbidden].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsPermissionDenied]
|
||||
var IsForbidden = cerrdefs.IsPermissionDenied
|
||||
|
||||
// IsSystem returns if the passed in error is an [ErrSystem].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsInternal]
|
||||
var IsSystem = cerrdefs.IsInternal
|
||||
|
||||
// IsNotModified returns if the passed in error is an [ErrNotModified].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsNotModified]
|
||||
var IsNotModified = cerrdefs.IsNotModified
|
||||
|
||||
// IsNotImplemented returns if the passed in error is an [ErrNotImplemented].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsNotImplemented]
|
||||
var IsNotImplemented = cerrdefs.IsNotImplemented
|
||||
|
||||
// IsUnknown returns if the passed in error is an [ErrUnknown].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsUnknown]
|
||||
var IsUnknown = cerrdefs.IsUnknown
|
||||
|
||||
// IsCancelled returns if the passed in error is an [ErrCancelled].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsCanceled]
|
||||
var IsCancelled = cerrdefs.IsCanceled
|
||||
|
||||
// IsDeadline returns if the passed in error is an [ErrDeadline].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsDeadlineExceeded]
|
||||
var IsDeadline = cerrdefs.IsDeadlineExceeded
|
||||
|
||||
// IsDataLoss returns if the passed in error is an [ErrDataLoss].
|
||||
//
|
||||
// Deprecated: use containerd [cerrdefs.IsDataLoss]
|
||||
var IsDataLoss = cerrdefs.IsDataLoss
|
||||
|
||||
// IsContext returns if the passed in error is due to context cancellation or deadline exceeded.
|
||||
func IsContext(err error) bool {
|
||||
return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)
|
||||
}
|
||||
Vendored
+1
-2
@@ -221,7 +221,7 @@ github.com/davecgh/go-spew/spew
|
||||
# github.com/distribution/reference v0.6.0
|
||||
## explicit; go 1.20
|
||||
github.com/distribution/reference
|
||||
# github.com/docker/cli v28.1.1+incompatible
|
||||
# github.com/docker/cli v28.2.1+incompatible
|
||||
## explicit
|
||||
github.com/docker/cli/cli
|
||||
github.com/docker/cli/cli-plugins/metadata
|
||||
@@ -281,7 +281,6 @@ github.com/docker/docker/api/types/time
|
||||
github.com/docker/docker/api/types/versions
|
||||
github.com/docker/docker/api/types/volume
|
||||
github.com/docker/docker/client
|
||||
github.com/docker/docker/errdefs
|
||||
github.com/docker/docker/internal/lazyregexp
|
||||
github.com/docker/docker/internal/multierror
|
||||
github.com/docker/docker/pkg/homedir
|
||||
|
||||
Reference in New Issue
Block a user