Skip to content

feat: streamline Azure login and fix Windows sync#77

Merged
steipete merged 10 commits into
openclaw:mainfrom
galiniliev:dev/galin/azure-cli
May 11, 2026
Merged

feat: streamline Azure login and fix Windows sync#77
steipete merged 10 commits into
openclaw:mainfrom
galiniliev:dev/galin/azure-cli

Conversation

@galiniliev
Copy link
Copy Markdown
Contributor

@galiniliev galiniliev commented May 11, 2026

Summary

This PR improves Azure direct-mode setup and fixes several Windows SSH/rsync sync issues.

The main Azure change is that users can now authenticate with the Azure CLI instead of configuring service-principal environment variables. After az login, users can run crabbox azure login to persist the active subscription, tenant, and location into Crabbox config, or Crabbox can auto-resolve the active subscription from az account show at runtime.

This also adds Azure private-network selection for VPN/private VNet use, and documents the regional constraints around shared Azure network infrastructure.

Significant Changes

Azure CLI login flow

  • Added crabbox azure login.
  • Uses az account show to detect the active Azure subscription, tenant, and subscription name.
  • Validates Azure access through DefaultAzureCredential.
  • Writes Azure subscription ID, tenant ID, and location to the Crabbox user config.
  • Sets provider: azure when no provider is already configured.
  • Supports --subscription <id|name>, --location <region>, and --json.
  • Direct Azure usage no longer requires users to manually export AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_CLIENT_ID, or AZURE_CLIENT_SECRET for the common az login workflow.
  • If no subscription is configured, direct Azure provisioning now attempts to auto-resolve the active Azure CLI subscription before failing.

Azure private network support

  • Added azure.network config and CRABBOX_AZURE_NETWORK.
  • Supports Azure SSH host selection through public or private VM addresses.
  • When azure.network: private is configured, Crabbox uses the VM NIC private IP when available.
  • Falls back to the public IP if no private IP has been discovered yet.
  • Azure server records now include private_net.ipv4.ip.
  • Azure acquire and resolve paths now select the SSH host through the Azure network preference instead of always using the public IP.

Azure docs

  • Added Azure command docs for crabbox azure login.
  • Updated provider and feature docs to describe the az login setup path.
  • Documented CRABBOX_AZURE_NETWORK and azure.network.
  • Clarified that shared Azure vnet/subnet/NSG resources are regional. Reusing default shared resource names requires azure.location to match the existing resource region, or distinct vnet/subnet/NSG names must be used for a new region.

Windows SSH and rsync fixes

  • Disabled SSH ControlMaster on Windows.
    • Windows OpenSSH does not support the Unix-domain socket behavior used by SSH multiplexing.
    • This avoids errors such as getsockname failed: Not a socket.
  • Fixed Windows local path handling for native rsync.
    • Converts Windows drive paths like C:\OpenClaw\crabbox / C:/OpenClaw/crabbox into rsync-safe /c/OpenClaw/crabbox form.
    • Prevents rsync from interpreting the drive-letter colon as a remote-host separator.
  • Added a Windows WSL rsync execution path.
    • Prefers WSL rsync when wsl.exe is available to avoid MSYS2/Cygwin rsync signal-handling issues with Windows SSH child processes.
    • Converts Windows paths to WSL mount paths such as /mnt/c/....
    • Converts paths embedded inside the rsync -e "ssh ..." argument, including SSH key and known_hosts paths.
    • Copies the SSH private key into WSL /tmp and applies chmod 600 so WSL OpenSSH can use it safely.
  • Added Windows-focused tests for rsync path conversion and WSL path conversion.

Test fixes

  • Removed t.Parallel() from Azure tests that call t.Setenv.
  • This avoids Go test runner panics caused by combining parallel tests with process-wide environment mutation.

Verification

go test ./internal/cli -run "Azure|AzAccount|RsyncLocalPath|WindowsToWSLPath" -count=1
go test ./internal/providers/azure -count=1

Also manually validated Azure config behavior locally with:

crabbox pool list

using Azure provider config and azure.network: private.

galiniliev and others added 10 commits May 11, 2026 06:29
Add a new `crabbox azure login` subcommand that detects the active Azure
subscription from the `az` CLI (`az account show`), validates credentials
through `DefaultAzureCredential`, and persists subscription ID, tenant ID,
and location to the user config file. This eliminates the need to manually
export AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID environment
variables for direct-mode local development.

Changes:

CLI:
- internal/cli/azure_cli.go: new azAccountShow() helper that runs
  `az account show --output json` and parses subscription/tenant/name.
- internal/cli/azure_login.go: new `crabbox azure login` command with
  --subscription, --location, and --json flags. Validates token acquisition
  before writing config.
- internal/cli/azure.go: NewAzureClient now auto-resolves subscription from
  `az account show` when AzureSubscription is empty, before erroring.
  Includes the underlying error in the message for diagnostics.
- internal/cli/cli_kong.go: registered `azure` command group with `login`
  subcommand; added `azure` to isKongCommandGroup.
- internal/cli/app.go: added `crabbox azure login` to CLI help text.

Tests:
- internal/cli/azure_cli_test.go: JSON parsing and missing `az` CLI tests.
- internal/cli/azure_login_test.go: config write round-trip and existing
  config preservation tests.
- internal/cli/azure_test.go: TestNewAzureClientAutoResolvesSubscription
  verifies the fallback error mentions `az login`.

Docs:
- docs/commands/azure.md: new command reference for `crabbox azure login`.
- docs/providers/azure.md: added Quick Start with `az login` section.
- docs/features/azure.md: added quick-start section.

The service-principal environment variable path is unchanged. This is a
purely additive change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When connecting through a VPN to the Azure virtual network, outbound SSH
to public IPs may be blocked by corporate firewalls. This adds an
azure.network config option (public|private) that selects whether Crabbox
uses the VM public IP or NIC private IP for SSH.

- Add PrivateNet.IPv4.IP field to Server struct
- Read NIC private IP in Azure provider (WaitForServerIP, GetServer, List)
- Add AzureServerHost helper to select IP based on config
- Support config (azure.network), env (CRABBOX_AZURE_NETWORK)
- Update Azure backend Acquire/Resolve to use configured network
- Add tests for IP selection and private IP population
- Document in provider and feature docs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Windows OpenSSH does not support Unix domain sockets used by
ControlMaster=auto for connection multiplexing. This causes
'getsockname failed: Not a socket' errors on every SSH probe,
preventing warmup, run, and all SSH-based operations from working.

Disable ControlMaster on Windows (runtime.GOOS == windows) the same
way it is already disabled for AuthSecret targets.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MSYS2/Cygwin rsync interprets the colon in Windows drive paths like
C:/foo as a remote host separator, causing 'source and destination
cannot both be remote' errors. Convert drive paths to POSIX style
(/c/foo) before passing to rsync on Windows.

Also disable SSH ControlMaster on Windows since Windows OpenSSH does
not support Unix domain sockets for connection multiplexing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MSYS2/Cygwin rsync has broken signal handling with Windows SSH child
processes (sigpacket::process: Suppressing signal 30), causing every
remote rsync transfer to fail with code 12. When WSL is available,
delegate rsync to WSL which has native Linux rsync without these
interop issues. SSH keys are copied to WSL /tmp with chmod 600, and
source paths are converted from /c/... to /mnt/c/... format.

Falls back to native rsync with MSYS2_ARG_CONV_EXCL when WSL is
not available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The -e 'ssh -i C:\path\key ...' argument embeds Windows paths that
WSL ssh cannot read. Replace drive-letter paths (C:/...) with WSL
mount paths (/mnt/c/...) anywhere in the string, not just when
the whole arg starts with a drive letter. Copy SSH keys to WSL /tmp
with chmod 600 since /mnt/c filesystem has 0777 permissions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove t.Parallel from Azure tests that call t.Setenv so Go's test runner no longer panics on process-wide environment mutation.

Document that Azure shared vnet, subnet, and NSG resources are regional. Reusing the default shared resource names requires azure.location to match the existing resources, or distinct names must be used for a new region.
@steipete steipete force-pushed the dev/galin/azure-cli branch from d0b6918 to 032a97e Compare May 11, 2026 05:29
@steipete steipete merged commit ebb08b0 into openclaw:main May 11, 2026
4 checks passed
@galiniliev galiniliev deleted the dev/galin/azure-cli branch May 11, 2026 05:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants