findWorkspaceAndAgentByHostname parses the hostname from the commandline and finds the workspace and agent it corresponds to, taking into account any name prefixes or suffixes configured (e.g. myworkspace.coder, or vscode-coder--myusername--myworkspace).
( ctx context.Context, inv *serpent.Invocation, client *codersdk.Client, hostname string, config codersdk.SSHConfigResponse, disableAutostart bool, )
| 890 | // corresponds to, taking into account any name prefixes or suffixes configured (e.g. myworkspace.coder, or |
| 891 | // vscode-coder--myusername--myworkspace). |
| 892 | func findWorkspaceAndAgentByHostname( |
| 893 | ctx context.Context, inv *serpent.Invocation, client *codersdk.Client, |
| 894 | hostname string, config codersdk.SSHConfigResponse, disableAutostart bool, |
| 895 | ) ( |
| 896 | codersdk.Workspace, codersdk.WorkspaceAgent, error, |
| 897 | ) { |
| 898 | // for suffixes, we don't explicitly get the . and must add it. This is to ensure that the suffix is always |
| 899 | // interpreted as a dotted label in DNS names, not just any string suffix. That is, a suffix of 'coder' will |
| 900 | // match a hostname like 'en.coder', but not 'encoder'. |
| 901 | qualifiedSuffix := "." + config.HostnameSuffix |
| 902 | |
| 903 | switch { |
| 904 | case config.HostnamePrefix != "" && strings.HasPrefix(hostname, config.HostnamePrefix): |
| 905 | hostname = strings.TrimPrefix(hostname, config.HostnamePrefix) |
| 906 | case config.HostnameSuffix != "" && strings.HasSuffix(hostname, qualifiedSuffix): |
| 907 | hostname = strings.TrimSuffix(hostname, qualifiedSuffix) |
| 908 | } |
| 909 | hostname = normalizeWorkspaceInput(hostname) |
| 910 | |
| 911 | ws, agent, otherAgents, err := GetWorkspaceAndAgent(ctx, inv, client, !disableAutostart, hostname) |
| 912 | if err != nil && strings.Contains(err.Error(), "multiple agents found") { |
| 913 | var errorMsg strings.Builder |
| 914 | _, _ = errorMsg.WriteString(fmt.Sprintf("%s\nTry running:\n", err.Error())) |
| 915 | for _, agent := range otherAgents { |
| 916 | switch { |
| 917 | case config.HostnameSuffix != "": |
| 918 | _, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s.%s.%s.%s", agent.Name, ws.Name, ws.OwnerName, config.HostnameSuffix)))) |
| 919 | case config.HostnamePrefix != "": |
| 920 | _, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s%s.%s.%s", config.HostnamePrefix, agent.Name, ws.Name, ws.OwnerName)))) |
| 921 | default: |
| 922 | _, _ = errorMsg.WriteString(fmt.Sprintf(" %s\n", cliui.Code(fmt.Sprintf("$ ssh %s.%s.%s", agent.Name, ws.Name, ws.OwnerName)))) |
| 923 | } |
| 924 | } |
| 925 | return ws, agent, xerrors.New(errorMsg.String()) |
| 926 | } |
| 927 | return ws, agent, err |
| 928 | } |
| 929 | |
| 930 | // watchAndClose ensures closer is called if the context is canceled or |
| 931 | // the workspace reaches the stopped state. |
no test coverage detected