github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/namespace.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "os" 22 "sort" 23 "strings" 24 "text/tabwriter" 25 26 "github.com/containerd/containerd/namespaces" 27 "github.com/containerd/log" 28 "github.com/containerd/nerdctl/pkg/clientutil" 29 "github.com/containerd/nerdctl/pkg/mountutil/volumestore" 30 "github.com/spf13/cobra" 31 ) 32 33 func newNamespaceCommand() *cobra.Command { 34 namespaceCommand := &cobra.Command{ 35 Annotations: map[string]string{Category: Management}, 36 Use: "namespace", 37 Aliases: []string{"ns"}, 38 Short: "Manage containerd namespaces", 39 Long: "Unrelated to Linux namespaces and Kubernetes namespaces", 40 RunE: unknownSubcommandAction, 41 SilenceUsage: true, 42 SilenceErrors: true, 43 } 44 namespaceCommand.AddCommand(newNamespaceLsCommand()) 45 namespaceCommand.AddCommand(newNamespaceRmCommand()) 46 namespaceCommand.AddCommand(newNamespaceCreateCommand()) 47 namespaceCommand.AddCommand(newNamespacelabelUpdateCommand()) 48 namespaceCommand.AddCommand(newNamespaceInspectCommand()) 49 return namespaceCommand 50 } 51 52 func newNamespaceLsCommand() *cobra.Command { 53 namespaceLsCommand := &cobra.Command{ 54 Use: "ls", 55 Aliases: []string{"list"}, 56 Short: "List containerd namespaces", 57 RunE: namespaceLsAction, 58 SilenceUsage: true, 59 SilenceErrors: true, 60 } 61 namespaceLsCommand.Flags().BoolP("quiet", "q", false, "Only display names") 62 return namespaceLsCommand 63 } 64 65 func namespaceLsAction(cmd *cobra.Command, args []string) error { 66 globalOptions, err := processRootCmdFlags(cmd) 67 if err != nil { 68 return err 69 } 70 client, ctx, cancel, err := clientutil.NewClient(cmd.Context(), globalOptions.Namespace, globalOptions.Address) 71 if err != nil { 72 return err 73 } 74 defer cancel() 75 76 nsService := client.NamespaceService() 77 nsList, err := nsService.List(ctx) 78 if err != nil { 79 return err 80 } 81 quiet, err := cmd.Flags().GetBool("quiet") 82 if err != nil { 83 return err 84 } 85 if quiet { 86 for _, ns := range nsList { 87 fmt.Fprintln(cmd.OutOrStdout(), ns) 88 } 89 return nil 90 } 91 dataStore, err := clientutil.DataStore(globalOptions.DataRoot, globalOptions.Address) 92 if err != nil { 93 return err 94 } 95 96 w := tabwriter.NewWriter(cmd.OutOrStdout(), 4, 8, 4, ' ', 0) 97 // no "NETWORKS", because networks are global objects 98 fmt.Fprintln(w, "NAME\tCONTAINERS\tIMAGES\tVOLUMES\tLABELS") 99 for _, ns := range nsList { 100 ctx = namespaces.WithNamespace(ctx, ns) 101 var numContainers, numImages, numVolumes int 102 var labelStrings []string 103 104 containers, err := client.Containers(ctx) 105 if err != nil { 106 log.L.Warn(err) 107 } 108 numContainers = len(containers) 109 110 images, err := client.ImageService().List(ctx) 111 if err != nil { 112 log.L.Warn(err) 113 } 114 numImages = len(images) 115 116 volStore, err := volumestore.Path(dataStore, ns) 117 if err != nil { 118 log.L.Warn(err) 119 } else { 120 volEnts, err := os.ReadDir(volStore) 121 if err != nil { 122 if !os.IsNotExist(err) { 123 log.L.Warn(err) 124 } 125 } 126 numVolumes = len(volEnts) 127 } 128 129 labels, err := client.NamespaceService().Labels(ctx, ns) 130 if err != nil { 131 return err 132 } 133 for k, v := range labels { 134 labelStrings = append(labelStrings, strings.Join([]string{k, v}, "=")) 135 } 136 sort.Strings(labelStrings) 137 fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%v\t\n", ns, numContainers, numImages, numVolumes, strings.Join(labelStrings, ",")) 138 } 139 return w.Flush() 140 }