github.com/demonoid81/containerd@v1.3.4/cmd/ctr/commands/namespaces/namespaces.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 namespaces
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"sort"
    23  	"strings"
    24  	"text/tabwriter"
    25  
    26  	"github.com/containerd/containerd/cmd/ctr/commands"
    27  	"github.com/containerd/containerd/errdefs"
    28  	"github.com/containerd/containerd/log"
    29  	"github.com/pkg/errors"
    30  	"github.com/urfave/cli"
    31  )
    32  
    33  // Command is the cli command for managing namespaces
    34  var Command = cli.Command{
    35  	Name:    "namespaces",
    36  	Aliases: []string{"namespace", "ns"},
    37  	Usage:   "manage namespaces",
    38  	Subcommands: cli.Commands{
    39  		createCommand,
    40  		listCommand,
    41  		removeCommand,
    42  		setLabelsCommand,
    43  	},
    44  }
    45  
    46  var createCommand = cli.Command{
    47  	Name:        "create",
    48  	Aliases:     []string{"c"},
    49  	Usage:       "create a new namespace",
    50  	ArgsUsage:   "<name> [<key>=<value]",
    51  	Description: "create a new namespace. it must be unique",
    52  	Action: func(context *cli.Context) error {
    53  		namespace, labels := commands.ObjectWithLabelArgs(context)
    54  		if namespace == "" {
    55  			return errors.New("please specify a namespace")
    56  		}
    57  		client, ctx, cancel, err := commands.NewClient(context)
    58  		if err != nil {
    59  			return err
    60  		}
    61  		defer cancel()
    62  		namespaces := client.NamespaceService()
    63  		return namespaces.Create(ctx, namespace, labels)
    64  	},
    65  }
    66  
    67  var setLabelsCommand = cli.Command{
    68  	Name:        "label",
    69  	Usage:       "set and clear labels for a namespace",
    70  	ArgsUsage:   "<name> [<key>=<value>, ...]",
    71  	Description: "set and clear labels for a namespace",
    72  	Action: func(context *cli.Context) error {
    73  		namespace, labels := commands.ObjectWithLabelArgs(context)
    74  		if namespace == "" {
    75  			return errors.New("please specify a namespace")
    76  		}
    77  		client, ctx, cancel, err := commands.NewClient(context)
    78  		if err != nil {
    79  			return err
    80  		}
    81  		defer cancel()
    82  		namespaces := client.NamespaceService()
    83  		for k, v := range labels {
    84  			if err := namespaces.SetLabel(ctx, namespace, k, v); err != nil {
    85  				return err
    86  			}
    87  		}
    88  		return nil
    89  	},
    90  }
    91  
    92  var listCommand = cli.Command{
    93  	Name:        "list",
    94  	Aliases:     []string{"ls"},
    95  	Usage:       "list namespaces",
    96  	ArgsUsage:   "[flags]",
    97  	Description: "list namespaces",
    98  	Flags: []cli.Flag{
    99  		cli.BoolFlag{
   100  			Name:  "quiet, q",
   101  			Usage: "print only the namespace name",
   102  		},
   103  	},
   104  	Action: func(context *cli.Context) error {
   105  		quiet := context.Bool("quiet")
   106  		client, ctx, cancel, err := commands.NewClient(context)
   107  		if err != nil {
   108  			return err
   109  		}
   110  		defer cancel()
   111  		namespaces := client.NamespaceService()
   112  		nss, err := namespaces.List(ctx)
   113  		if err != nil {
   114  			return err
   115  		}
   116  
   117  		if quiet {
   118  			for _, ns := range nss {
   119  				fmt.Println(ns)
   120  			}
   121  			return nil
   122  		}
   123  
   124  		tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
   125  		fmt.Fprintln(tw, "NAME\tLABELS\t")
   126  		for _, ns := range nss {
   127  			labels, err := namespaces.Labels(ctx, ns)
   128  			if err != nil {
   129  				return err
   130  			}
   131  
   132  			var labelStrings []string
   133  			for k, v := range labels {
   134  				labelStrings = append(labelStrings, strings.Join([]string{k, v}, "="))
   135  			}
   136  			sort.Strings(labelStrings)
   137  
   138  			fmt.Fprintf(tw, "%v\t%v\t\n", ns, strings.Join(labelStrings, ","))
   139  		}
   140  		return tw.Flush()
   141  	},
   142  }
   143  
   144  var removeCommand = cli.Command{
   145  	Name:        "remove",
   146  	Aliases:     []string{"rm"},
   147  	Usage:       "remove one or more namespaces",
   148  	ArgsUsage:   "<name> [<name>, ...]",
   149  	Description: "remove one or more namespaces. for now, the namespace must be empty",
   150  	Flags: []cli.Flag{
   151  		cli.BoolFlag{
   152  			Name:  "cgroup,c",
   153  			Usage: "delete the namespace's cgroup",
   154  		},
   155  	},
   156  	Action: func(context *cli.Context) error {
   157  		var exitErr error
   158  		client, ctx, cancel, err := commands.NewClient(context)
   159  		if err != nil {
   160  			return err
   161  		}
   162  		defer cancel()
   163  
   164  		opts := deleteOpts(context)
   165  		namespaces := client.NamespaceService()
   166  		for _, target := range context.Args() {
   167  			if err := namespaces.Delete(ctx, target, opts...); err != nil {
   168  				if !errdefs.IsNotFound(err) {
   169  					if exitErr == nil {
   170  						exitErr = errors.Wrapf(err, "unable to delete %v", target)
   171  					}
   172  					log.G(ctx).WithError(err).Errorf("unable to delete %v", target)
   173  					continue
   174  				}
   175  
   176  			}
   177  
   178  			fmt.Println(target)
   179  		}
   180  		return exitErr
   181  	},
   182  }