Skip to content

Commit 84d6ee8

Browse files
waynrsharmita3andrewsomething
authored
registry: implement garbage collection subcommands (#902)
* registry: stub out garbage collection subcommands * registry: implement garbage collection subcommands * fix TestRegistryCommand * registry: add integrations tests for garbage collection subcommands * add TestGarbageCollectionCommand and fix displayable commands * update godo mocks and vendor code * registry: add unit tests for garbage collection subcommands * registry: fix bugs in garbage collection subcommands * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> * Update commands/registry.go Co-authored-by: sharmita3 <[email protected]> Co-authored-by: sharmita3 <[email protected]> Co-authored-by: Andrew Starr-Bochicchio <[email protected]>
1 parent 5cc3aeb commit 84d6ee8

File tree

18 files changed

+6502
-41
lines changed

18 files changed

+6502
-41
lines changed

commands/displayers/registry.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,55 @@ func (r *RepositoryTag) KV() []map[string]interface{} {
147147

148148
return out
149149
}
150+
151+
type GarbageCollection struct {
152+
GarbageCollections []do.GarbageCollection
153+
}
154+
155+
var _ Displayable = &GarbageCollection{}
156+
157+
func (g *GarbageCollection) JSON(out io.Writer) error {
158+
return writeJSON(g.GarbageCollections, out)
159+
}
160+
161+
func (g *GarbageCollection) Cols() []string {
162+
return []string{
163+
"UUID",
164+
"RegistryName",
165+
"Status",
166+
"CreatedAt",
167+
"UpdatedAt",
168+
"BlobsDeleted",
169+
"FreedBytes",
170+
}
171+
}
172+
173+
func (g *GarbageCollection) ColMap() map[string]string {
174+
return map[string]string{
175+
"UUID": "UUID",
176+
"RegistryName": "Registry Name",
177+
"Status": "Status",
178+
"CreatedAt": "Created At",
179+
"UpdatedAt": "Updated At",
180+
"BlobsDeleted": "Blobs Deleted",
181+
"FreedBytes": "Bytes Freed",
182+
}
183+
}
184+
185+
func (g *GarbageCollection) KV() []map[string]interface{} {
186+
out := []map[string]interface{}{}
187+
188+
for _, gc := range g.GarbageCollections {
189+
out = append(out, map[string]interface{}{
190+
"UUID": gc.UUID,
191+
"RegistryName": gc.RegistryName,
192+
"Status": gc.Status,
193+
"CreatedAt": gc.CreatedAt,
194+
"UpdatedAt": gc.UpdatedAt,
195+
"BlobsDeleted": gc.BlobsDeleted,
196+
"FreedBytes": gc.FreedBytes,
197+
})
198+
}
199+
200+
return out
201+
}

commands/registry.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func Registry() *Command {
5151
}
5252

5353
cmd.AddCommand(Repository())
54+
cmd.AddCommand(GarbageCollection())
5455

5556
createRegDesc := "This command creates a new private container registry with the provided name."
5657
CmdBuilder(cmd, RunRegistryCreate, "create <registry-name>",
@@ -169,6 +170,77 @@ func Repository() *Command {
169170
return cmd
170171
}
171172

173+
// GarbageCollection creates the garbage-collection subcommand
174+
func GarbageCollection() *Command {
175+
cmd := &Command{
176+
Command: &cobra.Command{
177+
Use: "garbage-collection",
178+
Aliases: []string{"gc", "g"},
179+
Short: "Display commands for garbage collection for a container registry",
180+
Long: "The subcommands of `doctl registry garbage-collection` start a garbage collection, retrieve or cancel a currently-active garbage collection or list past garbage collections for a specified registry.",
181+
},
182+
}
183+
184+
runStartGarbageCollectionDesc := "This command starts a garbage collection on a container registry. There can be only one active garbage collection at a time for a given registry."
185+
CmdBuilder(
186+
cmd,
187+
RunStartGarbageCollection,
188+
"start",
189+
"Start garbage collection for a container registry",
190+
runStartGarbageCollectionDesc,
191+
Writer,
192+
aliasOpt("s"),
193+
displayerType(&displayers.GarbageCollection{}),
194+
)
195+
196+
gcInfoIncluded := `
197+
- UUID
198+
- Status
199+
- Registry Name
200+
- Created At
201+
- Updated At
202+
- Blobs Deleted
203+
- Freed Bytes
204+
`
205+
206+
runGetGarbageCollectionDesc := "This command retrieves the currently-active garbage collection for a container registry, if any active garbage collection exists. Information included about the registry includes:" + gcInfoIncluded
207+
CmdBuilder(
208+
cmd,
209+
RunGetGarbageCollection,
210+
"get-active",
211+
"Retrieve information about the currently-active garbage collection for a container registry",
212+
runGetGarbageCollectionDesc,
213+
Writer,
214+
aliasOpt("ga", "g"),
215+
displayerType(&displayers.GarbageCollection{}),
216+
)
217+
218+
runListGarbageCollectionsDesc := "This command retrieves a list of past garbage collections for a registry. Information about each garbage collection includes:" + gcInfoIncluded
219+
CmdBuilder(
220+
cmd,
221+
RunListGarbageCollections,
222+
"list",
223+
"Retrieve information about past garbage collections for a container registry",
224+
runListGarbageCollectionsDesc,
225+
Writer,
226+
aliasOpt("ls", "l"),
227+
displayerType(&displayers.GarbageCollection{}),
228+
)
229+
230+
runCancelGarbageCollectionDesc := "This command cancels the currently-active garbage collection for a container registry."
231+
CmdBuilder(
232+
cmd,
233+
RunCancelGarbageCollection,
234+
"cancel",
235+
"Cancel the currently-active garbage collection for a container registry",
236+
runCancelGarbageCollectionDesc,
237+
Writer,
238+
aliasOpt("c"),
239+
)
240+
241+
return cmd
242+
}
243+
172244
// Registry Run Commands
173245

174246
// RunRegistryCreate creates a registry
@@ -514,3 +586,134 @@ func displayRepositoryTags(c *CmdConfig, tags ...do.RepositoryTag) error {
514586
}
515587
return c.Display(item)
516588
}
589+
590+
// Garbage Collection run commands
591+
592+
// RunStartGarbageCollection starts a garbage collection for the specified
593+
// registry.
594+
func RunStartGarbageCollection(c *CmdConfig) error {
595+
var registryName string
596+
// we anticipate supporting multiple registries in the future by allowing the
597+
// user to specify a registry argument on the command line but defaulting to
598+
// the default registry returned by c.Registry().Get()
599+
if len(c.Args) == 0 {
600+
var err error
601+
registry, err := c.Registry().Get()
602+
if err != nil {
603+
return fmt.Errorf("failed to get registry: %w", err)
604+
}
605+
registryName = registry.Name
606+
} else if len(c.Args) == 1 {
607+
registryName = c.Args[0]
608+
} else {
609+
return doctl.NewTooManyArgsErr(c.NS)
610+
}
611+
612+
gc, err := c.Registry().StartGarbageCollection(registryName)
613+
if err != nil {
614+
return err
615+
}
616+
617+
return displayGarbageCollections(c, *gc)
618+
}
619+
620+
// RunGetGarbageCollection gets the specified registry's currently-active
621+
// garbage collection.
622+
func RunGetGarbageCollection(c *CmdConfig) error {
623+
var registryName string
624+
// we anticipate supporting multiple registries in the future by allowing the
625+
// user to specify a registry argument on the command line but defaulting to
626+
// the default registry returned by c.Registry().Get()
627+
if len(c.Args) == 0 {
628+
var err error
629+
registry, err := c.Registry().Get()
630+
if err != nil {
631+
return fmt.Errorf("failed to get registry: %w", err)
632+
}
633+
registryName = registry.Name
634+
} else if len(c.Args) == 1 {
635+
registryName = c.Args[0]
636+
} else {
637+
return doctl.NewTooManyArgsErr(c.NS)
638+
}
639+
640+
gc, err := c.Registry().GetGarbageCollection(registryName)
641+
if err != nil {
642+
return err
643+
}
644+
645+
return displayGarbageCollections(c, *gc)
646+
}
647+
648+
// RunListGarbageCollections gets the specified registry's currently-active
649+
// garbage collection.
650+
func RunListGarbageCollections(c *CmdConfig) error {
651+
var registryName string
652+
// we anticipate supporting multiple registries in the future by allowing the
653+
// user to specify a registry argument on the command line but defaulting to
654+
// the default registry returned by c.Registry().Get()
655+
if len(c.Args) == 0 {
656+
var err error
657+
registry, err := c.Registry().Get()
658+
if err != nil {
659+
return fmt.Errorf("failed to get registry: %w", err)
660+
}
661+
registryName = registry.Name
662+
} else if len(c.Args) == 1 {
663+
registryName = c.Args[0]
664+
} else {
665+
return doctl.NewTooManyArgsErr(c.NS)
666+
}
667+
668+
gcs, err := c.Registry().ListGarbageCollections(registryName)
669+
if err != nil {
670+
return err
671+
}
672+
673+
return displayGarbageCollections(c, gcs...)
674+
}
675+
676+
// RunCancelGarbageCollection gets the specified registry's currently-active
677+
// garbage collection.
678+
func RunCancelGarbageCollection(c *CmdConfig) error {
679+
var (
680+
registryName string
681+
gcUUID string
682+
)
683+
684+
if len(c.Args) == 0 {
685+
return doctl.NewMissingArgsErr(c.NS)
686+
} else if len(c.Args) == 1 { // <gc-uuid>
687+
gcUUID = c.Args[0]
688+
} else if len(c.Args) == 2 { // <registry-name> <gc-uuid>
689+
registryName = c.Args[0]
690+
gcUUID = c.Args[1]
691+
} else {
692+
return doctl.NewTooManyArgsErr(c.NS)
693+
}
694+
695+
// we anticipate supporting multiple registries in the future by allowing the
696+
// user to specify a registry argument on the command line but defaulting to
697+
// the default registry returned by c.Registry().Get()
698+
if registryName == "" {
699+
registry, err := c.Registry().Get()
700+
if err != nil {
701+
return fmt.Errorf("failed to get registry: %w", err)
702+
}
703+
registryName = registry.Name
704+
}
705+
706+
_, err := c.Registry().CancelGarbageCollection(registryName, gcUUID)
707+
if err != nil {
708+
return err
709+
}
710+
711+
return nil
712+
}
713+
714+
func displayGarbageCollections(c *CmdConfig, garbageCollections ...do.GarbageCollection) error {
715+
item := &displayers.GarbageCollection{
716+
GarbageCollections: garbageCollections,
717+
}
718+
return c.Display(item)
719+
}

0 commit comments

Comments
 (0)