// Clone creates a copy of the container, giving the copy the specified name. func (mock *mockContainer) Clone(name string, extraArgs []string, templateArgs []string) (golxc.Container, error) { state := mock.getState() if state == golxc.StateUnknown { return nil, fmt.Errorf("container has not been created") } else if state == golxc.StateRunning { return nil, fmt.Errorf("container is running, clone not possible") } container := &mockContainer{ factory: mock.factory, name: name, state: golxc.StateStopped, logLevel: golxc.LogWarning, } mock.factory.instances[name] = container // Create the container directory. containerDir := filepath.Join(mock.factory.containerDir, name) if err := os.MkdirAll(containerDir, 0755); err != nil { return nil, err } if err := utils.CopyFile(container.configFilename(), mock.configFilename()); err != nil { return nil, err } mock.factory.notify(eventArgs(Cloned, mock.name, extraArgs, templateArgs)) return container, nil }
// buildToolsTarball bundles a tools tarball and places it in a temp directory in // the expected tools path. func buildToolsTarball(forceVersion *version.Number) (builtTools *BuiltTools, err error) { // TODO(rog) find binaries from $PATH when not using a development // version of juju within a $GOPATH. logger.Debugf("Building tools") // We create the entire archive before asking the environment to // start uploading so that we can be sure we have archived // correctly. f, err := ioutil.TempFile("", "juju-tgz") if err != nil { return nil, err } defer f.Close() defer os.Remove(f.Name()) toolsVersion, sha256Hash, err := envtools.BundleTools(f, forceVersion) if err != nil { return nil, err } fileInfo, err := f.Stat() if err != nil { return nil, fmt.Errorf("cannot stat newly made tools archive: %v", err) } size := fileInfo.Size() logger.Infof("built tools %v (%dkB)", toolsVersion, (size+512)/1024) baseToolsDir, err := ioutil.TempDir("", "juju-tools") if err != nil { return nil, err } // If we exit with an error, clean up the built tools directory. defer func() { if err != nil { os.RemoveAll(baseToolsDir) } }() err = os.MkdirAll(filepath.Join(baseToolsDir, storage.BaseToolsPath, "releases"), 0755) if err != nil { return nil, err } storageName := envtools.StorageName(toolsVersion) err = utils.CopyFile(filepath.Join(baseToolsDir, storageName), f.Name()) if err != nil { return nil, err } return &BuiltTools{ Version: toolsVersion, Dir: baseToolsDir, StorageName: storageName, Size: size, Sha256Hash: sha256Hash, }, nil }
func (*fileSuite) TestCopyFile(c *gc.C) { dir := c.MkDir() f, err := ioutil.TempFile(dir, "source") c.Assert(err, gc.IsNil) defer f.Close() _, err = f.Write([]byte("hello world")) c.Assert(err, gc.IsNil) dest := filepath.Join(dir, "dest") err = utils.CopyFile(dest, f.Name()) c.Assert(err, gc.IsNil) data, err := ioutil.ReadFile(dest) c.Assert(err, gc.IsNil) c.Assert(string(data), gc.Equals, "hello world") }
// cloneToolsForSeries copies the built tools tarball into a tarball for the specified // series and generates corresponding metadata. func cloneToolsForSeries(toolsInfo *BuiltTools, series ...string) error { // Copy the tools to the target storage, recording a Tools struct for each one. var targetTools coretools.List targetTools = append(targetTools, &coretools.Tools{ Version: toolsInfo.Version, Size: toolsInfo.Size, SHA256: toolsInfo.Sha256Hash, }) putTools := func(vers version.Binary) (string, error) { name := envtools.StorageName(vers) src := filepath.Join(toolsInfo.Dir, toolsInfo.StorageName) dest := filepath.Join(toolsInfo.Dir, name) err := utils.CopyFile(dest, src) if err != nil { return "", err } // Append to targetTools the attributes required to write out tools metadata. targetTools = append(targetTools, &coretools.Tools{ Version: vers, Size: toolsInfo.Size, SHA256: toolsInfo.Sha256Hash, }) return name, nil } logger.Debugf("generating tarballs for %v", series) for _, series := range series { _, err := ubuntu.SeriesVersion(series) if err != nil { return err } if series != toolsInfo.Version.Series { fakeVersion := toolsInfo.Version fakeVersion.Series = series if _, err := putTools(fakeVersion); err != nil { return err } } } // The tools have been copied to a temp location from which they will be uploaded, // now write out the matching simplestreams metadata so that SyncTools can find them. metadataStore, err := filestorage.NewFileStorageWriter(toolsInfo.Dir) if err != nil { return err } logger.Debugf("generating tools metadata") return envtools.MergeAndWriteMetadata(metadataStore, targetTools, false) }
// Create creates a new container based on the given template. func (mock *mockContainer) Create(configFile, template string, extraArgs []string, templateArgs []string) error { if mock.getState() != golxc.StateUnknown { return fmt.Errorf("container is already created") } mock.factory.instances[mock.name] = mock // Create the container directory. containerDir := filepath.Join(mock.factory.containerDir, mock.name) if err := os.MkdirAll(containerDir, 0755); err != nil { return err } if err := utils.CopyFile(mock.configFilename(), configFile); err != nil { return err } mock.setState(golxc.StateStopped) mock.factory.notify(eventArgs(Created, mock.name, extraArgs, templateArgs)) return nil }