Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions pkg/app/env_describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,20 @@ import (
var CommandDescribeEnvironment = &cli.Command{
Name: "describe",
Aliases: []string{"d"},
Usage: "Show details about environments, including dependencies",
Usage: "Show details about environments, including dependencies and port binding",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "env",
Usage: "Specify the envd environment to use",
Aliases: []string{"e"},
Name: "env",
Usage: "Specify the envd environment to use",
Aliases: []string{"e"},
Required: true,
},
},
Action: getEnvironmentDependency,
Action: getEnvironmentDescriptions,
}

func getEnvironmentDependency(clicontext *cli.Context) error {
func getEnvironmentDescriptions(clicontext *cli.Context) error {
envName := clicontext.String("env")
if envName == "" {
return errors.New("env is required")
}
envdEngine, err := envd.New(clicontext.Context)
if err != nil {
return errors.Wrap(err, "failed to create envd engine")
Expand All @@ -54,13 +52,20 @@ func getEnvironmentDependency(clicontext *cli.Context) error {
if err != nil {
return errors.Wrap(err, "failed to list dependencies")
}
renderDependencies(dep, os.Stdout)

ports, err := envdEngine.ListEnvPortBinding(clicontext.Context, envName)
if err != nil {
return errors.Wrap(err, "failed to list port bindings")
}

renderDependencies(os.Stdout, dep)
renderPortBindings(os.Stdout, ports)
return nil
}

func renderDependencies(dep *types.Dependency, w io.Writer) {
func createTable(w io.Writer, headers []string) *tablewriter.Table {
table := tablewriter.NewWriter(w)
table.SetHeader([]string{"Dependency", "Type"})
table.SetHeader(headers)

table.SetAutoWrapText(false)
table.SetAutoFormatHeaders(true)
Expand All @@ -70,13 +75,34 @@ func renderDependencies(dep *types.Dependency, w io.Writer) {
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetHeaderLine(false)
table.SetBorder(false)
table.SetBorder(true)
table.SetTablePadding("\t") // pad with tabs
table.SetNoWhiteSpace(true)

return table
}

func renderPortBindings(w io.Writer, ports []types.PortBinding) {
if ports == nil {
return
}
table := createTable(w, []string{"Container Port", "Protocol", "Host IP", "Host Port"})
for _, port := range ports {
row := make([]string, 4)
row[0] = port.Port
row[1] = port.Protocol
row[2] = port.HostIP
row[3] = port.HostPort
table.Append(row)
}
table.Render()
}

func renderDependencies(w io.Writer, dep *types.Dependency) {
if dep == nil {
return
}
table := createTable(w, []string{"Dependencies", "Type"})
for _, p := range dep.PyPIPackages {
envRow := make([]string, 2)
envRow[0] = p
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/image_describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ func getImageDependency(clicontext *cli.Context) error {
if err != nil {
return errors.Wrap(err, "failed to list dependencies")
}
renderDependencies(dep, os.Stdout)
renderDependencies(os.Stdout, dep)
return nil
}
11 changes: 11 additions & 0 deletions pkg/envd/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Engine interface {
ResumeEnvironment(ctx context.Context, env string) (string, error)
ListEnvironment(ctx context.Context) ([]types.EnvdEnvironment, error)
ListEnvDependency(ctx context.Context, env string) (*types.Dependency, error)
ListEnvPortBinding(ctx context.Context, env string) ([]types.PortBinding, error)
GetInfo(ctx context.Context) (*types.EnvdInfo, error)
}

Expand Down Expand Up @@ -142,6 +143,16 @@ func (e generalEngine) ListEnvDependency(
return dep, nil
}

func (e generalEngine) ListEnvPortBinding(ctx context.Context, env string) ([]types.PortBinding, error) {
logrus.WithField("env", env).Debug("getting env port bindings")
ctr, err := e.dockerCli.GetContainer(ctx, env)
if err != nil {
return nil, errors.Wrap(err, "failed to get container")
}
ports := types.NewPortBindingFromContainerJSON(ctr)
return ports, nil
}

func (e generalEngine) GetInfo(ctx context.Context) (*types.EnvdInfo, error) {
info, err := e.dockerCli.GetInfo(ctx)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions pkg/types/envd.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ type Dependency struct {
PyPIPackages []string `json:"pypi_packages,omitempty"`
}

type PortBinding struct {
Port string
Protocol string
HostIP string
HostPort string
}

func NewImage(image types.ImageSummary) (*EnvdImage, error) {
img := EnvdImage{
ImageSummary: image,
Expand Down Expand Up @@ -135,6 +142,24 @@ func NewDependencyFromImage(img types.ImageSummary) (*Dependency, error) {
return newDependencyFromLabels(img.Labels)
}

func NewPortBindingFromContainerJSON(ctr types.ContainerJSON) []PortBinding {
config := ctr.HostConfig.PortBindings
var ports []PortBinding
for port, bindings := range config {
if len(bindings) <= 0 {
continue
}
binding := bindings[len(bindings)-1]
ports = append(ports, PortBinding{
Port: port.Port(),
Protocol: port.Proto(),
HostIP: binding.HostIP,
HostPort: binding.HostPort,
})
}
return ports
}

func GetImageName(image EnvdImage) string {
if len(image.ImageSummary.RepoTags) != 0 {
return image.ImageSummary.RepoTags[0]
Expand Down