1package cni 2 3import ( 4 "errors" 5 6 "github.com/Microsoft/go-winio/pkg/guid" 7 "github.com/Microsoft/hcsshim/internal/regstate" 8) 9 10const ( 11 cniRoot = "cni" 12 cniKey = "cfg" 13) 14 15// PersistedNamespaceConfig is the registry version of the `NamespaceID` to UVM 16// map. 17type PersistedNamespaceConfig struct { 18 namespaceID string 19 stored bool 20 21 ContainerID string 22 HostUniqueID guid.GUID 23} 24 25// NewPersistedNamespaceConfig creates an in-memory namespace config that can be 26// persisted to the registry. 27func NewPersistedNamespaceConfig(namespaceID, containerID string, containerHostUniqueID guid.GUID) *PersistedNamespaceConfig { 28 return &PersistedNamespaceConfig{ 29 namespaceID: namespaceID, 30 ContainerID: containerID, 31 HostUniqueID: containerHostUniqueID, 32 } 33} 34 35// LoadPersistedNamespaceConfig loads a persisted config from the registry that matches 36// `namespaceID`. If not found returns `regstate.NotFoundError` 37func LoadPersistedNamespaceConfig(namespaceID string) (*PersistedNamespaceConfig, error) { 38 sk, err := regstate.Open(cniRoot, false) 39 if err != nil { 40 return nil, err 41 } 42 defer sk.Close() 43 44 pnc := PersistedNamespaceConfig{ 45 namespaceID: namespaceID, 46 stored: true, 47 } 48 if err := sk.Get(namespaceID, cniKey, &pnc); err != nil { 49 return nil, err 50 } 51 return &pnc, nil 52} 53 54// Store stores or updates the in-memory config to its registry state. If the 55// store failes returns the store error. 56func (pnc *PersistedNamespaceConfig) Store() error { 57 if pnc.namespaceID == "" { 58 return errors.New("invalid namespaceID ''") 59 } 60 if pnc.ContainerID == "" { 61 return errors.New("invalid containerID ''") 62 } 63 empty := guid.GUID{} 64 if pnc.HostUniqueID == empty { 65 return errors.New("invalid containerHostUniqueID 'empy'") 66 } 67 sk, err := regstate.Open(cniRoot, false) 68 if err != nil { 69 return err 70 } 71 defer sk.Close() 72 73 if pnc.stored { 74 if err := sk.Set(pnc.namespaceID, cniKey, pnc); err != nil { 75 return err 76 } 77 } else { 78 if err := sk.Create(pnc.namespaceID, cniKey, pnc); err != nil { 79 return err 80 } 81 } 82 pnc.stored = true 83 return nil 84} 85 86// Remove removes any persisted state associated with this config. If the config 87// is not found in the registery `Remove` returns no error. 88func (pnc *PersistedNamespaceConfig) Remove() error { 89 if pnc.stored { 90 sk, err := regstate.Open(cniRoot, false) 91 if err != nil { 92 if regstate.IsNotFoundError(err) { 93 pnc.stored = false 94 return nil 95 } 96 return err 97 } 98 defer sk.Close() 99 100 if err := sk.Remove(pnc.namespaceID); err != nil { 101 if regstate.IsNotFoundError(err) { 102 pnc.stored = false 103 return nil 104 } 105 return err 106 } 107 } 108 pnc.stored = false 109 return nil 110} 111