github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/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 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types" 23 "github.com/coreos/rkt/Godeps/_workspace/src/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 Run: runWrapper(runRm), 31 } 32 flagUUIDFile string 33 ) 34 35 func init() { 36 cmdRkt.AddCommand(cmdRm) 37 cmdRm.Flags().StringVar(&flagUUIDFile, "uuid-file", "", "read pod UUID from file instead of argument") 38 } 39 40 func runRm(cmd *cobra.Command, args []string) (exit int) { 41 var podUUID *types.UUID 42 var podUUIDs []*types.UUID 43 var err error 44 45 switch { 46 case len(args) == 0 && flagUUIDFile != "": 47 podUUID, err = readUUIDFromFile(flagUUIDFile) 48 if err != nil { 49 stderr("Unable to read UUID from file: %v", err) 50 return 1 51 } 52 podUUIDs = append(podUUIDs, podUUID) 53 54 case len(args) > 0 && flagUUIDFile == "": 55 for _, uuid := range args { 56 podUUID, err := resolveUUID(uuid) 57 if err != nil { 58 stderr("Unable to resolve UUID: %v", err) 59 } else { 60 podUUIDs = append(podUUIDs, podUUID) 61 } 62 } 63 64 default: 65 cmd.Usage() 66 return 1 67 } 68 69 ret := 0 70 for _, podUUID = range podUUIDs { 71 p, err := getPod(podUUID) 72 if err != nil { 73 ret = 1 74 stderr("Cannot get pod: %v", err) 75 } 76 77 if removePod(p) { 78 stdout("%q", p.uuid) 79 } else { 80 ret = 1 81 } 82 } 83 84 if ret == 1 { 85 stderr("Failed to remove one or more pods") 86 } 87 88 return ret 89 } 90 91 func removePod(p *pod) bool { 92 switch { 93 case p.isRunning(): 94 stderr("Pod %q is currently running", p.uuid) 95 return false 96 97 case p.isEmbryo, p.isPreparing: 98 stderr("Pod %q is currently being prepared", p.uuid) 99 return false 100 101 case p.isExitedDeleting, p.isDeleting: 102 stderr("Pod %q is currently being deleted", p.uuid) 103 return false 104 105 case p.isAbortedPrepare: 106 stderr("Moving failed prepare %q to garbage", p.uuid) 107 if err := p.xToGarbage(); err != nil && err != os.ErrNotExist { 108 stderr("Rename error: %v", err) 109 return false 110 } 111 112 case p.isPrepared: 113 stderr("Moving expired prepared pod %q to garbage", p.uuid) 114 if err := p.xToGarbage(); err != nil && err != os.ErrNotExist { 115 stderr("Rename error: %v", err) 116 return false 117 } 118 119 // p.isExitedGarbage and p.isExited can be true at the same time. Test 120 // the most specific case first. 121 case p.isExitedGarbage, p.isGarbage: 122 123 case p.isExited: 124 if err := p.xToExitedGarbage(); err != nil && err != os.ErrNotExist { 125 stderr("Rename error: %v", err) 126 return false 127 } 128 } 129 130 if err := p.ExclusiveLock(); err != nil { 131 stderr("Unable to acquire exclusive lock: %v", err) 132 return false 133 } 134 135 deletePod(p) 136 137 return true 138 }