■ ■ ■ ■ ■ ■
cmd/portforward/portforward.go
| skipped 102 lines |
103 | 103 | | if err != nil { |
104 | 104 | | return err |
105 | 105 | | } |
106 | | - | |
107 | | - | // TODO: Check that target has at least 1 IP! |
| 106 | + | if target.State == nil || !target.State.Running { |
| 107 | + | return errors.New("target container found but it's not running") |
| 108 | + | } |
108 | 109 | | |
109 | 110 | | if err := client.ImagePullEx(ctx, helperImage, types.ImagePullOptions{}); err != nil { |
110 | 111 | | return fmt.Errorf("cannot pull port-forwarder helper image %q: %w", helperImage, err) |
| skipped 42 lines |
153 | 154 | | return fmt.Errorf("cannot inspect forwarder container: %w", err) |
154 | 155 | | } |
155 | 156 | | |
156 | | - | // TODO: Multi-network support. |
157 | | - | targetIP := target.NetworkSettings.Networks["bridge"].IPAddress |
158 | | - | for remotePort, localBindings := range forwarder.NetworkSettings.Ports { |
159 | | - | for _, binding := range localBindings { |
160 | | - | switch opts.output { |
161 | | - | case outFormatText: |
162 | | - | local := net.JoinHostPort(binding.HostIP, binding.HostPort) |
163 | | - | remote := targetIP + ":" + string(remotePort) |
164 | | - | cli.PrintOut("Forwarding %s to %s's %s\n", local, target.Name[1:], remote) |
165 | | - | case outFormatJSON: |
166 | | - | cli.PrintOut(jsonutil.Dump(map[string]string{ |
167 | | - | "localHost": binding.HostIP, |
168 | | - | "localPort": binding.HostPort, |
169 | | - | "remoteHost": targetIP, |
170 | | - | "remotePort": string(remotePort), |
171 | | - | })) |
172 | | - | default: |
173 | | - | panic("unreachable!") |
174 | | - | } |
175 | | - | } |
176 | | - | } |
| 157 | + | output(cli, forwardings, forwarder, opts.output) |
177 | 158 | | |
178 | 159 | | sigCh := make(chan os.Signal, 128) |
179 | 160 | | signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) |
| skipped 21 lines |
201 | 182 | | } |
202 | 183 | | |
203 | 184 | | return nil |
| 185 | + | } |
| 186 | + | |
| 187 | + | func output( |
| 188 | + | cli cliutil.CLI, |
| 189 | + | forwardings forwardingList, |
| 190 | + | forwarder types.ContainerJSON, |
| 191 | + | outFormat string, |
| 192 | + | ) { |
| 193 | + | targetIP := target.NetworkSettings.Networks["bridge"].IPAddress |
| 194 | + | for remotePort, localBindings := range forwarder.NetworkSettings.Ports { |
| 195 | + | for _, binding := range localBindings { |
| 196 | + | switch opts.output { |
| 197 | + | case outFormatText: |
| 198 | + | local := net.JoinHostPort(binding.HostIP, binding.HostPort) |
| 199 | + | remote := targetIP + ":" + string(remotePort) |
| 200 | + | cli.PrintOut("Forwarding %s to %s's %s\n", local, target.Name[1:], remote) |
| 201 | + | case outFormatJSON: |
| 202 | + | cli.PrintOut(jsonutil.Dump(map[string]string{ |
| 203 | + | "localHost": binding.HostIP, |
| 204 | + | "localPort": binding.HostPort, |
| 205 | + | "remoteHost": targetIP, |
| 206 | + | "remotePort": string(remotePort), |
| 207 | + | })) |
| 208 | + | default: |
| 209 | + | panic("unreachable!") |
| 210 | + | } |
| 211 | + | } |
| 212 | + | } |
204 | 213 | | } |
205 | 214 | | |
206 | 215 | | type forwarding struct { |
| skipped 78 lines |