Skip to content

Commit

Permalink
Small permissions fix + misc cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
sclevine committed Aug 20, 2018
1 parent 425875a commit 7aec268
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 76 deletions.
7 changes: 1 addition & 6 deletions detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ const (
CodeDetectFail = 100
)

type SimpleBuildpack struct {
ID string `toml:"id"`
Version string `toml:"version"`
}

type Buildpack struct {
ID string `toml:"id"`
Version string `toml:"version"`
Name string `toml:"name"`
Name string `toml:"-"`
Dir string `toml:"-"`
}

Expand Down
2 changes: 1 addition & 1 deletion exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (e *Exporter) GetMetadata(image v1.Image) (packs.BuildMetadata, error) {
if err != nil {
return metadata, fmt.Errorf("read config: %s", err)
}
label := cfg.Config.Labels["sh.packs.build"]
label := cfg.Config.Labels[packs.BuildLabel]
if err := json.Unmarshal([]byte(label), &metadata); err != nil {
return metadata, fmt.Errorf("unmarshal: %s", err)
}
Expand Down
18 changes: 6 additions & 12 deletions exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"
"github.com/buildpack/packs"
)

func TestExporter(t *testing.T) {
Expand Down Expand Up @@ -50,6 +51,7 @@ func testExporter(t *testing.T, when spec.G, it spec.S) {
Err: io.MultiWriter(stderr, it.Out()),
}
})

it.After(func() {
if err := os.RemoveAll(tmpDir); err != nil {
t.Fatal(err)
Expand All @@ -66,7 +68,7 @@ func testExporter(t *testing.T, when spec.G, it spec.S) {
}
})

it("a simple launch dir exists", func() {
it("should process a simple launch directory", func() {
image, err := exporter.Export("testdata/exporter/first/launch", stackImage, nil)
if err != nil {
t.Fatalf("Error: %s\n", err)
Expand Down Expand Up @@ -124,7 +126,7 @@ func testExporter(t *testing.T, when spec.G, it spec.S) {
}
})

when("rebuilding when toml exists without directory", func() {
when("rebuilding when layer TOML exists without directory", func() {
var firstImage v1.Image
it.Before(func() {
var err error
Expand All @@ -134,7 +136,7 @@ func testExporter(t *testing.T, when spec.G, it spec.S) {
}
})

it("reuses layers if there is a layer.toml file", func() {
it("should reuse layers if there is a layer TOML file", func() {
image, err := exporter.Export("testdata/exporter/second/launch", stackImage, firstImage)
if err != nil {
t.Fatalf("Error: %s\n", err)
Expand Down Expand Up @@ -185,14 +187,6 @@ func getBusyboxWithEntrypoint() (v1.Image, error) {
return mutate.Config(stackImage, config)
}

func randString(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = 'a' + byte(rand.Intn(26))
}
return string(b)
}

func getLayerFile(layer v1.Layer, path string) (string, error) {
r, err := layer.Uncompressed()
if err != nil {
Expand Down Expand Up @@ -252,7 +246,7 @@ func getMetadata(image v1.Image) (metadata, error) {
if err != nil {
return metadata, fmt.Errorf("read config: %s", err)
}
label := cfg.Config.Labels["sh.packs.build"]
label := cfg.Config.Labels[packs.BuildLabel]
if err := json.Unmarshal([]byte(label), &metadata); err != nil {
return metadata, fmt.Errorf("unmarshal: %s", err)
}
Expand Down
20 changes: 10 additions & 10 deletions launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (l *Launcher) Launch(executable, startCommand string) error {
return packs.FailErr(err, "determine start command")
}

launcher, err := l.profiled()
launcher, err := l.profileD()
if err != nil {
return packs.FailErr(err, "determine profile")
}
Expand All @@ -61,8 +61,8 @@ func (l *Launcher) Launch(executable, startCommand string) error {
return nil
}

func (l *Launcher) profiled() (string, error) {
var script []string
func (l *Launcher) profileD() (string, error) {
var out []string

appendIfFile := func(path string) error {
fi, err := os.Stat(path)
Expand All @@ -73,18 +73,18 @@ func (l *Launcher) profiled() (string, error) {
return err
}
if !fi.IsDir() {
script = append(script, fmt.Sprintf(`source "%s"`, path))
out = append(out, fmt.Sprintf(`source "%s"`, path))
}
return nil
}

for _, bp := range l.Buildpacks {
pdscripts, err := filepath.Glob(filepath.Join(l.DefaultLaunchDir, bp, "*", "profile.d", "*"))
scripts, err := filepath.Glob(filepath.Join(l.DefaultLaunchDir, bp, "*", "profile.d", "*"))
if err != nil {
return "", err
}
for _, pdscript := range pdscripts {
if err := appendIfFile(pdscript); err != nil {
for _, script := range scripts {
if err := appendIfFile(script); err != nil {
return "", err
}
}
Expand All @@ -94,8 +94,8 @@ func (l *Launcher) profiled() (string, error) {
return "", err
}

script = append(script, `exec bash -c "$@"`)
return strings.Join(script, "\n"), nil
out = append(out, `exec bash -c "$@"`)
return strings.Join(out, "\n"), nil
}

func (l *Launcher) processFor(cmd string) (string, error) {
Expand All @@ -104,7 +104,7 @@ func (l *Launcher) processFor(cmd string) (string, error) {
return process, nil
}

return "", fmt.Errorf("process type %s was not available", l.DefaultProcessType)
return "", fmt.Errorf("process type %s was not found", l.DefaultProcessType)
}

if process, ok := l.findProcessType(cmd); ok {
Expand Down
66 changes: 48 additions & 18 deletions launcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type syscallExecArgs struct {
}

func testLauncher(t *testing.T, when spec.G, it spec.S) {

var (
launcher *lifecycle.Launcher
tmpDir string
Expand Down Expand Up @@ -68,7 +67,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {

when("#Launch", func() {
when("no start command has been specified", func() {
it("runs the default process type", func() {
it("should run the default process type", func() {
if err := launcher.Launch("/path/to/launcher", ""); err != nil {
t.Fatal(err)
}
Expand All @@ -90,7 +89,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
})

when("default start process type is not in the process types", func() {
it("returns an error", func() {
it("should return an error", func() {
launcher.DefaultProcessType = "not-exist"

err := launcher.Launch("/path/to/launcher", "")
Expand All @@ -104,9 +103,10 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("start command has been specified", func() {
when("start command matches a process type", func() {
it("runs that process type", func() {
it("should run that process type", func() {
if err := launcher.Launch("/path/to/launcher", "worker"); err != nil {
t.Fatal(err)
}
Expand All @@ -120,8 +120,9 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
}
})
})

when("start command does NOT match a process type", func() {
it("runs the start command", func() {
it("should run the start command", func() {
if err := launcher.Launch("/path/to/launcher", "some-different-process"); err != nil {
t.Fatal(err)
}
Expand All @@ -146,7 +147,7 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
{Type: "start", Command: "./start"},
}
launcher.Buildpacks = []string{"bp.1", "bp.2"}
launcher.Exec = syscallExecWithStdout(tmpDir)
launcher.Exec = syscallExecWithStdout(t, tmpDir)

if err := os.MkdirAll(filepath.Join(tmpDir, "launch", "bp.1", "layer", "profile.d"), 0755); err != nil {
t.Fatal(err)
Expand All @@ -161,32 +162,44 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
t.Fatal(err)
}
})
it("runs them in buildpack order", func() {

it("should run them in buildpack order", func() {
if err := launcher.Launch("/path/to/launcher", "start"); err != nil {
t.Fatal(err)
}

stdout, _ := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
stdout, err := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
if err != nil {
t.Fatal(err)
}
expected := "apple\nbanana\nhi from app\n"

if len(stdout) == 0 {
stderr, _ := ioutil.ReadFile(filepath.Join(tmpDir, "stderr"))
stderr, err := ioutil.ReadFile(filepath.Join(tmpDir, "stderr"))
if err != nil {
t.Fatal(err)
}
t.Fatalf("stdout was empty: stderr: %s", stderr)
}
if diff := cmp.Diff(string(stdout), expected); diff != "" {
t.Fatalf(`syscall.Exec stdout did not match: (-got +want)\n%s`, diff)
}
})

when("changing the buildpack order", func() {
it.Before(func() {
launcher.Buildpacks = []string{"bp.2", "bp.1"}
})
it("runs them in buildpack order", func() {

it("should run them in buildpack order", func() {
if err := launcher.Launch("/path/to/launcher", "start"); err != nil {
t.Fatal(err)
}

stdout, _ := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
stdout, err := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
if err != nil {
t.Fatal(err)
}
expected := "banana\napple\nhi from app\n"

if len(stdout) == 0 {
Expand All @@ -198,22 +211,30 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
}
})
})

when("app has '.profile'", func() {
it.Before(func() {
if err := ioutil.WriteFile(filepath.Join(tmpDir, "launch", "app", ".profile"), []byte("echo from profile"), 0644); err != nil {
t.Fatal(err)
}
})
it("sources .profile", func() {

it("should source .profile", func() {
if err := launcher.Launch("/path/to/launcher", "start"); err != nil {
t.Fatal(err)
}

stdout, _ := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
stdout, err := ioutil.ReadFile(filepath.Join(tmpDir, "stdout"))
if err != nil {
t.Fatal(err)
}
expected := "apple\nbanana\nfrom profile\nhi from app\n"

if len(stdout) == 0 {
stderr, _ := ioutil.ReadFile(filepath.Join(tmpDir, "stderr"))
stderr, err := ioutil.ReadFile(filepath.Join(tmpDir, "stderr"))
if err != nil {
t.Fatal(err)
}
t.Fatalf("stdout was empty: stderr: %s", stderr)
}
if diff := cmp.Diff(string(stdout), expected); diff != "" {
Expand All @@ -225,10 +246,19 @@ func testLauncher(t *testing.T, when spec.G, it spec.S) {
})
}

func syscallExecWithStdout(tmpDir string) func(argv0 string, argv []string, envv []string) error {
fstdin, _ := os.Create(filepath.Join(tmpDir, "stdin"))
fstdout, _ := os.Create(filepath.Join(tmpDir, "stdout"))
fstderr, _ := os.Create(filepath.Join(tmpDir, "stderr"))
func syscallExecWithStdout(t *testing.T, tmpDir string) func(argv0 string, argv []string, envv []string) error {
fstdin, err := os.Create(filepath.Join(tmpDir, "stdin"))
if err != nil {
t.Fatal(err)
}
fstdout, err := os.Create(filepath.Join(tmpDir, "stdout"))
if err != nil {
t.Fatal(err)
}
fstderr, err := os.Create(filepath.Join(tmpDir, "stderr"))
if err != nil {
t.Fatal(err)
}

return func(argv0 string, argv []string, envv []string) error {
pid, err := syscall.ForkExec(argv0, argv, &syscall.ProcAttr{
Expand Down
39 changes: 22 additions & 17 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,33 @@ import (

type BuildpackMap map[string]*Buildpack

type buildpackTOML struct {
ID string `toml:"id"`
Version string `toml:"version"`
Name string `toml:"name"`
}

func NewBuildpackMap(dir string) (BuildpackMap, error) {
buildpacks := BuildpackMap{}
glob := filepath.Join(dir, "*", "*", "buildpack.toml")
files, err := filepath.Glob(glob)
if err != nil {
return nil, err
}
for _, bpTOML := range files {
buildpackDir := filepath.Dir(bpTOML)
for _, file := range files {
buildpackDir := filepath.Dir(file)
base, version := filepath.Split(buildpackDir)
_, id := filepath.Split(filepath.Clean(base))
var buildpack Buildpack
if _, err := toml.DecodeFile(bpTOML, &buildpack); err != nil {
var bpTOML buildpackTOML
if _, err := toml.DecodeFile(file, &bpTOML); err != nil {
return nil, err
}
buildpack.Dir = buildpackDir
buildpacks[id+"@"+version] = &buildpack
buildpacks[id+"@"+version] = &Buildpack{
ID: bpTOML.ID,
Version: bpTOML.Version,
Name: bpTOML.Name,
Dir: buildpackDir,
}
}
return buildpacks, nil
}
Expand Down Expand Up @@ -63,27 +73,22 @@ func (m BuildpackMap) ReadOrder(orderPath string) (BuildpackOrder, error) {
}

func (g *BuildpackGroup) Write(path string) error {
buildpacks := make([]*SimpleBuildpack, 0, len(g.Buildpacks))
for _, b := range g.Buildpacks {
buildpacks = append(buildpacks, &SimpleBuildpack{ID: b.ID, Version: b.Version})
}

data := struct {
Repository string `toml:"repository"`
Buildpacks []*SimpleBuildpack `toml:"buildpacks"`
Repository string `toml:"repository"`
Buildpacks []*Buildpack `toml:"buildpacks"`
}{
Repository: g.Repository,
Buildpacks: buildpacks,
Buildpacks: g.Buildpacks,
}

return WriteTOML(path, data)
}

func (m BuildpackMap) ReadGroup(path string) (BuildpackGroup, error) {
func (m BuildpackMap) ReadGroup(path string) (*BuildpackGroup, error) {
var group BuildpackGroup
if _, err := toml.DecodeFile(path, &group); err != nil {
return BuildpackGroup{}, err
return nil, err
}
group.Buildpacks = m.mapFull(group.Buildpacks)
return group, nil
return &group, nil
}
Loading

0 comments on commit 7aec268

Please sign in to comment.