github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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  }