(ctx context.Context, command, shell string, ports []int, useEntrypoint bool)
| 279 | } |
| 280 | |
| 281 | func (env *Environment) RunBackground(ctx context.Context, command, shell string, ports []int, useEntrypoint bool) (EndpointMappings, error) { |
| 282 | args := []string{} |
| 283 | if command != "" { |
| 284 | args = []string{shell, "-c", command} |
| 285 | } |
| 286 | displayCommand := command + " &" |
| 287 | serviceState := env.container() |
| 288 | |
| 289 | // Expose ports |
| 290 | for _, port := range ports { |
| 291 | serviceState = serviceState.WithExposedPort(port, dagger.ContainerWithExposedPortOpts{ |
| 292 | Protocol: dagger.NetworkProtocolTcp, |
| 293 | Description: fmt.Sprintf("Port %d", port), |
| 294 | }) |
| 295 | } |
| 296 | |
| 297 | // Start the service |
| 298 | startCtx, cancel := context.WithTimeout(ctx, serviceStartTimeout) |
| 299 | defer cancel() |
| 300 | svc, err := serviceState.AsService(dagger.ContainerAsServiceOpts{ |
| 301 | Args: args, |
| 302 | UseEntrypoint: useEntrypoint, |
| 303 | }).Start(startCtx) |
| 304 | if err != nil { |
| 305 | var exitErr *dagger.ExecError |
| 306 | if errors.As(err, &exitErr) { |
| 307 | env.Notes.AddCommand(displayCommand, exitErr.ExitCode, exitErr.Stdout, exitErr.Stderr) |
| 308 | return nil, fmt.Errorf("command failed with exit code %d.\nstdout: %s\nstderr: %s", exitErr.ExitCode, exitErr.Stdout, exitErr.Stderr) |
| 309 | } |
| 310 | if errors.Is(err, context.DeadlineExceeded) { |
| 311 | err = fmt.Errorf("service failed to start within %s timeout", serviceStartTimeout) |
| 312 | env.Notes.AddCommand(displayCommand, 137, "", err.Error()) |
| 313 | return nil, err |
| 314 | } |
| 315 | return nil, err |
| 316 | } |
| 317 | |
| 318 | env.Notes.AddCommand(displayCommand, 0, "", "") |
| 319 | |
| 320 | endpoints := EndpointMappings{} |
| 321 | for _, port := range ports { |
| 322 | endpoint := &EndpointMapping{} |
| 323 | endpoints[port] = endpoint |
| 324 | |
| 325 | // Expose port on the host |
| 326 | tunnel, err := env.dag.Host().Tunnel(svc, dagger.HostTunnelOpts{ |
| 327 | Ports: []dagger.PortForward{ |
| 328 | { |
| 329 | Backend: port, |
| 330 | Protocol: dagger.NetworkProtocolTcp, |
| 331 | }, |
| 332 | }, |
| 333 | }).Start(ctx) |
| 334 | if err != nil { |
| 335 | return nil, err |
| 336 | } |
| 337 | |
| 338 | externalEndpoint, err := tunnel.Endpoint(ctx, dagger.ServiceEndpointOpts{ |
no test coverage detected