func containerLXDLoad(d *Daemon, name string) (container, error) { shared.Log.Debug("Container load", log.Ctx{"container": name}) args, err := dbContainerGet(d.db, name) if err != nil { return nil, err } baseConfig := map[string]string{} if err := shared.DeepCopy(&args.Config, &baseConfig); err != nil { return nil, err } baseDevices := shared.Devices{} if err := shared.DeepCopy(&args.Devices, &baseDevices); err != nil { return nil, err } c := &containerLXD{ daemon: d, id: args.ID, name: name, ephemeral: args.Ephemeral, architecture: args.Architecture, config: args.Config, profiles: args.Profiles, devices: args.Devices, cType: args.Ctype, baseConfig: baseConfig, baseDevices: baseDevices} s, err := storageForFilename(d, c.PathGet("")) if err != nil { shared.Log.Warn("Couldn't detect storage.", log.Ctx{"container": c.NameGet()}) c.Storage = d.Storage } else { c.Storage = s } if err := c.init(); err != nil { return nil, err } return c, nil }
func MakeRaw(fd int) (*State, error) { var err error var oldState, newState *State oldState, err = GetState(fd) if err != nil { return nil, err } err = shared.DeepCopy(&oldState, &newState) if err != nil { return nil, err } C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState.Termios))) err = Restore(fd, newState) if err != nil { return nil, err } return oldState, nil }
func containerLXDCreateInternal( d *Daemon, name string, args containerLXDArgs) (*containerLXD, error) { shared.Log.Info( "Container create", log.Ctx{ "container": name, "isSnapshot": args.Ctype == cTypeSnapshot}) if args.Ctype != cTypeSnapshot { if err := validContainerName(name); err != nil { return nil, err } } path := containerPathGet(name, args.Ctype == cTypeSnapshot) if shared.PathExists(path) { shared.Log.Error( "The container already exists on disk", log.Ctx{ "container": name, "path": path}) return nil, fmt.Errorf( "The container already exists on disk, container: '%s', path: '%s'", name, path) } if args.Profiles == nil { args.Profiles = []string{"default"} } if args.Config == nil { args.Config = map[string]string{} } if args.BaseImage != "" { args.Config["volatile.base_image"] = args.BaseImage } if args.Devices == nil { args.Devices = shared.Devices{} } profiles, err := dbProfilesGet(d.db) if err != nil { return nil, err } for _, profile := range args.Profiles { if !shared.StringInSlice(profile, profiles) { return nil, fmt.Errorf("Requested profile '%s' doesn't exist", profile) } } id, err := dbContainerCreate(d.db, name, args) if err != nil { return nil, err } shared.Log.Debug( "Container created in the DB", log.Ctx{"container": name, "id": id}) baseConfig := map[string]string{} if err := shared.DeepCopy(&args.Config, &baseConfig); err != nil { return nil, err } baseDevices := shared.Devices{} if err := shared.DeepCopy(&args.Devices, &baseDevices); err != nil { return nil, err } c := &containerLXD{ daemon: d, id: id, name: name, ephemeral: args.Ephemeral, architecture: args.Architecture, config: args.Config, profiles: args.Profiles, devices: args.Devices, cType: args.Ctype, baseConfig: baseConfig, baseDevices: baseDevices} // No need to detect storage here, its a new container. c.Storage = d.Storage if err := c.init(); err != nil { c.Delete() // Delete the container from the DB. return nil, err } return c, nil }
func (n *network) Update(newNetwork shared.NetworkConfig) error { err := networkFillAuto(newNetwork.Config) if err != nil { return err } newConfig := newNetwork.Config // Backup the current state oldConfig := map[string]string{} err = shared.DeepCopy(&n.config, &oldConfig) if err != nil { return err } // Define a function which reverts everything. Defer this function // so that it doesn't need to be explicitly called in every failing // return path. Track whether or not we want to undo the changes // using a closure. undoChanges := true defer func() { if undoChanges { n.config = oldConfig } }() // Diff the configurations changedConfig := []string{} userOnly := true for key, _ := range oldConfig { if oldConfig[key] != newConfig[key] { if !strings.HasPrefix(key, "user.") { userOnly = false } if !shared.StringInSlice(key, changedConfig) { changedConfig = append(changedConfig, key) } } } for key, _ := range newConfig { if oldConfig[key] != newConfig[key] { if !strings.HasPrefix(key, "user.") { userOnly = false } if !shared.StringInSlice(key, changedConfig) { changedConfig = append(changedConfig, key) } } } // Skip on no change if len(changedConfig) == 0 { return nil } // Update the network if !userOnly { if shared.StringInSlice("bridge.driver", changedConfig) && n.IsRunning() { err = n.Stop() if err != nil { return err } } if shared.StringInSlice("bridge.external_interfaces", changedConfig) && n.IsRunning() { devices := []string{} for _, dev := range strings.Split(newConfig["bridge.external_interfaces"], ",") { dev = strings.TrimSpace(dev) devices = append(devices, dev) } for _, dev := range strings.Split(oldConfig["bridge.external_interfaces"], ",") { dev = strings.TrimSpace(dev) if dev == "" { continue } if !shared.StringInSlice(dev, devices) && shared.PathExists(fmt.Sprintf("/sys/class/net/%s", dev)) { err = networkDetachInterface(n.name, dev) if err != nil { return err } } } } } // Apply the new configuration n.config = newConfig // Update the database err = dbNetworkUpdate(n.daemon.db, n.name, n.config) if err != nil { return err } // Restart the network if !userOnly { err = n.Start() if err != nil { return err } } // Success, update the closure to mark that the changes should be kept. undoChanges = false return nil }
func containerLXDCreateInternal( d *Daemon, name string, args containerLXDArgs) (*containerLXD, error) { shared.Log.Info( "Container create", log.Ctx{ "container": name, "isSnapshot": args.Ctype == cTypeSnapshot}) if args.Ctype != cTypeSnapshot && strings.Contains(name, shared.SnapshotDelimiter) { return nil, fmt.Errorf( "The character '%s' is reserved for snapshots.", shared.SnapshotDelimiter) } path := containerPathGet(name, args.Ctype == cTypeSnapshot) if shared.PathExists(path) { shared.Log.Error( "The container already exists on disk", log.Ctx{ "container": name, "path": path}) return nil, fmt.Errorf( "The container already exists on disk, container: '%s', path: '%s'", name, path) } if args.Profiles == nil { args.Profiles = []string{"default"} } if args.Config == nil { args.Config = map[string]string{} } if args.BaseImage != "" { args.Config["volatile.base_image"] = args.BaseImage } if args.Devices == nil { args.Devices = shared.Devices{} } id, err := dbContainerCreate(d.db, name, args) if err != nil { return nil, err } shared.Log.Debug( "Container created in the DB", log.Ctx{"container": name, "id": id}) myConfig := map[string]string{} if err := shared.DeepCopy(&args.Config, &myConfig); err != nil { return nil, err } myDevices := shared.Devices{} if err := shared.DeepCopy(&args.Devices, &myDevices); err != nil { return nil, err } c := &containerLXD{ daemon: d, id: id, name: name, ephemeral: args.Ephemeral, architecture: args.Architecture, config: args.Config, profiles: args.Profiles, devices: args.Devices, cType: args.Ctype, myConfig: myConfig, myDevices: myDevices} // No need to detect storage here, its a new container. c.Storage = d.Storage if err := c.init(); err != nil { c.Delete() // Delete the container from the DB. return nil, err } return c, nil }