MCPcopy Index your code
hub / github.com/coder/coder / maybeInjectSubAgentIntoContainerLocked

Method maybeInjectSubAgentIntoContainerLocked

agent/agentcontainers/api.go:1670–2137  ·  view source on GitHub ↗

maybeInjectSubAgentIntoContainerLocked injects a subagent into a dev container and starts the subagent process. This method assumes that api.mu is held. This method is idempotent and will not re-inject the subagent if it is already/still running in the container. This method uses an internal timeou

(ctx context.Context, dc codersdk.WorkspaceAgentDevcontainer)

Source from the content-addressed store, hash-verified

1668// This method uses an internal timeout to prevent blocking indefinitely
1669// if something goes wrong with the injection.
1670func (api *API) maybeInjectSubAgentIntoContainerLocked(ctx context.Context, dc codersdk.WorkspaceAgentDevcontainer) (err error) {
1671 if api.ignoredDevcontainers[dc.WorkspaceFolder] {
1672 return nil
1673 }
1674
1675 ctx, cancel := context.WithTimeout(ctx, defaultOperationTimeout)
1676 defer cancel()
1677
1678 container := dc.Container
1679 if container == nil {
1680 return xerrors.New("container is nil, cannot inject subagent")
1681 }
1682
1683 logger := api.logger.With(
1684 slog.F("devcontainer_id", dc.ID),
1685 slog.F("devcontainer_name", dc.Name),
1686 slog.F("workspace_folder", dc.WorkspaceFolder),
1687 slog.F("config_path", dc.ConfigPath),
1688 slog.F("container_id", container.ID),
1689 slog.F("container_name", container.FriendlyName),
1690 )
1691
1692 // Check if subagent already exists for this devcontainer.
1693 maybeRecreateSubAgent := false
1694 proc, injected := api.injectedSubAgentProcs[dc.WorkspaceFolder]
1695 if injected {
1696 if _, ignoreChecked := api.ignoredDevcontainers[dc.WorkspaceFolder]; !ignoreChecked {
1697 // If ignore status has not yet been checked, or cleared by
1698 // modifications to the devcontainer.json, we must read it
1699 // to determine the current status. This can happen while
1700 // the devcontainer subagent is already running or before
1701 // we've had a chance to inject it.
1702 //
1703 // Note, for simplicity, we do not try to optimize to reduce
1704 // ReadConfig calls here.
1705 config, err := api.dccli.ReadConfig(ctx, dc.WorkspaceFolder, dc.ConfigPath, nil)
1706 if err != nil {
1707 return xerrors.Errorf("read devcontainer config: %w", err)
1708 }
1709
1710 dcIgnored := config.Configuration.Customizations.Coder.Ignore
1711 if dcIgnored {
1712 proc.stop()
1713 if proc.agent.ID != uuid.Nil {
1714 // Unlock while doing the delete operation.
1715 api.mu.Unlock()
1716 client := *api.subAgentClient.Load()
1717 if err := client.Delete(ctx, proc.agent.ID); err != nil {
1718 api.mu.Lock()
1719 return xerrors.Errorf("delete subagent: %w", err)
1720 }
1721 api.mu.Lock()
1722 }
1723 // Reset agent and containerID to force config re-reading if ignore is toggled.
1724 proc.agent = SubAgent{}
1725 proc.containerID = ""
1726 api.injectedSubAgentProcs[dc.WorkspaceFolder] = proc
1727 api.ignoredDevcontainers[dc.WorkspaceFolder] = dcIgnored

Callers 1

Calls 15

expandedAgentNameFunction · 0.85
ErrMethod · 0.80
CloneConfigMethod · 0.80
OptionsAsEnvsMethod · 0.80
MatchMethod · 0.80
EqualConfigMethod · 0.80
NewMethod · 0.65
ReadConfigMethod · 0.65
stopMethod · 0.65
DeleteMethod · 0.65
AddMethod · 0.65

Tested by

no test coverage detected