Example #1
0
func TestBeginLocalACI(t *testing.T) {
	manblob, err := json.Marshal(detailedManifest())
	if err != nil {
		panic(err)
	}

	tmpexpandedaci := mustTempDir()
	defer os.RemoveAll(tmpexpandedaci)

	err = ioutil.WriteFile(path.Join(tmpexpandedaci, aci.ManifestFile), manblob, 0644)
	if err != nil {
		panic(err)
	}

	err = os.Mkdir(path.Join(tmpexpandedaci, aci.RootfsDir), 0755)
	if err != nil {
		panic(err)
	}

	tmpaci, err := ioutil.TempFile("", "acbuild-test")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(tmpaci.Name())

	aw := aci.NewImageWriter(detailedManifest(), tar.NewWriter(tmpaci))
	err = filepath.Walk(tmpexpandedaci, aci.BuildWalker(tmpexpandedaci, aw, nil))
	aw.Close()
	if err != nil {
		panic(err)
	}
	tmpaci.Close()

	workingDir := mustTempDir()
	defer cleanUpTest(workingDir)

	_, _, _, err = runACBuild(workingDir, "begin", tmpaci.Name())
	if err != nil {
		t.Fatalf("%s\n", err.Error())
	}

	checkManifest(t, workingDir, detailedManifest())
	checkEmptyRootfs(t, workingDir)
}
Example #2
0
// Write will produce the resulting ACI from the current build context, saving
// it to the given path, optionally signing it.
func (a *ACBuild) Write(output string, overwrite, sign bool, gpgflags []string) (err error) {
	if err = a.lock(); err != nil {
		return err
	}
	defer func() {
		if err1 := a.unlock(); err == nil {
			err = err1
		}
	}()

	man, err := util.GetManifest(a.CurrentACIPath)
	if err != nil {
		return err
	}

	if man.App != nil && len(man.App.Exec) == 0 {
		fmt.Fprintf(os.Stderr, "warning: exec command was never set.\n")
	}

	if man.Name == types.ACIdentifier(placeholdername) {
		return fmt.Errorf("can't write ACI, name was never set")
	}

	fileFlags := os.O_CREATE | os.O_WRONLY

	_, err = os.Stat(output)
	switch {
	case os.IsNotExist(err):
		break
	case err != nil:
		return err
	default:
		if !overwrite {
			return fmt.Errorf("ACI already exists: %s", output)
		}
		fileFlags |= os.O_TRUNC
	}

	// open/create the aci file
	ofile, err := os.OpenFile(output, fileFlags, 0644)
	if err != nil {
		return err
	}
	defer ofile.Close()

	defer func() {
		// When write is done, if an error is encountered remove the partial
		// ACI that had been written.
		if err != nil {
			os.Remove(output)
			os.Remove(output + ".asc")
		}
	}()

	// setup compression
	gzwriter := gzip.NewWriter(ofile)
	defer gzwriter.Close()

	// create the aci writer
	aw := aci.NewImageWriter(*man, tar.NewWriter(gzwriter))
	err = filepath.Walk(a.CurrentACIPath, aci.BuildWalker(a.CurrentACIPath, aw, nil))
	defer aw.Close()
	if err != nil {
		pathErr, ok := err.(*os.PathError)
		if !ok {
			fmt.Printf("not a path error!\n")
			return err
		}
		syscallErrno, ok := pathErr.Err.(syscall.Errno)
		if !ok {
			fmt.Printf("not a syscall errno!\n")
			return err
		}
		if pathErr.Op == "open" && syscallErrno != syscall.EACCES {
			return err
		}
		problemPath := pathErr.Path[len(path.Join(a.CurrentACIPath, aci.RootfsDir)):]
		return fmt.Errorf("%q: permission denied - call write as root", problemPath)
	}

	if sign {
		err = signACI(output, output+".asc", gpgflags)
		if err != nil {
			return err
		}
	}

	return nil
}
Example #3
0
func TestBeginLocalACI(t *testing.T) {
	wim := schema.ImageManifest{
		ACKind:    schema.ImageManifestKind,
		ACVersion: schema.AppContainerVersion,
		Name:      *types.MustACIdentifier("acbuild-begin-test"),
		Labels: types.Labels{
			types.Label{
				Name:  *types.MustACIdentifier("version"),
				Value: "9001",
			},
		},
		App: &types.App{
			Exec:  types.Exec{"/bin/nethack4", "-D", "wizard"},
			User:  "******",
			Group: "0",
			Environment: types.Environment{
				types.EnvironmentVariable{
					Name:  "FOO",
					Value: "BAR",
				},
			},
			MountPoints: []types.MountPoint{
				types.MountPoint{
					Name:     *types.MustACName("nethack4-data"),
					Path:     "/root/nethack4-data",
					ReadOnly: true,
				},
			},
			Ports: []types.Port{
				types.Port{
					Name:     *types.MustACName("gopher"),
					Protocol: "tcp",
					Port:     70,
					Count:    1,
				},
			},
		},
		Annotations: types.Annotations{
			types.Annotation{
				Name:  *types.MustACIdentifier("author"),
				Value: "the acbuild devs",
			},
		},
		Dependencies: types.Dependencies{
			types.Dependency{
				ImageName: *types.MustACIdentifier("quay.io/gnu/hurd"),
			},
		},
	}

	manblob, err := wim.MarshalJSON()
	if err != nil {
		panic(err)
	}

	tmpexpandedaci := mustTempDir()
	defer os.RemoveAll(tmpexpandedaci)

	err = ioutil.WriteFile(path.Join(tmpexpandedaci, aci.ManifestFile), manblob, 0644)
	if err != nil {
		panic(err)
	}

	err = os.Mkdir(path.Join(tmpexpandedaci, aci.RootfsDir), 0755)
	if err != nil {
		panic(err)
	}

	tmpaci, err := ioutil.TempFile("", "acbuild-test")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(tmpaci.Name())

	aw := aci.NewImageWriter(wim, tar.NewWriter(tmpaci))
	err = filepath.Walk(tmpexpandedaci, aci.BuildWalker(tmpexpandedaci, aw, nil))
	aw.Close()
	if err != nil {
		panic(err)
	}
	tmpaci.Close()

	tmpdir := mustTempDir()
	defer cleanUpTest(tmpdir)

	err = runAcbuild(tmpdir, "begin", tmpaci.Name())
	if err != nil {
		t.Fatalf("%v", err)
	}

	checkMinimalContainer(t, path.Join(tmpdir, ".acbuild", "currentaci"), wim)
}
Example #4
0
// Write will produce the resulting ACI from the current build context, saving
// it to the given path, optionally signing it.
func (a *ACBuild) Write(output string, overwrite, sign bool, gpgflags []string) (err error) {
	if err = a.lock(); err != nil {
		return err
	}
	defer func() {
		if err1 := a.unlock(); err == nil {
			err = err1
		}
	}()

	man, err := util.GetManifest(a.CurrentACIPath)
	if err != nil {
		return err
	}

	if man.App != nil && len(man.App.Exec) == 0 {
		fmt.Fprintf(os.Stderr, "warning: exec command was never set.\n")
	}

	if man.Name == types.ACIdentifier(placeholdername) {
		return fmt.Errorf("can't write ACI, name was never set")
	}

	fileFlags := os.O_CREATE | os.O_WRONLY

	ex, err := util.Exists(output)
	if err != nil {
		return err
	}
	if ex {
		if !overwrite {
			return fmt.Errorf("ACI already exists: %s", output)
		}
		fileFlags |= os.O_TRUNC
	}

	// open/create the aci file
	ofile, err := os.OpenFile(output, fileFlags, 0644)
	if err != nil {
		return err
	}
	defer ofile.Close()

	// setup compression
	gzwriter := gzip.NewWriter(ofile)
	defer gzwriter.Close()

	// create the aci writer
	aw := aci.NewImageWriter(*man, tar.NewWriter(gzwriter))
	err = filepath.Walk(a.CurrentACIPath, aci.BuildWalker(a.CurrentACIPath, aw, nil))
	defer aw.Close()
	if err != nil {
		return err
	}

	if sign {
		err = signACI(output, output+".asc", gpgflags)
		if err != nil {
			os.Remove(output)
			os.Remove(output + ".asc")
			return err
		}
	}

	return nil
}