Ejemplo n.º 1
0
// FetchAndRender will fetch the given image and all of its dependencies if
// they have not been fetched yet, and will then render them on to the
// filesystem if they have not been rendered yet.
func (r Registry) FetchAndRender(imagename types.ACIdentifier, labels types.Labels, size uint) error {
	_, err := r.GetACI(imagename, labels)
	if err == ErrNotFound {
		err := r.fetchACIWithSize(imagename, labels, size)
		if err != nil {
			return err
		}
	}

	filesToRender, err := acirenderer.GetRenderedACI(imagename,
		labels, r)
	if err != nil {
		return err
	}

	for _, fs := range filesToRender {
		ex, err := util.Exists(path.Join(r.Scratchpath, fs.Key, "rendered"))
		if err != nil {
			return err
		}
		if ex {
			//This ACI has already been rendered
			continue
		}

		err = util.UnTar(path.Join(r.Depstore, fs.Key),
			path.Join(r.Scratchpath, fs.Key), fs.FileMap)
		if err != nil {
			return err
		}

		rfile, err := os.Create(path.Join(r.Scratchpath, fs.Key, "rendered"))
		if err != nil {
			return err
		}
		rfile.Close()
	}
	return nil
}
Ejemplo n.º 2
0
// FetchAndRender will fetch the given image and all of its dependencies if
// they have not been fetched yet, and will then render them on to the
// filesystem if they have not been rendered yet.
func (r Registry) FetchAndRender(imagename types.ACIdentifier, labels types.Labels, size uint) error {
	err := r.Fetch(imagename, labels, size, true)
	if err != nil {
		return err
	}

	filesToRender, err := acirenderer.GetRenderedACI(imagename,
		labels, r)
	if err != nil {
		return err
	}

	for _, fs := range filesToRender {
		ex, err := util.Exists(
			path.Join(r.DepStoreExpandedPath, fs.Key, "rendered"))
		if err != nil {
			return err
		}
		if ex {
			//This ACI has already been rendered
			continue
		}

		err = util.UnTar(path.Join(r.DepStoreTarPath, fs.Key),
			path.Join(r.DepStoreExpandedPath, fs.Key), fs.FileMap)
		if err != nil {
			return err
		}

		rfile, err := os.Create(
			path.Join(r.DepStoreExpandedPath, fs.Key, "rendered"))
		if err != nil {
			return err
		}
		rfile.Close()
	}
	return nil
}
Ejemplo n.º 3
0
func (a *ACBuild) beginFromImage(start string, insecure bool) error {
	// Check if we're starting with a file
	finfo, err := os.Stat(start)
	if err == nil {
		if finfo.IsDir() {
			return fmt.Errorf("provided starting ACI is a directory: %s", start)
		}
		return util.UnTar(start, a.CurrentACIPath, nil)
	} else if !os.IsNotExist(err) {
		return err
	}

	// Check if we're starting with a docker image
	if strings.HasPrefix(start, "docker://") {
		// TODO use docker2aci
		return fmt.Errorf("docker containers are currently unsupported")
	}

	// Perform meta discovery, download the ACI, and start with that.

	app, err := discovery.NewAppFromString(start)
	if err != nil {
		return err
	}
	labels, err := types.LabelsFromMap(app.Labels)
	if err != nil {
		return err
	}

	tmpDepStoreTarPath, err := ioutil.TempDir("", "acbuild-begin-tar")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpDepStoreTarPath)

	tmpDepStoreExpandedPath, err := ioutil.TempDir("", "acbuild-begin-expanded")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpDepStoreExpandedPath)

	reg := registry.Registry{
		DepStoreTarPath:      tmpDepStoreTarPath,
		DepStoreExpandedPath: tmpDepStoreExpandedPath,
		Insecure:             insecure,
		Debug:                a.Debug,
	}

	err = reg.Fetch(app.Name, labels, 0, false)
	if err != nil {
		return err
	}

	files, err := ioutil.ReadDir(tmpDepStoreTarPath)
	if err != nil {
		return err
	}

	if len(files) != 1 {
		var filelist string
		for _, file := range files {
			if filelist == "" {
				filelist = file.Name()
			} else {
				filelist = filelist + ", " + file.Name()
			}
		}
		panic("unexpected number of files in store after download: " + filelist)
	}

	return util.UnTar(path.Join(tmpDepStoreTarPath, files[0].Name()), a.CurrentACIPath, nil)
}
Ejemplo n.º 4
0
// Begin will start a new build, storing the untarred ACI the build operates on
// at tmpaci. If start is the empty string, the build will begin with an empty
// ACI, otherwise the ACI stored at start will be used at the starting point.
func Begin(tmpaci, start string) error {
	ex, err := util.Exists(tmpaci)
	if err != nil {
		return err
	}
	if ex {
		return fmt.Errorf("build already in progress? path exists: %s", tmpaci)
	}

	err = os.MkdirAll(path.Join(tmpaci, aci.RootfsDir), 0755)
	if err != nil {
		return err
	}

	if start != "" {
		ex, err := util.Exists(start)
		if err != nil {
			return err
		}
		if !ex {
			return fmt.Errorf("start aci doesn't exist: %s", start)
		}

		err = util.UnTar(start, tmpaci, nil)
		if err != nil {
			return err
		}

		return nil
	}

	acid, err := types.NewACIdentifier("acbuild-unnamed")
	if err != nil {
		return err
	}

	manifest := &schema.ImageManifest{
		ACKind:    schema.ImageManifestKind,
		ACVersion: schema.AppContainerVersion,
		Name:      *acid,
		App: &types.App{
			Exec:  placeholderexec,
			User:  "0",
			Group: "0",
		},
	}

	manblob, err := manifest.MarshalJSON()
	if err != nil {
		return err
	}

	manfile, err := os.Create(path.Join(tmpaci, aci.ManifestFile))
	if err != nil {
		return err
	}

	_, err = manfile.Write(manblob)
	if err != nil {
		return err
	}

	err = manfile.Close()
	if err != nil {
		return err
	}

	return nil
}