func createFromMigration(d *Daemon, req *containerPostReq) Response { if req.Source.Mode != "pull" { return NotImplemented } createArgs := DbCreateContainerArgs{ d: d, name: req.Name, ctype: cTypeRegular, config: req.Config, profiles: req.Profiles, ephem: req.Ephemeral, baseImage: req.Source.BaseImage, } _, err := dbCreateContainer(createArgs) if err != nil { return SmartError(err) } c, err := newLxdContainer(req.Name, d) if err != nil { removeContainer(d, req.Name) return SmartError(err) } // rsync complaisn if the parent directory for the rootfs sync doesn't // exist dpath := shared.VarPath("lxc", req.Name) if err := os.MkdirAll(dpath, 0700); err != nil { removeContainer(d, req.Name) return InternalError(err) } if err := extractShiftIfExists(d, c, req.Source.BaseImage, req.Name); err != nil { removeContainer(d, req.Name) return InternalError(err) } config, err := shared.GetTLSConfig(d.certf, d.keyf) if err != nil { removeContainer(d, req.Name) return InternalError(err) } args := migration.MigrationSinkArgs{ Url: req.Source.Operation, Dialer: websocket.Dialer{ TLSClientConfig: config, NetDial: shared.RFC3493Dialer}, Container: c.c, Secrets: req.Source.Websockets, IdMapSet: c.idmapset, } sink, err := migration.NewMigrationSink(&args) if err != nil { removeContainer(d, req.Name) return BadRequest(err) } run := func() shared.OperationResult { err := sink() if err != nil { removeContainer(d, req.Name) return shared.OperationError(err) } c, err := newLxdContainer(req.Name, d) if err != nil { return shared.OperationError(err) } err = templateApply(c, "copy") if err != nil { return shared.OperationError(err) } return shared.OperationError(nil) } resources := make(map[string][]string) resources["containers"] = []string{req.Name} return &asyncResponse{run: run, resources: resources} }
func createFromMigration(d *Daemon, req *containerPostReq) Response { if req.Source.Mode != "pull" { return NotImplemented } run := func() shared.OperationResult { createArgs := containerLXDArgs{ Ctype: cTypeRegular, Config: req.Config, Profiles: req.Profiles, Ephemeral: req.Ephemeral, BaseImage: req.Source.BaseImage, } var c container if _, err := dbImageGet(d.db, req.Source.BaseImage, false, true); err == nil { c, err = containerLXDCreateFromImage( d, req.Name, createArgs, req.Source.BaseImage) if err != nil { return shared.OperationError(err) } } else { c, err = containerLXDCreateAsEmpty(d, req.Name, createArgs) if err != nil { return shared.OperationError(err) } } config, err := shared.GetTLSConfig(d.certf, d.keyf) if err != nil { c.Delete() return shared.OperationError(err) } lxContainer, err := c.LXContainerGet() if err != nil { c.Delete() return shared.OperationError(err) } idmapset, err := c.IdmapSetGet() if err != nil { c.Delete() return shared.OperationError(err) } args := migration.MigrationSinkArgs{ Url: req.Source.Operation, Dialer: websocket.Dialer{ TLSClientConfig: config, NetDial: shared.RFC3493Dialer}, Container: lxContainer, Secrets: req.Source.Websockets, IdMapSet: idmapset, } sink, err := migration.NewMigrationSink(&args) if err != nil { c.Delete() return shared.OperationError(err) } // Start the storage for this container (LVM mount/umount) c.StorageStart() defer c.StorageStop() // And finaly run the migration. err = sink() if err != nil { c.Delete() return shared.OperationError(err) } err = c.TemplateApply("copy") if err != nil { return shared.OperationError(err) } return shared.OperationError(nil) } resources := make(map[string][]string) resources["containers"] = []string{req.Name} return &asyncResponse{run: run, resources: resources} }