diff --git a/Dockerfile b/Dockerfile index 717cfc76..364d0cf8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ ARG GO_VERSION FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:latest AS goreleaser-xx -FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine3.14 AS base +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS base COPY --from=goreleaser-xx / / RUN apk add --no-cache ca-certificates gcc file git linux-headers musl-dev tar WORKDIR /src diff --git a/cmd/image.go b/cmd/image.go index 69caaded..d5fc45eb 100644 --- a/cmd/image.go +++ b/cmd/image.go @@ -9,6 +9,7 @@ import ( "time" "unicode" + "github.com/AlecAivazis/survey/v2" "github.com/crazy-max/diun/v4/pb" "github.com/docker/go-units" "github.com/jedib0t/go-pretty/v6/table" @@ -21,7 +22,7 @@ type ImageCmd struct { List ImageListCmd `kong:"cmd,default='1',help='List images in database.'"` Inspect ImageInspectCmd `kong:"cmd,help='Display information of an image in database.'"` Remove ImageRemoveCmd `kong:"cmd,help='Remove an image manifest from database.'"` - //Prune ImagePruneCmd `kong:"cmd,help='Remove unused manifests from the database.'"` + Prune ImagePruneCmd `kong:"cmd,help='Remove all manifests from the database.'"` } // ImageListCmd holds image list command @@ -48,6 +49,11 @@ func (s *ImageListCmd) Run(ctx *Context) error { return nil } + if len(il.Images) == 0 { + fmt.Println("No image found in the database") + return nil + } + t := table.NewWriter() t.SetOutputMirror(os.Stdout) t.AppendHeader(table.Row{"Name", "Manifests Count", "Latest Tag", "Latest Created", "Latest Digest"}) @@ -103,7 +109,6 @@ func (s *ImageInspectCmd) Run(ctx *Context) error { type ImageRemoveCmd struct { CliGlobals Image string `kong:"name='image',required,help='Image to remove.'"` - All bool `kong:"name='all',default='false',help='Remove all manifests from the database.'"` } func (s *ImageRemoveCmd) Run(ctx *Context) error { @@ -129,3 +134,62 @@ func (s *ImageRemoveCmd) Run(ctx *Context) error { return nil } + +// ImagePruneCmd holds image prune command +type ImagePruneCmd struct { + CliGlobals + //All bool `kong:"name='all',default='false',help='Remove all manifests from the database.'"` + //Filter string `kong:"name='filter',help='Provide filter values (e.g., until=24h).'"` + Force bool `kong:"name='force',default='false',help='Do not prompt for confirmation.'"` +} + +const ( + pruneAllWarning = `This will remove all manifests from the database. Are you sure you want to continue?` +) + +func (s *ImagePruneCmd) Run(ctx *Context) error { + defer s.conn.Close() + + if !s.Force { + var confirmed bool + prompt := &survey.Confirm{ + Message: pruneAllWarning, + } + if err := survey.AskOne(prompt, &confirmed); err != nil { + return err + } + if !confirmed { + return nil + } + } + + removed, err := s.imageSvc.ImagePrune(context.Background(), &pb.ImagePruneRequest{ + //All: s.All, + //Filter: s.Filter, + }) + if err != nil { + return err + } + + if len(removed.Images) == 0 { + fmt.Println("Nothing to be removed from the database") + return nil + } + + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{"Tag", "Created", "Digest", "Size"}) + var totalSize int64 + var totalManifest int + for _, image := range removed.Images { + for _, manifest := range image.Manifests { + t.AppendRow(table.Row{manifest.Tag, manifest.Created.AsTime().Format(time.RFC3339), manifest.Digest, units.HumanSize(float64(manifest.Size))}) + totalSize += manifest.Size + } + totalManifest += len(image.Manifests) + } + t.AppendFooter(table.Row{"Total", fmt.Sprintf("%d (%s)", totalManifest, units.HumanSize(float64(totalSize)))}) + t.Render() + + return nil +} diff --git a/docs/usage/command-line.md b/docs/usage/command-line.md index 4f997ce8..1cfe6b11 100644 --- a/docs/usage/command-line.md +++ b/docs/usage/command-line.md @@ -108,6 +108,22 @@ diun image inspect --image drone/drone !!! warning All manifest for an image will be removed if no tag is specified +### `image prune` + +!!! note + Diun needs to be started through [`serve`](#serve) command to be able to use this command. + +Remove all manifests from the database. + +* `--force`: Do not prompt for confirmation +* `--grpc-authority `: Link to Diun gRPC API (default `127.0.0.1:42286`) + +Examples: + +```shell +diun image prune +``` + ### `notif test` !!! note diff --git a/go.mod b/go.mod index 146c347c..0a99f64d 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/crazy-max/diun/v4 go 1.17 require ( + github.com/AlecAivazis/survey/v2 v2.3.2 github.com/alecthomas/kong v0.2.18 github.com/bmatcuk/doublestar/v3 v3.0.0 github.com/containerd/containerd v1.5.8 @@ -19,6 +20,7 @@ require ( github.com/gregdel/pushover v1.1.0 github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b github.com/imdario/mergo v0.3.12 + github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/matcornic/hermes/v2 v2.1.0 github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 github.com/microcosm-cc/bluemonday v1.0.16 @@ -83,13 +85,16 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/huandu/xstrings v1.2.0 // indirect github.com/jaytaylor/html2text v0.0.0-20180606194806-57d518f124b0 // indirect - github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/moby/sys/mountinfo v0.4.1 // indirect github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -115,7 +120,7 @@ require ( golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect + golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect golang.org/x/text v0.3.6 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/appengine v1.6.6 // indirect diff --git a/go.sum b/go.sum index 546e3cd4..af4551d9 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= github.com/AkihiroSuda/containerd-fuse-overlayfs v1.0.0/go.mod h1:0mMDvQFeLbbn1Wy8P2j3hwFhqBq+FKn8OZPno8WLmp8= +github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= +github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -140,6 +142,8 @@ github.com/Microsoft/hcsshim/test v0.0.0-20200826032352-301c83a30e7c/go.mod h1:3 github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk= @@ -382,6 +386,7 @@ github.com/crazy-max/gonfig v0.5.0 h1:Fb388ei7KOXK7lN5p/qtRpsVEAzwgJJTkjuzudw58F github.com/crazy-max/gonfig v0.5.0/go.mod h1:LsKZ9UBOt0BwMRyjct2u042IAq3Hs49BsMgR7OZ9Cbg= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= @@ -747,6 +752,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -796,6 +803,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -822,7 +831,9 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -853,6 +864,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= @@ -862,6 +874,7 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -878,6 +891,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.16 h1:kHmAq2t7WPWLjiGvzKa5o3HzSfahUKiOq7fAPUiMNIc= github.com/microcosm-cc/bluemonday v1.0.16/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= @@ -1169,6 +1183,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1313,6 +1328,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1539,8 +1555,9 @@ golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w= +golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/grpc/image.go b/internal/grpc/image.go index e02158fa..6d3a711f 100644 --- a/internal/grpc/image.go +++ b/internal/grpc/image.go @@ -121,3 +121,38 @@ func (c *Client) ImageRemove(ctx context.Context, request *pb.ImageRemoveRequest Manifests: removed, }, nil } + +func (c *Client) ImagePrune(ctx context.Context, request *pb.ImagePruneRequest) (*pb.ImagePruneResponse, error) { + images, err := c.db.ListImage() + if err != nil { + return nil, err + } + + var removed []*pb.ImagePruneResponse_Image + for n, m := range images { + var manifests []*pb.Manifest + for _, manifest := range m { + if err = c.db.DeleteManifest(manifest); err != nil { + return nil, err + } + b, _ := json.Marshal(manifest) + manifests = append(manifests, &pb.Manifest{ + Tag: manifest.Tag, + MimeType: manifest.MIMEType, + Digest: manifest.Digest.String(), + Created: timestamppb.New(*manifest.Created), + Labels: manifest.Labels, + Platform: manifest.Platform, + Size: int64(len(b)), + }) + } + removed = append(removed, &pb.ImagePruneResponse_Image{ + Name: n, + Manifests: manifests, + }) + } + + return &pb.ImagePruneResponse{ + Images: removed, + }, nil +} diff --git a/pb/image.pb.go b/pb/image.pb.go index 250cfa12..c1d85250 100644 --- a/pb/image.pb.go +++ b/pb/image.pb.go @@ -389,6 +389,108 @@ func (x *ImageRemoveResponse) GetManifests() []*Manifest { return nil } +type ImagePruneRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + All bool `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"` + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *ImagePruneRequest) Reset() { + *x = ImagePruneRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_image_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImagePruneRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImagePruneRequest) ProtoMessage() {} + +func (x *ImagePruneRequest) ProtoReflect() protoreflect.Message { + mi := &file_image_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImagePruneRequest.ProtoReflect.Descriptor instead. +func (*ImagePruneRequest) Descriptor() ([]byte, []int) { + return file_image_proto_rawDescGZIP(), []int{7} +} + +func (x *ImagePruneRequest) GetAll() bool { + if x != nil { + return x.All + } + return false +} + +func (x *ImagePruneRequest) GetFilter() string { + if x != nil { + return x.Filter + } + return "" +} + +type ImagePruneResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Images []*ImagePruneResponse_Image `protobuf:"bytes,1,rep,name=images,proto3" json:"images,omitempty"` +} + +func (x *ImagePruneResponse) Reset() { + *x = ImagePruneResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_image_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImagePruneResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImagePruneResponse) ProtoMessage() {} + +func (x *ImagePruneResponse) ProtoReflect() protoreflect.Message { + mi := &file_image_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImagePruneResponse.ProtoReflect.Descriptor instead. +func (*ImagePruneResponse) Descriptor() ([]byte, []int) { + return file_image_proto_rawDescGZIP(), []int{8} +} + +func (x *ImagePruneResponse) GetImages() []*ImagePruneResponse_Image { + if x != nil { + return x.Images + } + return nil +} + type ImageListResponse_Image struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -402,7 +504,7 @@ type ImageListResponse_Image struct { func (x *ImageListResponse_Image) Reset() { *x = ImageListResponse_Image{} if protoimpl.UnsafeEnabled { - mi := &file_image_proto_msgTypes[8] + mi := &file_image_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -415,7 +517,7 @@ func (x *ImageListResponse_Image) String() string { func (*ImageListResponse_Image) ProtoMessage() {} func (x *ImageListResponse_Image) ProtoReflect() protoreflect.Message { - mi := &file_image_proto_msgTypes[8] + mi := &file_image_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -464,7 +566,7 @@ type ImageInspectResponse_Image struct { func (x *ImageInspectResponse_Image) Reset() { *x = ImageInspectResponse_Image{} if protoimpl.UnsafeEnabled { - mi := &file_image_proto_msgTypes[9] + mi := &file_image_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -477,7 +579,7 @@ func (x *ImageInspectResponse_Image) String() string { func (*ImageInspectResponse_Image) ProtoMessage() {} func (x *ImageInspectResponse_Image) ProtoReflect() protoreflect.Message { - mi := &file_image_proto_msgTypes[9] + mi := &file_image_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -507,6 +609,61 @@ func (x *ImageInspectResponse_Image) GetManifests() []*Manifest { return nil } +type ImagePruneResponse_Image struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Manifests []*Manifest `protobuf:"bytes,2,rep,name=manifests,proto3" json:"manifests,omitempty"` +} + +func (x *ImagePruneResponse_Image) Reset() { + *x = ImagePruneResponse_Image{} + if protoimpl.UnsafeEnabled { + mi := &file_image_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImagePruneResponse_Image) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImagePruneResponse_Image) ProtoMessage() {} + +func (x *ImagePruneResponse_Image) ProtoReflect() protoreflect.Message { + mi := &file_image_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImagePruneResponse_Image.ProtoReflect.Descriptor instead. +func (*ImagePruneResponse_Image) Descriptor() ([]byte, []int) { + return file_image_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *ImagePruneResponse_Image) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ImagePruneResponse_Image) GetManifests() []*Manifest { + if x != nil { + return x.Manifests + } + return nil +} + var File_image_proto protoreflect.FileDescriptor var file_image_proto_rawDesc = []byte{ @@ -563,22 +720,40 @@ var file_image_proto_rawDesc = []byte{ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, - 0x73, 0x74, 0x73, 0x32, 0xd1, 0x01, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x43, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, - 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x62, 0x2e, 0x49, - 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, - 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1e, 0x5a, 0x1c, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x2d, 0x6d, 0x61, 0x78, 0x2f, - 0x64, 0x69, 0x75, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x22, 0x93, 0x01, 0x0a, 0x12, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x1a, + 0x47, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x09, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x09, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x32, 0x90, 0x02, 0x0a, 0x0c, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, + 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0b, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0a, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x50, 0x72, 0x75, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1e, 0x5a, 0x1c, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x2d, + 0x6d, 0x61, 0x78, 0x2f, 0x64, 0x69, 0x75, 0x6e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -593,7 +768,7 @@ func file_image_proto_rawDescGZIP() []byte { return file_image_proto_rawDescData } -var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_image_proto_goTypes = []interface{}{ (*Manifest)(nil), // 0: pb.Manifest (*ImageListRequest)(nil), // 1: pb.ImageListRequest @@ -602,30 +777,37 @@ var file_image_proto_goTypes = []interface{}{ (*ImageInspectResponse)(nil), // 4: pb.ImageInspectResponse (*ImageRemoveRequest)(nil), // 5: pb.ImageRemoveRequest (*ImageRemoveResponse)(nil), // 6: pb.ImageRemoveResponse - nil, // 7: pb.Manifest.LabelsEntry - (*ImageListResponse_Image)(nil), // 8: pb.ImageListResponse.Image - (*ImageInspectResponse_Image)(nil), // 9: pb.ImageInspectResponse.Image - (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp + (*ImagePruneRequest)(nil), // 7: pb.ImagePruneRequest + (*ImagePruneResponse)(nil), // 8: pb.ImagePruneResponse + nil, // 9: pb.Manifest.LabelsEntry + (*ImageListResponse_Image)(nil), // 10: pb.ImageListResponse.Image + (*ImageInspectResponse_Image)(nil), // 11: pb.ImageInspectResponse.Image + (*ImagePruneResponse_Image)(nil), // 12: pb.ImagePruneResponse.Image + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp } var file_image_proto_depIdxs = []int32{ - 10, // 0: pb.Manifest.created:type_name -> google.protobuf.Timestamp - 7, // 1: pb.Manifest.labels:type_name -> pb.Manifest.LabelsEntry - 8, // 2: pb.ImageListResponse.images:type_name -> pb.ImageListResponse.Image - 9, // 3: pb.ImageInspectResponse.image:type_name -> pb.ImageInspectResponse.Image + 13, // 0: pb.Manifest.created:type_name -> google.protobuf.Timestamp + 9, // 1: pb.Manifest.labels:type_name -> pb.Manifest.LabelsEntry + 10, // 2: pb.ImageListResponse.images:type_name -> pb.ImageListResponse.Image + 11, // 3: pb.ImageInspectResponse.image:type_name -> pb.ImageInspectResponse.Image 0, // 4: pb.ImageRemoveResponse.manifests:type_name -> pb.Manifest - 0, // 5: pb.ImageListResponse.Image.latest:type_name -> pb.Manifest - 0, // 6: pb.ImageInspectResponse.Image.manifests:type_name -> pb.Manifest - 1, // 7: pb.ImageService.ImageList:input_type -> pb.ImageListRequest - 3, // 8: pb.ImageService.ImageInspect:input_type -> pb.ImageInspectRequest - 5, // 9: pb.ImageService.ImageRemove:input_type -> pb.ImageRemoveRequest - 2, // 10: pb.ImageService.ImageList:output_type -> pb.ImageListResponse - 4, // 11: pb.ImageService.ImageInspect:output_type -> pb.ImageInspectResponse - 6, // 12: pb.ImageService.ImageRemove:output_type -> pb.ImageRemoveResponse - 10, // [10:13] is the sub-list for method output_type - 7, // [7:10] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 12, // 5: pb.ImagePruneResponse.images:type_name -> pb.ImagePruneResponse.Image + 0, // 6: pb.ImageListResponse.Image.latest:type_name -> pb.Manifest + 0, // 7: pb.ImageInspectResponse.Image.manifests:type_name -> pb.Manifest + 0, // 8: pb.ImagePruneResponse.Image.manifests:type_name -> pb.Manifest + 1, // 9: pb.ImageService.ImageList:input_type -> pb.ImageListRequest + 3, // 10: pb.ImageService.ImageInspect:input_type -> pb.ImageInspectRequest + 5, // 11: pb.ImageService.ImageRemove:input_type -> pb.ImageRemoveRequest + 7, // 12: pb.ImageService.ImagePrune:input_type -> pb.ImagePruneRequest + 2, // 13: pb.ImageService.ImageList:output_type -> pb.ImageListResponse + 4, // 14: pb.ImageService.ImageInspect:output_type -> pb.ImageInspectResponse + 6, // 15: pb.ImageService.ImageRemove:output_type -> pb.ImageRemoveResponse + 8, // 16: pb.ImageService.ImagePrune:output_type -> pb.ImagePruneResponse + 13, // [13:17] is the sub-list for method output_type + 9, // [9:13] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_image_proto_init() } @@ -718,7 +900,31 @@ func file_image_proto_init() { return nil } } + file_image_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImagePruneRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } file_image_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImagePruneResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_image_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImageListResponse_Image); i { case 0: return &v.state @@ -730,7 +936,7 @@ func file_image_proto_init() { return nil } } - file_image_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_image_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ImageInspectResponse_Image); i { case 0: return &v.state @@ -742,6 +948,18 @@ func file_image_proto_init() { return nil } } + file_image_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImagePruneResponse_Image); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -749,7 +967,7 @@ func file_image_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_image_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/pb/image.proto b/pb/image.proto index 9871297a..bd3fb1dd 100644 --- a/pb/image.proto +++ b/pb/image.proto @@ -46,8 +46,22 @@ message ImageRemoveResponse { repeated Manifest manifests = 1; } +message ImagePruneRequest { + bool all = 1; + string filter = 2; +} + +message ImagePruneResponse { + message Image { + string name = 1; + repeated Manifest manifests = 2; + } + repeated Image images = 1; +} + service ImageService { rpc ImageList(ImageListRequest) returns (ImageListResponse) {} rpc ImageInspect(ImageInspectRequest) returns (ImageInspectResponse) {} rpc ImageRemove(ImageRemoveRequest) returns (ImageRemoveResponse) {} + rpc ImagePrune(ImagePruneRequest) returns (ImagePruneResponse) {} } diff --git a/pb/image_grpc.pb.go b/pb/image_grpc.pb.go index d2028311..2500ec8b 100644 --- a/pb/image_grpc.pb.go +++ b/pb/image_grpc.pb.go @@ -21,6 +21,7 @@ type ImageServiceClient interface { ImageList(ctx context.Context, in *ImageListRequest, opts ...grpc.CallOption) (*ImageListResponse, error) ImageInspect(ctx context.Context, in *ImageInspectRequest, opts ...grpc.CallOption) (*ImageInspectResponse, error) ImageRemove(ctx context.Context, in *ImageRemoveRequest, opts ...grpc.CallOption) (*ImageRemoveResponse, error) + ImagePrune(ctx context.Context, in *ImagePruneRequest, opts ...grpc.CallOption) (*ImagePruneResponse, error) } type imageServiceClient struct { @@ -58,6 +59,15 @@ func (c *imageServiceClient) ImageRemove(ctx context.Context, in *ImageRemoveReq return out, nil } +func (c *imageServiceClient) ImagePrune(ctx context.Context, in *ImagePruneRequest, opts ...grpc.CallOption) (*ImagePruneResponse, error) { + out := new(ImagePruneResponse) + err := c.cc.Invoke(ctx, "/pb.ImageService/ImagePrune", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ImageServiceServer is the server API for ImageService service. // All implementations must embed UnimplementedImageServiceServer // for forward compatibility @@ -65,6 +75,7 @@ type ImageServiceServer interface { ImageList(context.Context, *ImageListRequest) (*ImageListResponse, error) ImageInspect(context.Context, *ImageInspectRequest) (*ImageInspectResponse, error) ImageRemove(context.Context, *ImageRemoveRequest) (*ImageRemoveResponse, error) + ImagePrune(context.Context, *ImagePruneRequest) (*ImagePruneResponse, error) mustEmbedUnimplementedImageServiceServer() } @@ -81,6 +92,9 @@ func (UnimplementedImageServiceServer) ImageInspect(context.Context, *ImageInspe func (UnimplementedImageServiceServer) ImageRemove(context.Context, *ImageRemoveRequest) (*ImageRemoveResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ImageRemove not implemented") } +func (UnimplementedImageServiceServer) ImagePrune(context.Context, *ImagePruneRequest) (*ImagePruneResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImagePrune not implemented") +} func (UnimplementedImageServiceServer) mustEmbedUnimplementedImageServiceServer() {} // UnsafeImageServiceServer may be embedded to opt out of forward compatibility for this service. @@ -148,6 +162,24 @@ func _ImageService_ImageRemove_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _ImageService_ImagePrune_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImagePruneRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ImageServiceServer).ImagePrune(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/pb.ImageService/ImagePrune", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ImageServiceServer).ImagePrune(ctx, req.(*ImagePruneRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ImageService_ServiceDesc is the grpc.ServiceDesc for ImageService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -167,6 +199,10 @@ var ImageService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ImageRemove", Handler: _ImageService_ImageRemove_Handler, }, + { + MethodName: "ImagePrune", + Handler: _ImageService_ImagePrune_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "image.proto", diff --git a/test/dockerfile1/mount/Dockerfile1 b/test/dockerfile1/mount/Dockerfile1 index 6101ba6a..617d53ee 100644 --- a/test/dockerfile1/mount/Dockerfile1 +++ b/test/dockerfile1/mount/Dockerfile1 @@ -38,7 +38,7 @@ LABEL maintainer="CrazyMax" RUN apk --update --no-cache add \ ca-certificates \ libressl \ - && rm -rf /tmp/* /var/cache/apk/* + && rm -rf /tmp/* COPY --from=build /usr/local/bin/diun /usr/local/bin/diun RUN diun --version