MCPcopy
hub / github.com/amir20/dozzle / deployService

Method deployService

internal/deploy/deployer.go:417–480  ·  view source on GitHub ↗
(ctx context.Context, projectName, name string, svc composetypes.ServiceConfig, networkIDs map[string]string, status chan<- StatusUpdate)

Source from the content-addressed store, hash-verified

415}
416
417func (d *Deployer) deployService(ctx context.Context, projectName, name string, svc composetypes.ServiceConfig, networkIDs map[string]string, status chan<- StatusUpdate) error {
418 if svc.Image == "" {
419 return fmt.Errorf("service %q has no image (build is not supported)", name)
420 }
421
422 // Pick the primary network (attached at container-create time) deterministically.
423 // sortedNetworks is alphabetical so create-time and later NetworkConnect agree.
424 sortedNetworks := sortedNetworkNames(svc.Networks)
425 primaryNetName := ""
426 for _, n := range sortedNetworks {
427 if _, ok := networkIDs[n]; ok {
428 primaryNetName = n
429 break
430 }
431 }
432
433 config, hostConfig, networkingConfig := buildContainerConfig(projectName, name, svc, networkIDs, primaryNetName)
434
435 containerName := svc.ContainerName
436 if containerName == "" {
437 containerName = projectName + "-" + name + "-1"
438 }
439
440 sendStatus(ctx, status, name, "creating")
441 resp, err := d.cli.ContainerCreate(ctx, client.ContainerCreateOptions{
442 Config: config,
443 HostConfig: hostConfig,
444 NetworkingConfig: networkingConfig,
445 Name: containerName,
446 })
447 if err != nil {
448 return fmt.Errorf("creating container %q: %w", containerName, err)
449 }
450 log.Info().Str("service", name).Str("container", containerName).Str("id", shortID(resp.ID)).Msg("Created container")
451
452 for _, netName := range sortedNetworks {
453 if netName == primaryNetName {
454 continue
455 }
456 netID, ok := networkIDs[netName]
457 if !ok {
458 continue
459 }
460 netCfg := svc.Networks[netName]
461 aliases := copyAliases(netCfg, name)
462 if _, err := d.cli.NetworkConnect(ctx, netID, client.NetworkConnectOptions{Container: resp.ID, EndpointConfig: &network.EndpointSettings{
463 Aliases: aliases,
464 }}); err != nil {
465 // Partial attachment would leave an orphan. Remove and bail.
466 if _, rmErr := d.cli.ContainerRemove(ctx, resp.ID, client.ContainerRemoveOptions{Force: true}); rmErr != nil {
467 log.Warn().Err(rmErr).Str("container", shortID(resp.ID)).Msg("Failed to clean up after NetworkConnect error")
468 }
469 return fmt.Errorf("connecting container to network %q: %w", netName, err)
470 }
471 }
472
473 sendStatus(ctx, status, name, "starting")
474 if _, err := d.cli.ContainerStart(ctx, resp.ID, client.ContainerStartOptions{}); err != nil {

Callers 1

DeployMethod · 0.95

Calls 10

sortedNetworkNamesFunction · 0.85
buildContainerConfigFunction · 0.85
sendStatusFunction · 0.85
copyAliasesFunction · 0.85
InfoMethod · 0.80
shortIDFunction · 0.70
ContainerCreateMethod · 0.65
NetworkConnectMethod · 0.65
ContainerRemoveMethod · 0.65
ContainerStartMethod · 0.65

Tested by

no test coverage detected