diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index b3ec78260..429ff4719 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -1,7 +1,9 @@ package acceptance import ( + "bytes" "context" + "crypto/md5" "fmt" "io/ioutil" "math/rand" @@ -204,6 +206,63 @@ func testPack(t *testing.T, when spec.G, it spec.S) { }, spec.Parallel(), spec.Report(report.Terminal{})) }, spec.Parallel(), spec.Report(report.Terminal{})) + when("pack run", func() { + var sourceCodePath string + + it.Before(func() { + var err error + sourceCodePath, err = ioutil.TempDir("", "pack.build.node_app.") + if err != nil { + t.Fatal(err) + } + h.Run(t, exec.Command("cp", "-r", "testdata/node_app/.", sourceCodePath)) + + }) + it.After(func() { + repoName := fmt.Sprintf("pack.local/run/%x", md5.Sum([]byte(sourceCodePath))) + dockerCli.ImageRemove(context.TODO(), repoName, dockertypes.ImageRemoveOptions{Force: true, PruneChildren: true}) + + if sourceCodePath != "" { + os.RemoveAll(sourceCodePath) + } + }) + + it("starts an image", func() { + var buf bytes.Buffer + cmd := exec.Command(pack, "run", "--port", "3000") + cmd.Env = []string{"PACK_HOME=" + packHome} + cmd.Stdout = &buf + cmd.Stderr = &buf + cmd.Dir = sourceCodePath + cmd.Start() + + defer func() { + h.AssertNil(t, cmd.Process.Signal(os.Interrupt)) + }() + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + timer := time.NewTimer(2 * time.Minute) + defer timer.Stop() + + Loop: + for { + select { + case <-ticker.C: + if strings.Contains(buf.String(), "Example app listening on port 3000!") { + break Loop + } + case <-timer.C: + t.Fatal("timeout waiting for app to be up:\n", buf.String()) + } + } + + txt := h.HttpGet(t, "http://localhost:3000") + h.AssertEq(t, txt, "Buildpacks Worked! - 1000:1000") + }) + + }, spec.Parallel(), spec.Report(report.Terminal{})) + when("pack rebase", func() { var repoName, containerName, runBefore, runAfter string var buildAndSetRunImage func(runImage, contents1, contents2 string) diff --git a/build.go b/build.go index 0217d3cef..5475c0c41 100644 --- a/build.go +++ b/build.go @@ -119,6 +119,9 @@ func (bf *BuildFactory) BuildConfigFromFlags(f *BuildFlags) (*BuildConfig, error return nil, err } + if f.RepoName == "" { + f.RepoName = fmt.Sprintf("pack.local/run/%x", md5.Sum([]byte(appDir))) + } b := &BuildConfig{ AppDir: appDir, diff --git a/cmd/pack/main.go b/cmd/pack/main.go index c10b69a67..d8c9e7b60 100644 --- a/cmd/pack/main.go +++ b/cmd/pack/main.go @@ -59,19 +59,11 @@ func buildCommand() *cobra.Command { return b.Run() }, } - buildCommand.Flags().StringVarP(&buildFlags.AppDir, "path", "p", "current working directory", "path to app dir") - buildCommand.Flags().StringVar(&buildFlags.Builder, "builder", "", "builder") - buildCommand.Flags().StringVar(&buildFlags.RunImage, "run-image", "", "run image") - buildCommand.Flags().StringVar(&buildFlags.EnvFile, "env-file", "", "env file") - buildCommand.Flags().BoolVar(&buildFlags.Publish, "publish", false, "publish to registry") - buildCommand.Flags().BoolVar(&buildFlags.NoPull, "no-pull", false, "don't pull images before use") - buildCommand.Flags().StringArrayVar(&buildFlags.Buildpacks, "buildpack", []string{}, "buildpack ID or host directory path, \n\t\t repeat for each buildpack in order") + buildCommandFlags(buildCommand, &buildFlags) return buildCommand } func runCommand() *cobra.Command { - wd, _ := os.Getwd() - var runFlags pack.RunFlags runCommand := &cobra.Command{ Use: "run", @@ -90,13 +82,22 @@ func runCommand() *cobra.Command { return r.Run(makeStopChannelForSignals) }, } - runCommand.Flags().StringVarP(&runFlags.AppDir, "path", "p", wd, "path to app dir") - runCommand.Flags().StringVar(&runFlags.Builder, "builder", "packs/samples", "builder") - runCommand.Flags().StringVar(&runFlags.RunImage, "run-image", "packs/run", "run image") + + buildCommandFlags(runCommand, &runFlags.BuildFlags) runCommand.Flags().StringVar(&runFlags.Port, "port", "", "comma separated ports to publish, defaults to ports exposed by the container") return runCommand } +func buildCommandFlags(cmd *cobra.Command, buildFlags *pack.BuildFlags) { + cmd.Flags().StringVarP(&buildFlags.AppDir, "path", "p", "current working directory", "path to app dir") + cmd.Flags().StringVar(&buildFlags.Builder, "builder", "", "builder") + cmd.Flags().StringVar(&buildFlags.RunImage, "run-image", "", "run image") + cmd.Flags().StringVar(&buildFlags.EnvFile, "env-file", "", "env file") + cmd.Flags().BoolVar(&buildFlags.Publish, "publish", false, "publish to registry") + cmd.Flags().BoolVar(&buildFlags.NoPull, "no-pull", false, "don't pull images before use") + cmd.Flags().StringArrayVar(&buildFlags.Buildpacks, "buildpack", []string{}, "buildpack ID or host directory path, \n\t\t repeat for each buildpack in order") +} + func rebaseCommand() *cobra.Command { var flags pack.RebaseFlags cmd := &cobra.Command{ diff --git a/run.go b/run.go index 3354e2abd..1de038f21 100644 --- a/run.go +++ b/run.go @@ -2,11 +2,9 @@ package pack import ( "context" - "crypto/md5" "fmt" "io" "log" - "path/filepath" "strconv" "strings" @@ -17,9 +15,7 @@ import ( ) type RunFlags struct { - AppDir string - Builder string - RunImage string + BuildFlags BuildFlags Port string } @@ -34,15 +30,8 @@ type RunConfig struct { Log *log.Logger } -func (bf *BuildFactory) RunConfigFromFlags(f *RunFlags) (*RunConfig, error) { - bc, err := bf.BuildConfigFromFlags(&BuildFlags{ - AppDir: f.AppDir, - Builder: f.Builder, - RunImage: f.RunImage, - RepoName: f.repoName(), - Publish: false, - NoPull: false, - }) +func (bf *BuildFactory) RunConfigFromFlags( f *RunFlags) (*RunConfig, error) { + bc, err := bf.BuildConfigFromFlags(&f.BuildFlags) if err != nil { return nil, err } @@ -66,9 +55,11 @@ func Run(appDir, buildImage, runImage, port string, makeStopCh func() <-chan str return err } r, err := bf.RunConfigFromFlags(&RunFlags{ - AppDir: appDir, - Builder: buildImage, - RunImage: runImage, + BuildFlags: BuildFlags{ + AppDir: appDir, + Builder: buildImage, + RunImage: runImage, + }, Port: port, }) if err != nil { @@ -123,14 +114,6 @@ func (r *RunConfig) Run(makeStopCh func() <-chan struct{}) error { return nil } -func (r *RunFlags) repoName() string { - dir, _ := filepath.Abs(r.AppDir) - // we can ignore errors here because they will be caught later by the Build command - h := md5.New() - io.WriteString(h, dir) - return fmt.Sprintf("pack.local/run/%x", h.Sum(nil)) -} - func (r *RunConfig) exposedPorts(ctx context.Context, imageID string) (string, error) { i, _, err := r.Cli.ImageInspectWithRaw(ctx, imageID) if err != nil { diff --git a/run_test.go b/run_test.go index 1671178f6..32286844c 100644 --- a/run_test.go +++ b/run_test.go @@ -92,10 +92,12 @@ func testRun(t *testing.T, when spec.G, it spec.S) { }, nil, nil) run, err := factory.RunConfigFromFlags(&pack.RunFlags{ - AppDir: "acceptance/testdata/node_app", - Builder: "some/builder", - RunImage: "some/run", - Port: "1370", + BuildFlags: pack.BuildFlags{ + AppDir: "acceptance/testdata/node_app", + Builder: "some/builder", + RunImage: "some/run", + }, + Port: "1370", }) h.AssertNil(t, err)