github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/container.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "strings" 8 9 "gopkg.in/mgo.v2/bson" 10 "gopkg.in/mgo.v2/txn" 11 12 "github.com/juju/juju/instance" 13 ) 14 15 // machineContainers holds the machine ids of all the containers belonging to a parent machine. 16 // All machines have an associated container ref doc, regardless of whether they host any containers. 17 type machineContainers struct { 18 DocID string `bson:"_id"` 19 Id string `bson:"machineid"` 20 ModelUUID string `bson:"model-uuid"` 21 Children []string `bson:",omitempty"` 22 } 23 24 func (st *State) addChildToContainerRefOp(parentId string, childId string) txn.Op { 25 return txn.Op{ 26 C: containerRefsC, 27 Id: st.docID(parentId), 28 Assert: txn.DocExists, 29 Update: bson.D{{"$addToSet", bson.D{{"children", childId}}}}, 30 } 31 } 32 33 func (st *State) insertNewContainerRefOp(machineId string, children ...string) txn.Op { 34 return txn.Op{ 35 C: containerRefsC, 36 Id: st.docID(machineId), 37 Assert: txn.DocMissing, 38 Insert: &machineContainers{ 39 Id: machineId, 40 Children: children, 41 }, 42 } 43 } 44 45 // removeContainerRefOps returns the txn.Op's necessary to remove a machine container record. 46 // These include removing the record itself and updating the host machine's children property. 47 func removeContainerRefOps(st *State, machineId string) []txn.Op { 48 removeRefOp := txn.Op{ 49 C: containerRefsC, 50 Id: st.docID(machineId), 51 Assert: txn.DocExists, 52 Remove: true, 53 } 54 // If the machine is a container, figure out its parent host. 55 parentId := ParentId(machineId) 56 if parentId == "" { 57 return []txn.Op{removeRefOp} 58 } 59 removeParentRefOp := txn.Op{ 60 C: containerRefsC, 61 Id: st.docID(parentId), 62 Assert: txn.DocExists, 63 Update: bson.D{{"$pull", bson.D{{"children", machineId}}}}, 64 } 65 return []txn.Op{removeRefOp, removeParentRefOp} 66 } 67 68 // ParentId returns the id of the host machine if machineId a container id, or "" 69 // if machineId is not for a container. 70 func ParentId(machineId string) string { 71 idParts := strings.Split(machineId, "/") 72 if len(idParts) < 3 { 73 return "" 74 } 75 return strings.Join(idParts[:len(idParts)-2], "/") 76 } 77 78 // ContainerTypeFromId returns the container type if machineId is a container id, or "" 79 // if machineId is not for a container. 80 func ContainerTypeFromId(machineId string) instance.ContainerType { 81 idParts := strings.Split(machineId, "/") 82 if len(idParts) < 3 { 83 return instance.ContainerType("") 84 } 85 return instance.ContainerType(idParts[len(idParts)-2]) 86 } 87 88 // NestingLevel returns how many levels of nesting exist for a machine id. 89 func NestingLevel(machineId string) int { 90 idParts := strings.Split(machineId, "/") 91 return (len(idParts) - 1) / 2 92 } 93 94 // TopParentId returns the id of the top level host machine for a container id. 95 func TopParentId(machineId string) string { 96 idParts := strings.Split(machineId, "/") 97 return idParts[0] 98 }