Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
Archivo: networks.go Proyecto: vahe/lxd
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
}
Ejemplo n.º 5
0
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
}