package cni import ( "errors" "github.com/Microsoft/go-winio/pkg/guid" "github.com/Microsoft/hcsshim/internal/regstate" ) const ( cniRoot = "cni" cniKey = "cfg" ) // PersistedNamespaceConfig is the registry version of the `NamespaceID` to UVM // map. type PersistedNamespaceConfig struct { namespaceID string stored bool ContainerID string HostUniqueID guid.GUID } // NewPersistedNamespaceConfig creates an in-memory namespace config that can be // persisted to the registry. func NewPersistedNamespaceConfig(namespaceID, containerID string, containerHostUniqueID guid.GUID) *PersistedNamespaceConfig { return &PersistedNamespaceConfig{ namespaceID: namespaceID, ContainerID: containerID, HostUniqueID: containerHostUniqueID, } } // LoadPersistedNamespaceConfig loads a persisted config from the registry that matches // `namespaceID`. If not found returns `regstate.NotFoundError` func LoadPersistedNamespaceConfig(namespaceID string) (*PersistedNamespaceConfig, error) { sk, err := regstate.Open(cniRoot, false) if err != nil { return nil, err } defer sk.Close() pnc := PersistedNamespaceConfig{ namespaceID: namespaceID, stored: true, } if err := sk.Get(namespaceID, cniKey, &pnc); err != nil { return nil, err } return &pnc, nil } // Store stores or updates the in-memory config to its registry state. If the // store failes returns the store error. func (pnc *PersistedNamespaceConfig) Store() error { if pnc.namespaceID == "" { return errors.New("invalid namespaceID ''") } if pnc.ContainerID == "" { return errors.New("invalid containerID ''") } empty := guid.GUID{} if pnc.HostUniqueID == empty { return errors.New("invalid containerHostUniqueID 'empy'") } sk, err := regstate.Open(cniRoot, false) if err != nil { return err } defer sk.Close() if pnc.stored { if err := sk.Set(pnc.namespaceID, cniKey, pnc); err != nil { return err } } else { if err := sk.Create(pnc.namespaceID, cniKey, pnc); err != nil { return err } } pnc.stored = true return nil } // Remove removes any persisted state associated with this config. If the config // is not found in the registery `Remove` returns no error. func (pnc *PersistedNamespaceConfig) Remove() error { if pnc.stored { sk, err := regstate.Open(cniRoot, false) if err != nil { if regstate.IsNotFoundError(err) { pnc.stored = false return nil } return err } defer sk.Close() if err := sk.Remove(pnc.namespaceID); err != nil { if regstate.IsNotFoundError(err) { pnc.stored = false return nil } return err } } pnc.stored = false return nil }