Projects STRLCPY cdebug Commits 8ce7f9d8
🤬
  • ■ ■ ■ ■ ■ ■
    cmd/exec/exec.go
    skipped 11 lines
    12 12   "github.com/docker/docker/api/types/container"
    13 13   dockerclient "github.com/docker/docker/client"
    14 14   "github.com/docker/docker/pkg/stdcopy"
    15  - "github.com/google/uuid"
    16 15   "github.com/sirupsen/logrus"
    17 16   "github.com/spf13/cobra"
    18 17   
    19 18   "github.com/iximiuz/cdebug/pkg/cmd"
    20 19   "github.com/iximiuz/cdebug/pkg/tty"
     20 + "github.com/iximiuz/cdebug/pkg/util"
    21 21  )
    22 22   
    23 23  const (
    skipped 120 lines
    144 144   return err
    145 145   }
    146 146   
    147  - runID := shortID()
     147 + runID := util.ShortID()
    148 148   nsMode := "container:" + target.ID
    149 149   resp, err := client.ContainerCreate(
    150 150   ctx,
    skipped 195 lines
    346 346   return name
    347 347   }
    348 348   return "cdebug-" + runID
    349  -}
    350  - 
    351  -func shortID() string {
    352  - return strings.Split(uuid.NewString(), "-")[0]
    353 349  }
    354 350   
    355 351  func mustRenderTemplate(t *template.Template, data any) string {
    skipped 18 lines
  • ■ ■ ■ ■ ■ ■
    cmd/portforward/portforward.go
     1 +package portforward
     2 + 
     3 +import (
     4 + "context"
     5 + "fmt"
     6 + "io"
     7 + 
     8 + "github.com/docker/docker/api/types"
     9 + "github.com/docker/docker/api/types/container"
     10 + dockerclient "github.com/docker/docker/client"
     11 + "github.com/docker/go-connections/nat"
     12 + "github.com/spf13/cobra"
     13 + 
     14 + "github.com/iximiuz/cdebug/pkg/cmd"
     15 + "github.com/iximiuz/cdebug/pkg/util"
     16 +)
     17 + 
     18 +// TODO:
     19 +// - parse ports args
     20 +// - handle non-default network case
     21 +// - handle exposing localhost ports
     22 +// cdebug exec --name helper --image socat <target> <target-port> <random-port>
     23 +// cdebug port-forward helper <host-port>:<random-port>
     24 + 
     25 +const (
     26 + helperImage = "nixery.dev/socat:latest"
     27 +)
     28 + 
     29 +type options struct {
     30 + target string
     31 + address string
     32 + ports []string
     33 +}
     34 + 
     35 +func NewCommand(cli cmd.CLI) *cobra.Command {
     36 + var opts options
     37 + 
     38 + cmd := &cobra.Command{
     39 + Use: "port-forward [OPTIONS] CONTAINER [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
     40 + Short: "Publish a port of an already running container (kind of)",
     41 + Args: cobra.MinimumNArgs(2),
     42 + RunE: func(cmd *cobra.Command, args []string) error {
     43 + opts.target = args[0]
     44 + if len(args) > 1 {
     45 + opts.ports = args[1:]
     46 + }
     47 + return runPortForward(context.Background(), cli, &opts)
     48 + },
     49 + }
     50 + 
     51 + flags := cmd.Flags()
     52 + flags.SetInterspersed(false) // Instead of relying on --
     53 + 
     54 + flags.StringVar(
     55 + &opts.address,
     56 + "address",
     57 + "127.0.0.1",
     58 + "Host's interface address to bind the port to",
     59 + )
     60 + 
     61 + return cmd
     62 +}
     63 + 
     64 +func runPortForward(ctx context.Context, cli cmd.CLI, opts *options) error {
     65 + client, err := dockerclient.NewClientWithOpts(
     66 + dockerclient.FromEnv,
     67 + dockerclient.WithAPIVersionNegotiation(),
     68 + )
     69 + if err != nil {
     70 + return fmt.Errorf("cannot initialize Docker client: %w", err)
     71 + }
     72 + 
     73 + target, err := client.ContainerInspect(ctx, opts.target)
     74 + if err != nil {
     75 + return fmt.Errorf("cannot inspect target container: %w", err)
     76 + }
     77 + 
     78 + if err := pullImage(ctx, cli, client, helperImage); err != nil {
     79 + return err
     80 + }
     81 + 
     82 + ports, portBindings, err := nat.ParsePortSpecs([]string{"8080:80"})
     83 + if err != nil {
     84 + return err
     85 + }
     86 + 
     87 + contIP := target.NetworkSettings.Networks["bridge"].IPAddress
     88 + resp, err := client.ContainerCreate(
     89 + ctx,
     90 + &container.Config{
     91 + Image: helperImage,
     92 + Entrypoint: []string{"socat"},
     93 + Cmd: []string{
     94 + "TCP-LISTEN:80,fork",
     95 + fmt.Sprintf("TCP-CONNECT:%s:%d", contIP, 80),
     96 + },
     97 + ExposedPorts: ports,
     98 + },
     99 + &container.HostConfig{
     100 + AutoRemove: true,
     101 + PortBindings: portBindings,
     102 + },
     103 + nil,
     104 + nil,
     105 + "port-forwarder-"+util.ShortID(),
     106 + )
     107 + if err != nil {
     108 + return fmt.Errorf("cannot create port-forwarder container: %w", err)
     109 + }
     110 + 
     111 + if err := client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
     112 + return fmt.Errorf("cannot start port-forwarder container: %w", err)
     113 + }
     114 + 
     115 + forwarderStatusCh, forwarderErrCh := client.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
     116 + // targetStatusCh, targetErrCh := client.ContainerWait(ctx, target.ID, container.WaitConditionNotRunning)
     117 + select {
     118 + case err := <-forwarderErrCh:
     119 + if err != nil {
     120 + return fmt.Errorf("waiting port-forwarder container failed: %w", err)
     121 + }
     122 + case <-forwarderStatusCh:
     123 + }
     124 + 
     125 + return nil
     126 +}
     127 + 
     128 +func pullImage(
     129 + ctx context.Context,
     130 + cli cmd.CLI,
     131 + client *dockerclient.Client,
     132 + image string,
     133 +) error {
     134 + resp, err := client.ImagePull(ctx, image, types.ImagePullOptions{})
     135 + if err != nil {
     136 + return fmt.Errorf("cannot pull port-forwarder helper image %q: %w", image, err)
     137 + }
     138 + defer resp.Close()
     139 + 
     140 + _, err = io.Copy(cli.OutputStream(), resp)
     141 + return err
     142 +}
     143 + 
  • ■ ■ ■ ■ ■
    main.go
    skipped 7 lines
    8 8   "github.com/spf13/cobra"
    9 9   
    10 10   "github.com/iximiuz/cdebug/cmd/exec"
     11 + "github.com/iximiuz/cdebug/cmd/portforward"
    11 12   "github.com/iximiuz/cdebug/pkg/cmd"
    12 13  )
    13 14   
    skipped 8 lines
    22 23   
    23 24   cmd.AddCommand(
    24 25   exec.NewCommand(cli),
    25  - // TODO: other commands
     26 + portforward.NewCommand(cli),
     27 + // TODO: other commands
    26 28   )
    27 29   
    28 30   if err := cmd.Execute(); err != nil {
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    pkg/util/util.go
     1 +package util
     2 + 
     3 +import (
     4 + "strings"
     5 + 
     6 + "github.com/google/uuid"
     7 +)
     8 + 
     9 +func ShortID() string {
     10 + return strings.Split(uuid.NewString(), "-")[0]
     11 +}
     12 + 
Please wait...
Page is in error, reload to recover