github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/rkt/rm.go (about)

     1  // Copyright 2015 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //+build linux
    16  
    17  package main
    18  
    19  import (
    20  	"os"
    21  
    22  	pkgPod "github.com/rkt/rkt/pkg/pod"
    23  	"github.com/spf13/cobra"
    24  )
    25  
    26  var (
    27  	cmdRm = &cobra.Command{
    28  		Use:   "rm --uuid-file=FILE | UUID ...",
    29  		Short: "Remove all files and resources associated with an exited pod",
    30  		Long:  `Unlike gc, rm allows users to remove specific pods.`,
    31  		Run:   ensureSuperuser(runWrapper(runRm)),
    32  	}
    33  	flagUUIDFile string
    34  )
    35  
    36  func init() {
    37  	cmdRkt.AddCommand(cmdRm)
    38  	cmdRm.Flags().StringVar(&flagUUIDFile, "uuid-file", "", "read pod UUID from file instead of argument")
    39  }
    40  
    41  func runRm(cmd *cobra.Command, args []string) (exit int) {
    42  	var podUUIDs []string
    43  	var ret int
    44  
    45  	switch {
    46  	case len(args) == 0 && flagUUIDFile != "":
    47  		podUUID, err := pkgPod.ReadUUIDFromFile(flagUUIDFile)
    48  		if err != nil {
    49  			stderr.PrintE("unable to resolve UUID from file", err)
    50  			ret = 254
    51  		} else {
    52  			podUUIDs = append(podUUIDs, podUUID)
    53  		}
    54  
    55  	case len(args) > 0 && flagUUIDFile == "":
    56  		podUUIDs = args
    57  
    58  	default:
    59  		cmd.Usage()
    60  		return 254
    61  	}
    62  
    63  	for _, podUUID := range podUUIDs {
    64  		p, err := pkgPod.PodFromUUIDString(getDataDir(), podUUID)
    65  		if err != nil {
    66  			ret = 254
    67  			stderr.PrintE("cannot get pod", err)
    68  			continue
    69  		}
    70  		defer p.Close()
    71  
    72  		if removePod(p) {
    73  			stdout.Printf("%q", p.UUID)
    74  		} else {
    75  			ret = 254
    76  		}
    77  	}
    78  
    79  	if ret == 254 {
    80  		stderr.Print("failed to remove one or more pods")
    81  	}
    82  
    83  	return ret
    84  }
    85  
    86  func removePod(p *pkgPod.Pod) bool {
    87  	switch p.State() {
    88  	case pkgPod.Running:
    89  		stderr.Printf("pod %q is currently running", p.UUID)
    90  		return false
    91  
    92  	case pkgPod.Embryo, pkgPod.Preparing:
    93  		stderr.Printf("pod %q is currently being prepared", p.UUID)
    94  		return false
    95  
    96  	case pkgPod.Deleting:
    97  		stderr.Printf("pod %q is currently being deleted", p.UUID)
    98  		return false
    99  
   100  	case pkgPod.AbortedPrepare:
   101  		stderr.Printf("moving failed prepare %q to garbage", p.UUID)
   102  		if err := p.ToGarbage(); err != nil && err != os.ErrNotExist {
   103  			stderr.PrintE("rename error", err)
   104  			return false
   105  		}
   106  
   107  	case pkgPod.Prepared:
   108  		stderr.Printf("moving expired prepared pod %q to garbage", p.UUID)
   109  		if err := p.ToGarbage(); err != nil && err != os.ErrNotExist {
   110  			stderr.PrintE("rename error", err)
   111  			return false
   112  		}
   113  
   114  	// p.isExitedGarbage and p.isExited can be true at the same time. Test
   115  	// the most specific case first.
   116  	case pkgPod.ExitedGarbage, pkgPod.Garbage:
   117  
   118  	case pkgPod.Exited:
   119  		if err := p.ToExitedGarbage(); err != nil && err != os.ErrNotExist {
   120  			stderr.PrintE("rename error", err)
   121  			return false
   122  		}
   123  	}
   124  
   125  	if err := p.ExclusiveLock(); err != nil {
   126  		stderr.PrintE("unable to acquire exclusive lock", err)
   127  		return false
   128  	}
   129  
   130  	return deletePod(p)
   131  }