// ImportData does what it says. It imports from a host's Source to a Dest // in a data container. It returns an error. // // do.Name - name of the data container to use (required) // do.Operations.ContainerNumber - container number (optional) // do.Source - directory which should be imported (required) // do.Destination - directory to _unload_ the payload into (required) // func ImportData(do *definitions.Do) error { log.WithFields(log.Fields{ "from": do.Source, "to": do.Destination, }).Debug("Importing") if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber) service, exists := perform.ContainerExists(srv.Operations) if !exists { return fmt.Errorf("There is no data container for that service.") } if err := checkErisContainerRoot(do, "import"); err != nil { return err } containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber) os.Chdir(do.Source) reader, err := util.Tar(do.Source, 0) if err != nil { return err } defer reader.Close() opts := docker.UploadToContainerOptions{ InputStream: reader, Path: do.Destination, NoOverwriteDirNonDir: true, } log.WithField("=>", containerName).Info("Copying into container") log.WithField("path", do.Source).Debug() if err := util.DockerClient.UploadToContainer(service.ID, opts); err != nil { return err } doChown := definitions.NowDo() doChown.Operations.DataContainerName = containerName doChown.Operations.ContainerType = "data" doChown.Operations.ContainerNumber = do.Operations.ContainerNumber //required b/c `docker cp` (UploadToContainer) goes in as root doChown.Operations.Args = []string{"chown", "--recursive", "eris", do.Destination} _, err = perform.DockerRunData(doChown.Operations, nil) if err != nil { return fmt.Errorf("Error changing owner: %v\n", err) } } else { log.WithField("name", do.Name).Info("Data container does not exist.") ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber) if err := perform.DockerCreateData(ops); err != nil { return fmt.Errorf("Error creating data container %v.", err) } return ImportData(do) } do.Result = "success" return nil }
func ImportData(do *definitions.Do) error { if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber) service, exists := perform.ContainerExists(srv.Operations) if !exists { return fmt.Errorf("There is no data container for that service.") } containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber) logger.Debugf("Importing FROM =>\t\t%s\n", do.Source) os.Chdir(do.Source) logger.Debugf("Importing TO =>\t\t\t%s\n", do.Destination) reader, err := util.Tar(do.Source, 0) if err != nil { return err } defer reader.Close() opts := docker.UploadToContainerOptions{ InputStream: reader, Path: do.Destination, NoOverwriteDirNonDir: true, } logger.Infof("Copying into Cont. ID =>\t%s\n", service.ID) logger.Debugf("\tPath =>\t\t\t%s\n", do.Source) if err := util.DockerClient.UploadToContainer(service.ID, opts); err != nil { return err } doChown := definitions.NowDo() doChown.Operations.DataContainerName = containerName doChown.Operations.ContainerType = "data" doChown.Operations.ContainerNumber = 1 doChown.Operations.Args = []string{"chown", "--recursive", "eris", do.Destination} _, err = perform.DockerRunData(doChown.Operations, nil) if err != nil { return fmt.Errorf("Error changing owner: %v\n", err) } } else { ops := loaders.LoadDataDefinition(do.Name, do.Operations.ContainerNumber) if err := perform.DockerCreateData(ops); err != nil { return fmt.Errorf("Error creating data container %v.", err) } return ImportData(do) } do.Result = "success" return nil }
//export from: do.Source(in container), to: do.Destination(on host) func ExportData(do *definitions.Do) error { if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { log.WithField("=>", do.Name).Info("Exporting data container") // we want to export to a temp directory. exportPath, err := ioutil.TempDir(os.TempDir(), do.Name) // TODO: do.Operations.ContainerNumber ? defer os.Remove(exportPath) if err != nil { return err } containerName := util.DataContainersName(do.Name, do.Operations.ContainerNumber) srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber) service, exists := perform.ContainerExists(srv.Operations) if !exists { return fmt.Errorf("There is no data container for that service.") } reader, writer := io.Pipe() defer reader.Close() if err := checkErisContainerRoot(do, "export"); err != nil { return err } opts := docker.DownloadFromContainerOptions{ OutputStream: writer, Path: do.Source, } go func() { log.WithField("=>", containerName).Info("Copying out of container") log.WithField("path", do.Source).Debug() IfExit(util.DockerClient.DownloadFromContainer(service.ID, opts)) // TODO: be smarter about catching this error writer.Close() }() log.WithField("=>", exportPath).Debug("Untarring package from container") if err = util.Untar(reader, do.Name, exportPath); err != nil { return err } // now if docker dumps to exportPath/.eris we should remove // move everything from .eris to exportPath if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, ".eris"), exportPath); err != nil { return err } // finally remove everything in the data directory and move // the temp contents there if _, err := os.Stat(do.Destination); os.IsNotExist(err) { if e2 := os.MkdirAll(do.Destination, 0755); e2 != nil { return fmt.Errorf("Error:\tThe marmots could neither find, nor had access to make the directory: (%s)\n", do.Destination) } } if err := moveOutOfDirAndRmDir(exportPath, do.Destination); err != nil { return err } } else { return fmt.Errorf("I cannot find that data container. Please check the data container name you sent me.") } do.Result = "success" return nil }
func ExportData(do *definitions.Do) error { if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { logger.Infoln("Exporting data container", do.Name) exportPath := filepath.Join(DataContainersPath, do.Name) // TODO: do.Operations.ContainerNumber ? srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber) service, exists := perform.ContainerExists(srv.Operations) if !exists { return fmt.Errorf("There is no data container for that service.") } logger.Infoln("Service ID: " + service.ID) cont, err := util.DockerClient.InspectContainer(service.ID) if err != nil { return err } reader, writer := io.Pipe() if do.Path != "" { do.Path = do.Path } else { do.Path = "/home/eris/.eris" } opts := docker.CopyFromContainerOptions{ OutputStream: writer, Container: service.ID, Resource: do.Path, } go func() { IfExit(util.DockerClient.CopyFromContainer(opts)) writer.Close() }() err = util.Untar(reader, do.Name, exportPath) if err != nil { return err } // docker actually exports to a `_data` folder for volumes // this section of the function moves whatever docker dumps // into exportPath/_data into export. ranging through the // volumes is probably overkill as we could just assume // that it *was* `_data` but in case docker changes later // we'll just keep it for now. os.Chdir(exportPath) var unTarDestination string for k, v := range cont.Volumes { if k == "/home/eris/.eris" { unTarDestination = filepath.Base(v) } } if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, unTarDestination), exportPath); err != nil { return err } // now if docker dumps to exportPath/.eris we should remove // move everything from .eris to exportPath if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, ".eris"), exportPath); err != nil { return err } } else { return fmt.Errorf("I cannot find that data container. Please check the data container name you sent me.") } do.Result = "success" return nil }
func ExportData(do *definitions.Do) error { if util.IsDataContainer(do.Name, do.Operations.ContainerNumber) { dVer, err := util.DockerClientVersion() if err != nil { return err } logger.Infoln("Exporting data container", do.Name) // we want to export to a temp directory. exportPath, err := ioutil.TempDir(os.TempDir(), do.Name) // TODO: do.Operations.ContainerNumber ? defer os.Remove(exportPath) if err != nil { return err } srv := PretendToBeAService(do.Name, do.Operations.ContainerNumber) service, exists := perform.ContainerExists(srv.Operations) if !exists { return fmt.Errorf("There is no data container for that service.") } cont, err := util.DockerClient.InspectContainer(service.ID) if err != nil { return err } reader, writer := io.Pipe() defer reader.Close() if do.Path != "" { do.Path = do.Path } else { do.Path = "/home/eris/.eris" } opts := docker.CopyFromContainerOptions{ OutputStream: writer, Container: service.ID, Resource: do.Path, } go func() { logger.Infof("Copying out of Cont. ID =>\t%s\n", service.ID) logger.Debugf("\tPath =>\t\t\t%s\n", do.Path) IfExit(util.DockerClient.CopyFromContainer(opts)) writer.Close() }() logger.Debugf("Untarring Package from Cont =>\t%s\n", exportPath) if err = util.Untar(reader, do.Name, exportPath); err != nil { return err } // docker actually exports to a `_data` folder for volumes // this section of the function moves whatever docker dumps // into exportPath/_data into export. ranging through the // volumes is probably overkill as we could just assume // that it *was* `_data` but in case docker changes later // we'll just keep it for now. this is specific to 1.7 and // below. For 1.8 we do not need to do this. os.Chdir(exportPath) var unTarDestination string for k, v := range cont.Volumes { if k == do.Path { unTarDestination = filepath.Base(v) } } logger.Debugf("Untarring to =>\t\t\t%s:%s\n", exportPath, unTarDestination) if dVer <= 1.7 { if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, unTarDestination), exportPath); err != nil { return err } } // now if docker dumps to exportPath/.eris we should remove // move everything from .eris to exportPath if err := moveOutOfDirAndRmDir(filepath.Join(exportPath, ".eris"), exportPath); err != nil { return err } // finally remove everything in the data directory and move // the temp contents there prevDir := filepath.Join(DataContainersPath, do.Name) if _, err := os.Stat(prevDir); os.IsNotExist(err) { if e2 := os.MkdirAll(prevDir, 0666); e2 != nil { return fmt.Errorf("Error:\tThe marmots could neither find, nor had access to make the directory: (%s)\n", prevDir) } } ClearDir(prevDir) if err := moveOutOfDirAndRmDir(exportPath, prevDir); err != nil { return err } } else { return fmt.Errorf("I cannot find that data container. Please check the data container name you sent me.") } do.Result = "success" return nil }