Skip to content

Commit

Permalink
Fetch default ports from image
Browse files Browse the repository at this point in the history
Rather then default the port to 8080, if the user does not specify ports
the ports exposed by the image are used. The container will also no
longer assume that the port inside the container should be 8080, it is
now symetrical, unless the user explicitly make it asymetrical.
  • Loading branch information
scothis committed Oct 15, 2018
1 parent ddf741d commit 0d15e74
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cmd/pack/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func runCommand() *cobra.Command {
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")
runCommand.Flags().StringVar(&runFlags.Port, "port", "8080", "local port to bind")
runCommand.Flags().StringVar(&runFlags.Port, "port", "", "comma separated ports to publish, defaults to ports exposed by the container")
return runCommand
}

Expand Down
23 changes: 21 additions & 2 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ func (r *RunConfig) Run(makeStopCh func() <-chan struct{}) error {
}

fmt.Println("*** RUNNING:")
if r.Port == "" {
r.Port, err = r.exposedPorts(ctx, r.RepoName)
if err != nil {
return err
}
}
exposedPorts, portBindings, err := parsePorts(r.Port)
if err != nil {
return err
Expand Down Expand Up @@ -146,13 +152,25 @@ func (r *RunFlags) repoName() string {
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 {
return "", err
}
ports := []string{}
for port := range i.Config.ExposedPorts {
ports = append(ports, port.Port())
}
return strings.Join(ports, ","), nil
}

func parsePorts(port string) (nat.PortSet, nat.PortMap, error) {
ports := strings.Split(port, ",")
for i, p := range ports {
p = strings.TrimSpace(p)
if _, err := strconv.Atoi(p); err == nil {
// default simple port to localhost and 8080 inside the container
p = fmt.Sprintf("127.0.0.1:%s:8080/tcp", p)
// default simple port to localhost and inside the container
p = fmt.Sprintf("127.0.0.1:%s:%s/tcp", p, p)
}
ports[i] = p
}
Expand All @@ -172,6 +190,7 @@ func logContainerListening(log *log.Logger, portBindings nat.PortMap) {
if host == "127.0.0.1" {
host = "localhost"
}
// TODO the service may not be http based
log.Printf("Starting container listening at http://%s:%s/\n", host, port)
}
}
Expand Down
39 changes: 36 additions & 3 deletions run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func testRun(t *testing.T, when spec.G, it spec.S) {
it("builds an image and runs it", func() {
mockBuild.EXPECT().Run().Return(nil)

exposedPorts, portBindings, _ := nat.ParsePortSpecs([]string{"127.0.0.1:1370:8080/tcp"})
exposedPorts, portBindings, _ := nat.ParsePortSpecs([]string{"127.0.0.1:1370:1370/tcp"})
mockDocker.EXPECT().ContainerCreate(gomock.Any(), &container.Config{
Image: subject.RepoName,
AttachStdout: true,
Expand Down Expand Up @@ -222,13 +222,46 @@ func testRun(t *testing.T, when spec.G, it spec.S) {
})
})

when("the port is not specified", func() {
it.Before(func() {
subject.Port = ""
})

it("gets exposed ports from the built image", func() {
mockBuild.EXPECT().Run().Return(nil)

exposedPorts, portBindings, _ := nat.ParsePortSpecs([]string{
"127.0.0.1:8080:8080/tcp",
})
mockDocker.EXPECT().ImageInspectWithRaw(gomock.Any(), subject.RepoName).Return(types.ImageInspect{
Config: &container.Config{
ExposedPorts: exposedPorts,
},
}, []byte{}, nil)

mockDocker.EXPECT().ContainerCreate(gomock.Any(), &container.Config{
Image: subject.RepoName,
AttachStdout: true,
AttachStderr: true,
ExposedPorts: exposedPorts,
}, &container.HostConfig{
AutoRemove: true,
PortBindings: portBindings,
}, nil, "").Return(ctr, nil)

mockDocker.EXPECT().RunContainer(gomock.Any(), ctr.ID, subject.Stdout, subject.Stderr).Return(nil)

err := subject.Run(makeStopCh)
assertNil(t, err)
})
})
when("custom ports bindings are defined", func() {
it("binds simple ports from localhost to the container on 8080", func() {
it("binds simple ports from localhost to the container on the same port", func() {
mockBuild.EXPECT().Run().Return(nil)

subject.Port = "1370"
exposedPorts, portBindings, _ := nat.ParsePortSpecs([]string{
"127.0.0.1:1370:8080/tcp",
"127.0.0.1:1370:1370/tcp",
})
mockDocker.EXPECT().ContainerCreate(gomock.Any(), &container.Config{
Image: subject.RepoName,
Expand Down

0 comments on commit 0d15e74

Please sign in to comment.