// CreateUsing creates the container using given arguments with specified backend. func (c *Container) CreateUsing(template string, backend BackendStore, args ...string) error { // FIXME: Support bdevtype and bdev_specs // bdevtypes: // "btrfs", "zfs", "lvm", "dir" // // best tries to find the best backing store type // // bdev_specs: // zfs requires zfsroot // lvm requires lvname/vgname/thinpool as well as fstype and fssize // btrfs requires nothing // dir requires nothing if err := c.makeSure(isNotDefined); err != nil { return err } c.mu.Lock() defer c.mu.Unlock() ctemplate := C.CString(template) defer C.free(unsafe.Pointer(ctemplate)) cbackend := C.CString(backend.String()) defer C.free(unsafe.Pointer(cbackend)) ret := false if args != nil { cargs := makeNullTerminatedArgs(args) if cargs == nil { return ErrAllocationFailed } defer freeNullTerminatedArgs(cargs, len(args)) ret = bool(C.go_lxc_create(c.container, ctemplate, cbackend, C.int(c.verbosity), cargs)) } else { ret = bool(C.go_lxc_create(c.container, ctemplate, cbackend, C.int(c.verbosity), nil)) } if !ret { return ErrCreateFailed } return nil }
// Create creates the container using given TemplateOptions func (c *Container) Create(options TemplateOptions) error { // FIXME: Support bdev_specs // // bdev_specs: // zfs requires zfsroot // lvm requires lvname/vgname/thinpool as well as fstype and fssize // btrfs requires nothing // dir requires nothing if err := c.makeSure(isNotDefined); err != nil { return err } c.mu.Lock() defer c.mu.Unlock() // use download template if not set if options.Template == "" { options.Template = "download" } // use Directory backend if not set if options.Backend == 0 { options.Backend = Directory } // unprivileged users are only allowed to use "download" template if os.Geteuid() != 0 && options.Template != "download" { return ErrTemplateNotAllowed } var args []string if options.Template == "download" { // required parameters if options.Distro == "" || options.Release == "" || options.Arch == "" { return ErrInsufficientNumberOfArguments } args = append(args, "--dist", options.Distro, "--release", options.Release, "--arch", options.Arch) // optional arguments if options.Variant != "" { args = append(args, "--variant", options.Variant) } if options.Server != "" { args = append(args, "--server", options.Server) } if options.KeyID != "" { args = append(args, "--keyid", options.KeyID) } if options.KeyServer != "" { args = append(args, "--keyserver", options.KeyServer) } if options.DisableGPGValidation { args = append(args, "--no-validate") } if options.FlushCache { args = append(args, "--flush-cache") } if options.ForceCache { args = append(args, "--force-cache") } } else { // optional arguments if options.Release != "" { args = append(args, "--release", options.Release) } if options.Arch != "" { args = append(args, "--arch", options.Arch) } if options.FlushCache { args = append(args, "--flush-cache") } } if options.ExtraArgs != nil { args = append(args, options.ExtraArgs...) } ctemplate := C.CString(options.Template) defer C.free(unsafe.Pointer(ctemplate)) cbackend := C.CString(options.Backend.String()) defer C.free(unsafe.Pointer(cbackend)) ret := false if args != nil { cargs := makeNullTerminatedArgs(args) if cargs == nil { return ErrAllocationFailed } defer freeNullTerminatedArgs(cargs, len(args)) ret = bool(C.go_lxc_create(c.container, ctemplate, cbackend, C.int(c.verbosity), cargs)) } else { ret = bool(C.go_lxc_create(c.container, ctemplate, cbackend, C.int(c.verbosity), nil)) } if !ret { return ErrCreateFailed } return nil }