Skip to content

Commit 8a54571

Browse files
hi-leiclaude
andcommitted
feat: add install script, update README, preload editor template
- Add scripts/install.sh for one-liner install (macOS/Linux/Windows) - Add scripts/test-install.Dockerfile for testing the installer - Rewrite README as user-facing onboarding guide - Preload startup script editor with bash template - Move dev docs reference to CLAUDE.md/AGENTS.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1d2f7d0 commit 8a54571

5 files changed

Lines changed: 269 additions & 28 deletions

File tree

README.md

Lines changed: 153 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,179 @@
1-
# verda
1+
# Verda CLI
22

3-
verda command-line application
3+
Command-line interface for [Verda Cloud](https://verda.com) — manage VMs, volumes, SSH keys, startup scripts, and more from your terminal.
44

5-
## Prerequisites
5+
## Install
66

7-
- **Go 1.25+**
8-
- **golangci-lint** (optional, for linting)
7+
### Quick install (macOS / Linux)
98

10-
## Quick Start
9+
```bash
10+
curl -sSL https://raw.githubusercontent.com/verda-cloud/verda-cli/main/scripts/install.sh | sh
11+
```
12+
13+
Install to a custom directory:
14+
15+
```bash
16+
VERDA_INSTALL_DIR=~/.local/bin curl -sSL https://raw.githubusercontent.com/verda-cloud/verda-cli/main/scripts/install.sh | sh
17+
```
18+
19+
Install a specific version:
20+
21+
```bash
22+
VERDA_VERSION=v1.0.0 curl -sSL https://raw.githubusercontent.com/verda-cloud/verda-cli/main/scripts/install.sh | sh
23+
```
24+
25+
### Manual download
26+
27+
Download the binary for your platform from [GitHub Releases](https://github.com/verda-cloud/verda-cli/releases):
1128

12-
### Build
29+
| Platform | File |
30+
|----------|------|
31+
| macOS (Apple Silicon) | `verda_VERSION_darwin_arm64.tar.gz` |
32+
| macOS (Intel) | `verda_VERSION_darwin_amd64.tar.gz` |
33+
| Linux (x86_64) | `verda_VERSION_linux_amd64.tar.gz` |
34+
| Linux (ARM64) | `verda_VERSION_linux_arm64.tar.gz` |
35+
| Windows (x86_64) | `verda_VERSION_windows_amd64.zip` |
36+
| Windows (ARM64) | `verda_VERSION_windows_arm64.zip` |
37+
38+
Extract and move to your PATH:
39+
40+
```bash
41+
tar xzf verda_*.tar.gz
42+
sudo mv verda /usr/local/bin/
43+
```
44+
45+
### Go install (for Go developers)
1346

1447
```bash
15-
make build
48+
go install github.com/verda-cloud/verda-cli/cmd/verda@latest
1649
```
1750

18-
### Run
51+
### Verify installation
1952

2053
```bash
21-
./bin/verda --help
54+
verda version
2255
```
2356

24-
## Development
57+
## Getting Started
58+
59+
### 1. Configure credentials
2560

2661
```bash
27-
make test # Run all tests
28-
make lint # Run linter
29-
make lint.fix # Auto-fix lint issues
30-
make clean # Remove build artifacts
62+
verda auth login
3163
```
3264

33-
### Git hooks (optional)
65+
This starts an interactive wizard to save your API credentials to `~/.verda/credentials`.
3466

35-
Sample pre-commit script lives in **`githooks/pre-commit`** (runs `go build`, `go vet`, optional `golangci-lint`, and short tests for affected packages). Wire it once per clone:
67+
### 2. List your VMs
3668

3769
```bash
38-
make hooks.install # sets git config core.hooksPath to githooks/
70+
verda vm list
3971
```
4072

41-
> **Note:** The template repo’s **`hooks/`** directory is only for `verdactl` post-generation scripts and is not part of the scaffolded project. Use **`githooks/`** for git hooks in generated apps.
73+
### 3. Create a VM
4274

43-
## Project Structure
75+
```bash
76+
# Interactive wizard
77+
verda vm create
78+
79+
# Non-interactive
80+
verda vm create \
81+
--kind gpu \
82+
--instance-type 1V100.6V \
83+
--location FIN-01 \
84+
--os ubuntu-24.04-cuda-12.8-open-docker \
85+
--os-volume-size 100 \
86+
--hostname gpu-runner
87+
```
88+
89+
## Commands
4490

4591
```
46-
githooks/ Sample pre-commit (optional: make hooks.install)
47-
cmd/verda/ Entry point
48-
internal/verda-cli/
49-
cmd/ Cobra commands
50-
cmd/util/ CLI utilities (factory, iostreams)
51-
options/ Shared CLI options
92+
Auth Commands:
93+
auth Manage shared credentials and profiles
94+
95+
VM Commands:
96+
vm Manage VM instances
97+
98+
Resource Commands:
99+
ssh-key Manage SSH keys
100+
startup-script Manage startup scripts
101+
volume Manage volumes
102+
103+
Other Commands:
104+
settings Manage CLI settings
105+
version Print version information
52106
```
107+
108+
### VM
109+
110+
| Command | Description |
111+
|---------|-------------|
112+
| `verda vm create` | Create a VM (interactive wizard or flags) |
113+
| `verda vm list` | List and inspect VM instances |
114+
| `verda vm action` | Start, shutdown, hibernate, or delete a VM |
115+
116+
### Volume
117+
118+
| Command | Description |
119+
|---------|-------------|
120+
| `verda volume create` | Create a block storage volume |
121+
| `verda volume list` | List volumes |
122+
| `verda volume action` | Detach, rename, resize, clone, or delete |
123+
| `verda volume trash` | List deleted volumes (restorable within 96h) |
124+
125+
### SSH Keys & Startup Scripts
126+
127+
| Command | Description |
128+
|---------|-------------|
129+
| `verda ssh-key list / add / delete` | Manage SSH keys |
130+
| `verda startup-script list / add / delete` | Manage startup scripts |
131+
132+
### Settings
133+
134+
| Command | Description |
135+
|---------|-------------|
136+
| `verda settings theme` | View or change the color theme |
137+
| `verda settings theme --select` | Interactive theme picker |
138+
139+
Available themes: `default`, `dracula`, `catppuccin`, `catppuccin-latte`, `nord`, `tokyonight`, `github-light`, `solarized-light`
140+
141+
### Auth
142+
143+
| Command | Description |
144+
|---------|-------------|
145+
| `verda auth login` | Save API credentials (interactive wizard) |
146+
| `verda auth show` | Show active profile and credentials path |
147+
| `verda auth use PROFILE` | Switch active auth profile |
148+
149+
## Global Flags
150+
151+
| Flag | Description |
152+
|------|-------------|
153+
| `--debug` | Enable debug output (API request/response details) |
154+
| `--timeout` | HTTP request timeout (default: 30s) |
155+
| `--base-url` | Override API base URL |
156+
| `--config` | Path to config file (default: `~/.verda/config.yaml`) |
157+
158+
## Configuration
159+
160+
Credentials are stored in `~/.verda/credentials` (AWS-style INI format):
161+
162+
```ini
163+
[default]
164+
verda_base_url = https://api.verda.com/v1
165+
verda_client_id = your-client-id
166+
verda_client_secret = your-client-secret
167+
```
168+
169+
Settings (theme, etc.) are stored in `~/.verda/config.yaml`.
170+
171+
Override the config directory with `VERDA_HOME` environment variable.
172+
173+
## Contributing
174+
175+
See [CLAUDE.md](CLAUDE.md) and [AGENTS.md](AGENTS.md) for development setup and coding conventions.
176+
177+
## License
178+
179+
See [LICENSE](LICENSE) for details.

internal/verda-cli/cmd/startupscript/add.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/spf13/cobra"
1010
"github.com/verda-cloud/verdacloud-sdk-go/pkg/verda"
11+
"github.com/verda-cloud/verdagostack/pkg/tui"
1112

1213
cmdutil "github/verda-cloud/verda-cli/internal/verda-cli/cmd/util"
1314
)
@@ -106,7 +107,9 @@ func runAdd(cmd *cobra.Command, f cmdutil.Factory, ioStreams cmdutil.IOStreams,
106107
}
107108
content = string(data)
108109
case 1: // Paste content
109-
content, err = prompter.Editor(ctx, "Script content (Ctrl+D to finish)")
110+
content, err = prompter.Editor(ctx, "Script content (Ctrl+D to finish)",
111+
tui.WithEditorDefault("#!/bin/bash\n\n# Your startup script here\n"),
112+
tui.WithFileExt(".sh"))
110113
if err != nil {
111114
return nil //nolint:nilerr
112115
}

internal/verda-cli/cmd/vm/wizard.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,9 @@ func promptAddStartupScript(ctx context.Context, prompter tui.Prompter, client *
887887
}
888888
content = string(data)
889889
case 1: // Paste content
890-
content, err = prompter.Editor(ctx, "Script content (Ctrl+D to finish)")
890+
content, err = prompter.Editor(ctx, "Script content (Ctrl+D to finish)",
891+
tui.WithEditorDefault("#!/bin/bash\n\n# Your startup script here\n"),
892+
tui.WithFileExt(".sh"))
891893
if err != nil {
892894
return nil, nil //nolint:nilerr
893895
}

scripts/install.sh

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/bin/sh
2+
# Verda CLI installer
3+
# Usage: curl -sSL https://raw.githubusercontent.com/verda-cloud/verda-cli/main/scripts/install.sh | sh
4+
#
5+
# Environment variables:
6+
# VERDA_INSTALL_DIR - Installation directory (default: /usr/local/bin)
7+
# VERDA_VERSION - Specific version to install (default: latest)
8+
9+
set -e
10+
11+
REPO="verda-cloud/verda-cli"
12+
BINARY="verda"
13+
INSTALL_DIR="${VERDA_INSTALL_DIR:-/usr/local/bin}"
14+
15+
# Detect OS
16+
OS="$(uname -s)"
17+
case "$OS" in
18+
Linux*) OS="linux" ;;
19+
Darwin*) OS="darwin" ;;
20+
MINGW*|MSYS*|CYGWIN*) OS="windows" ;;
21+
*)
22+
echo "Error: Unsupported operating system: $OS"
23+
exit 1
24+
;;
25+
esac
26+
27+
# Detect architecture
28+
ARCH="$(uname -m)"
29+
case "$ARCH" in
30+
x86_64|amd64) ARCH="amd64" ;;
31+
arm64|aarch64) ARCH="arm64" ;;
32+
*)
33+
echo "Error: Unsupported architecture: $ARCH"
34+
exit 1
35+
;;
36+
esac
37+
38+
# Resolve version
39+
if [ -z "$VERDA_VERSION" ]; then
40+
VERDA_VERSION=$(curl -sSf "https://api.github.com/repos/${REPO}/releases/latest" | grep '"tag_name"' | cut -d '"' -f4)
41+
if [ -z "$VERDA_VERSION" ]; then
42+
echo "Error: Could not determine latest version. Set VERDA_VERSION manually."
43+
exit 1
44+
fi
45+
fi
46+
47+
VERSION_NUM="${VERDA_VERSION#v}"
48+
49+
# Determine archive format
50+
EXT="tar.gz"
51+
if [ "$OS" = "windows" ]; then
52+
EXT="zip"
53+
fi
54+
55+
FILENAME="${BINARY}_${VERSION_NUM}_${OS}_${ARCH}.${EXT}"
56+
URL="https://github.com/${REPO}/releases/download/${VERDA_VERSION}/${FILENAME}"
57+
58+
echo "Installing Verda CLI ${VERDA_VERSION} (${OS}/${ARCH})..."
59+
echo " From: ${URL}"
60+
echo " To: ${INSTALL_DIR}/${BINARY}"
61+
62+
# Create temp directory
63+
TMP_DIR=$(mktemp -d)
64+
trap 'rm -rf "$TMP_DIR"' EXIT
65+
66+
# Download
67+
echo "Downloading..."
68+
if command -v curl >/dev/null 2>&1; then
69+
curl -sSfL "$URL" -o "${TMP_DIR}/${FILENAME}"
70+
elif command -v wget >/dev/null 2>&1; then
71+
wget -q "$URL" -O "${TMP_DIR}/${FILENAME}"
72+
else
73+
echo "Error: curl or wget is required"
74+
exit 1
75+
fi
76+
77+
# Extract
78+
echo "Extracting..."
79+
cd "$TMP_DIR"
80+
if [ "$EXT" = "tar.gz" ]; then
81+
tar xzf "$FILENAME"
82+
elif [ "$EXT" = "zip" ]; then
83+
unzip -q "$FILENAME"
84+
fi
85+
86+
# Install
87+
if [ -w "$INSTALL_DIR" ]; then
88+
mv "$BINARY" "$INSTALL_DIR/$BINARY"
89+
else
90+
echo "Elevating permissions to install to ${INSTALL_DIR}..."
91+
sudo mv "$BINARY" "$INSTALL_DIR/$BINARY"
92+
fi
93+
94+
chmod +x "$INSTALL_DIR/$BINARY"
95+
96+
echo ""
97+
echo "Verda CLI ${VERDA_VERSION} installed successfully!"
98+
echo ""
99+
echo "Get started:"
100+
echo " verda auth login # Configure credentials"
101+
echo " verda vm list # List VM instances"
102+
echo " verda --help # See all commands"

scripts/test-install.Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM ubuntu:24.04
2+
RUN apt-get update && apt-get install -y curl ca-certificates && rm -rf /var/lib/apt/lists/*
3+
COPY scripts/install.sh /tmp/install.sh
4+
RUN chmod +x /tmp/install.sh
5+
# Test the install script (will fail until first release exists)
6+
# RUN VERDA_VERSION=v1.0.0 sh /tmp/install.sh
7+
CMD ["sh", "/tmp/install.sh"]

0 commit comments

Comments
 (0)