github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/linklayerdevices_refs.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/mgo.v2" 9 "gopkg.in/mgo.v2/bson" 10 "gopkg.in/mgo.v2/txn" 11 ) 12 13 // linkLayerDevicesRefsDoc associates each known link-layer network device on a 14 // machine with the number of its "children" devices (if any) on the same 15 // machine. 16 type linkLayerDevicesRefsDoc struct { 17 // DocID is the (parent) device DocID (global key prefixed by ModelUUID). 18 DocID string `bson:"_id"` 19 20 // ModelUUID is the UUID of the model the device belongs to. 21 ModelUUID string `bson:"model-uuid"` 22 23 // NumChildren is number of devices which refer to this device as their 24 // parent. 25 NumChildren int `bson:"num-children"` 26 } 27 28 // insertLinkLayerDevicesRefsOp returns an operation to insert a new 29 // linkLayerDevicesRefsDoc for the given modelUUID and linkLayerDeviceDocID, 30 // with NumChildren=0. 31 func insertLinkLayerDevicesRefsOp(modelUUID, linkLayerDeviceDocID string) txn.Op { 32 refsDoc := &linkLayerDevicesRefsDoc{ 33 DocID: linkLayerDeviceDocID, 34 ModelUUID: modelUUID, 35 NumChildren: 0, 36 } 37 return txn.Op{ 38 C: linkLayerDevicesRefsC, 39 Id: linkLayerDeviceDocID, 40 Assert: txn.DocMissing, 41 Insert: refsDoc, 42 } 43 } 44 45 // removeLinkLayerDevicesRefsOp returns an operation to remove the 46 // linkLayerDevicesRefsDoc for the given linkLayerDeviceDocID, asserting the 47 // document has NumChildren == 0. 48 func removeLinkLayerDevicesRefsOp(linkLayerDeviceDocID string) txn.Op { 49 hasNoChildren := bson.D{{"num-children", 0}} 50 return txn.Op{ 51 C: linkLayerDevicesRefsC, 52 Id: linkLayerDeviceDocID, 53 Assert: hasNoChildren, 54 Remove: true, 55 } 56 } 57 58 // getParentDeviceNumChildrenRefs returns the NumChildren value for the given 59 // linkLayerDeviceDocID. If the linkLayerDevicesRefsDoc is missing, no error and 60 // -1 children are returned. 61 func getParentDeviceNumChildrenRefs(st *State, linkLayerDeviceDocID string) (int, error) { 62 devicesRefs, closer := st.getCollection(linkLayerDevicesRefsC) 63 defer closer() 64 65 var doc linkLayerDevicesRefsDoc 66 err := devicesRefs.FindId(linkLayerDeviceDocID).One(&doc) 67 if err == mgo.ErrNotFound { 68 return -1, nil 69 } else if err != nil { 70 return 0, errors.Trace(err) 71 } 72 return doc.NumChildren, nil 73 } 74 75 // incrementDeviceNumChildrenOp returns an operation that increments the 76 // NumChildren value of the linkLayerDevicesRefsDoc matching the given 77 // linkLayerDeviceDocID, and asserting the document has NumChildren >= 0. 78 func incrementDeviceNumChildrenOp(linkLayerDeviceDocID string) txn.Op { 79 hasZeroOrMoreChildren := bson.D{{"num-children", bson.D{{"$gte", 0}}}} 80 return txn.Op{ 81 C: linkLayerDevicesRefsC, 82 Id: linkLayerDeviceDocID, 83 Assert: hasZeroOrMoreChildren, 84 Update: bson.D{{"$inc", bson.D{{"num-children", 1}}}}, 85 } 86 } 87 88 // decrementDeviceNumChildrenOp returns an operation that decrements the 89 // NumChildren value of the linkLayerDevicesRefsDoc matching the given 90 // linkLayerDeviceDocID, and asserting the document has NumChildren >= 1. 91 func decrementDeviceNumChildrenOp(linkLayerDeviceDocID string) txn.Op { 92 hasAtLeastOneMoreChild := bson.D{{"num-children", bson.D{{"$gte", 1}}}} 93 return txn.Op{ 94 C: linkLayerDevicesRefsC, 95 Id: linkLayerDeviceDocID, 96 Assert: hasAtLeastOneMoreChild, 97 Update: bson.D{{"$inc", bson.D{{"num-children", -1}}}}, 98 } 99 }