Use NSC keychain for macOS fallback
This commit is contained in:
parent
c72426ef52
commit
f74a17c124
1 changed files with 43 additions and 8 deletions
|
|
@ -14,6 +14,18 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func nscCLIEnv() []string {
|
||||||
|
env := os.Environ()
|
||||||
|
out := env[:0]
|
||||||
|
for _, entry := range env {
|
||||||
|
if strings.HasPrefix(entry, "NSC_TOKEN_FILE=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out = append(out, entry)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func normalizeMacOSNSCMachineType(machineType string) (normalized string, changed bool, err error) {
|
func normalizeMacOSNSCMachineType(machineType string) (normalized string, changed bool, err error) {
|
||||||
vcpu, memoryMB, err := parseMachineTypeCPUxMemGB(machineType)
|
vcpu, memoryMB, err := parseMachineTypeCPUxMemGB(machineType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -56,10 +68,6 @@ func (d *Dispatcher) launchMacOSRunnerViaNSC(ctx context.Context, runnerName str
|
||||||
if machineType == "" {
|
if machineType == "" {
|
||||||
return errors.New("machine_type is required for macos runners")
|
return errors.New("machine_type is required for macos runners")
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(os.Getenv("NSC_TOKEN_FILE")) == "" {
|
|
||||||
// The Burrow forge host feeds NSC_TOKEN_FILE from the intake-backed runtime token.
|
|
||||||
return errors.New("NSC_TOKEN_FILE is required for macos runners")
|
|
||||||
}
|
|
||||||
|
|
||||||
selectors := macosSelectorsArg(d.opts.MacosBaseImageID)
|
selectors := macosSelectorsArg(d.opts.MacosBaseImageID)
|
||||||
if selectors == "" {
|
if selectors == "" {
|
||||||
|
|
@ -141,6 +149,7 @@ func (d *Dispatcher) launchMacOSRunnerViaNSC(ctx context.Context, runnerName str
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
cmd := exec.CommandContext(createCtx, d.opts.BinaryPath, args...)
|
cmd := exec.CommandContext(createCtx, d.opts.BinaryPath, args...)
|
||||||
|
cmd.Env = nscCLIEnv()
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cmd.Stdout = &buf
|
cmd.Stdout = &buf
|
||||||
cmd.Stderr = &buf
|
cmd.Stderr = &buf
|
||||||
|
|
@ -210,10 +219,9 @@ func (d *Dispatcher) launchMacOSRunnerViaNSC(ctx context.Context, runnerName str
|
||||||
defer d.destroyNSCInstance(context.Background(), runnerName, instanceID)
|
defer d.destroyNSCInstance(context.Background(), runnerName, instanceID)
|
||||||
|
|
||||||
script := macosBootstrapWrapperScript(runnerName, req, d.opts.Executor, d.opts.WorkDir)
|
script := macosBootstrapWrapperScript(runnerName, req, d.opts.Executor, d.opts.WorkDir)
|
||||||
// Use the Compute SSH config endpoint (direct TCP) instead of `nsc ssh`, which
|
// The CLI fallback is explicitly keychain-backed and does not rely on the
|
||||||
// relies on a websocket-based SSH proxy that is not supported by the
|
// service bearer token, so use `nsc ssh` end-to-end here.
|
||||||
// revokable tenant token we run the dispatcher with.
|
if err := d.runMacOSNSCSSHScript(ctx, runnerName, instanceID, script); err != nil {
|
||||||
if err := d.runMacOSComputeSSHScript(ctx, runnerName, instanceID, script); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -285,6 +293,7 @@ func (d *Dispatcher) destroyNSCInstance(ctx context.Context, runnerName, instanc
|
||||||
args := []string{"destroy", "--force", instanceID}
|
args := []string{"destroy", "--force", instanceID}
|
||||||
args = prependNSCRegionArgs(args, d.opts.ComputeBaseURL)
|
args = prependNSCRegionArgs(args, d.opts.ComputeBaseURL)
|
||||||
cmd := exec.CommandContext(ctx, d.opts.BinaryPath, args...)
|
cmd := exec.CommandContext(ctx, d.opts.BinaryPath, args...)
|
||||||
|
cmd.Env = nscCLIEnv()
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cmd.Stdout = &buf
|
cmd.Stdout = &buf
|
||||||
cmd.Stderr = &buf
|
cmd.Stderr = &buf
|
||||||
|
|
@ -336,6 +345,32 @@ func shellSingleQuote(value string) string {
|
||||||
return "'" + strings.ReplaceAll(value, "'", `'\"'\"'`) + "'"
|
return "'" + strings.ReplaceAll(value, "'", `'\"'\"'`) + "'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dispatcher) runMacOSNSCSSHScript(ctx context.Context, runnerName, instanceID, script string) error {
|
||||||
|
sshCtx, cancel := context.WithTimeout(ctx, 5*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
args := []string{"ssh", "--disable-pty", instanceID, "/bin/bash"}
|
||||||
|
args = prependNSCRegionArgs(args, d.opts.ComputeBaseURL)
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(sshCtx, d.opts.BinaryPath, args...)
|
||||||
|
cmd.Env = nscCLIEnv()
|
||||||
|
cmd.Stdin = strings.NewReader(script)
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
cmd.Stdout = &buf
|
||||||
|
cmd.Stderr = &buf
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
if errors.Is(sshCtx.Err(), context.DeadlineExceeded) {
|
||||||
|
return fmt.Errorf("nsc ssh timed out after %s\n%s", 5*time.Minute, strings.TrimSpace(buf.String()))
|
||||||
|
}
|
||||||
|
return fmt.Errorf("nsc ssh runner bootstrap failed: %w\n%s", err, strings.TrimSpace(buf.String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
d.log.Info("macos runner bootstrap completed via nsc ssh", "runner", runnerName, "instance", instanceID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func prependNSCRegionArgs(args []string, computeBaseURL string) []string {
|
func prependNSCRegionArgs(args []string, computeBaseURL string) []string {
|
||||||
region := strings.TrimSpace(os.Getenv("NSC_REGION"))
|
region := strings.TrimSpace(os.Getenv("NSC_REGION"))
|
||||||
if region == "" {
|
if region == "" {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue