From ee15bc8a5f164b662165d773c1c8ca90e64fdb89 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Sat, 27 Dec 2025 16:40:49 -0500 Subject: [PATCH] Add --dump-bootstrap command to all un-inception implementations --- un.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- un.js | 46 ++++++++++++++++++++++++++++++++++++++++++---- un.lua | 47 +++++++++++++++++++++++++++++++++++++++++++---- un.php | 45 +++++++++++++++++++++++++++++++++++++++++---- un.pl | 44 ++++++++++++++++++++++++++++++++++++++++---- un.py | 31 +++++++++++++++++++++++++++++-- un.rb | 46 ++++++++++++++++++++++++++++++++++++++++++---- un.sh | 41 +++++++++++++++++++++++++++++++++++++---- un.ts | 46 ++++++++++++++++++++++++++++++++++++++++++---- 9 files changed, 359 insertions(+), 32 deletions(-) diff --git a/un.go b/un.go index bed2b0b..c112810 100644 --- a/un.go +++ b/un.go @@ -342,7 +342,7 @@ func cmdSession(sessionList, sessionKill, sessionShell, network string, vcpu int fmt.Printf("%sSession created: %s%s\n", Green, result["id"], Reset) } -func cmdService(serviceName, servicePorts, serviceDomains, serviceType, serviceBootstrap, serviceList, serviceInfo, serviceLogs, serviceTail, serviceSleep, serviceWake, serviceDestroy, network string, vcpu int, apiKey string) { +func cmdService(serviceName, servicePorts, serviceDomains, serviceType, serviceBootstrap, serviceList, serviceInfo, serviceLogs, serviceTail, serviceSleep, serviceWake, serviceDestroy, serviceExecute, serviceCommand, serviceDumpBootstrap, serviceDumpFile, network string, vcpu int, apiKey string) { if serviceList != "" { result := apiRequest("/services", "GET", nil, apiKey) services := result["services"].([]interface{}) @@ -412,6 +412,43 @@ func cmdService(serviceName, servicePorts, serviceDomains, serviceType, serviceB return } + if serviceExecute != "" { + payload := map[string]interface{}{"command": serviceCommand} + result := apiRequest("/services/"+serviceExecute+"/execute", "POST", payload, apiKey) + if stdout, ok := result["stdout"].(string); ok { + fmt.Printf("%s%s%s", Blue, stdout, Reset) + } + if stderr, ok := result["stderr"].(string); ok { + fmt.Fprintf(os.Stderr, "%s%s%s", Red, stderr, Reset) + } + return + } + + if serviceDumpBootstrap != "" { + fmt.Fprintf(os.Stderr, "Fetching bootstrap script from %s...\n", serviceDumpBootstrap) + payload := map[string]interface{}{"command": "cat /tmp/bootstrap.sh"} + result := apiRequest("/services/"+serviceDumpBootstrap+"/execute", "POST", payload, apiKey) + + if bootstrap, ok := result["stdout"].(string); ok && bootstrap != "" { + if serviceDumpFile != "" { + // Write to file + err := os.WriteFile(serviceDumpFile, []byte(bootstrap), 0755) + if err != nil { + fmt.Fprintf(os.Stderr, "%sError: Could not write to %s: %v%s\n", Red, serviceDumpFile, err, Reset) + os.Exit(1) + } + fmt.Printf("Bootstrap saved to %s\n", serviceDumpFile) + } else { + // Print to stdout + fmt.Print(bootstrap) + } + } else { + fmt.Fprintf(os.Stderr, "%sError: Failed to fetch bootstrap (service not running or no bootstrap file)%s\n", Red, Reset) + os.Exit(1) + } + return + } + // Create service if serviceName != "" { payload := map[string]interface{}{"name": serviceName} @@ -645,6 +682,10 @@ func main() { serviceSleep := serviceCmd.String("sleep", "", "Freeze service") serviceWake := serviceCmd.String("wake", "", "Unfreeze service") serviceDestroy := serviceCmd.String("destroy", "", "Destroy service") + serviceExecute := serviceCmd.String("execute", "", "Execute command in service") + serviceCommand := serviceCmd.String("command", "", "Command to execute (with -execute)") + serviceDumpBootstrap := serviceCmd.String("dump-bootstrap", "", "Dump bootstrap script") + serviceDumpFile := serviceCmd.String("dump-file", "", "File to save bootstrap (with -dump-bootstrap)") serviceNetwork := serviceCmd.String("n", "", "Network mode") serviceVcpu := serviceCmd.Int("v", 0, "vCPU count") serviceKey := serviceCmd.String("k", "", "API key") @@ -684,7 +725,7 @@ func main() { if vc == 0 { vc = *vcpu } - cmdService(*serviceName, *servicePorts, *serviceDomains, *serviceType, *serviceBootstrap, *serviceList, *serviceInfo, *serviceLogs, *serviceTail, *serviceSleep, *serviceWake, *serviceDestroy, net, vc, key) + cmdService(*serviceName, *servicePorts, *serviceDomains, *serviceType, *serviceBootstrap, *serviceList, *serviceInfo, *serviceLogs, *serviceTail, *serviceSleep, *serviceWake, *serviceDestroy, *serviceExecute, *serviceCommand, *serviceDumpBootstrap, *serviceDumpFile, net, vc, key) return case "key": diff --git a/un.js b/un.js index eb513c6..4e223a8 100644 --- a/un.js +++ b/un.js @@ -438,6 +438,34 @@ async function cmdService(args) { return; } + if (args.dumpBootstrap) { + console.error(`Fetching bootstrap script from ${args.dumpBootstrap}...`); + const payload = { command: "cat /tmp/bootstrap.sh" }; + const result = await apiRequest(`/services/${args.dumpBootstrap}/execute`, "POST", payload, apiKey); + + if (result.stdout) { + const bootstrap = result.stdout; + if (args.dumpFile) { + // Write to file + try { + fs.writeFileSync(args.dumpFile, bootstrap); + fs.chmodSync(args.dumpFile, 0o755); + console.log(`Bootstrap saved to ${args.dumpFile}`); + } catch (e) { + console.error(`${RED}Error: Could not write to ${args.dumpFile}: ${e.message}${RESET}`); + process.exit(1); + } + } else { + // Print to stdout + process.stdout.write(bootstrap); + } + } else { + console.error(`${RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file)${RESET}`); + process.exit(1); + } + return; + } + if (args.name) { const payload = { name: args.name }; if (args.ports) payload.ports = args.ports.split(',').map(p => parseInt(p.trim())); @@ -494,6 +522,8 @@ function parseArgs(argv) { destroy: null, execute: null, command_arg: null, + dumpBootstrap: null, + dumpFile: null, extend: false, }; @@ -570,10 +600,10 @@ function parseArgs(argv) { } else if (arg === '--tail' && i + 1 < argv.length) { args.tail = argv[++i]; i++; - } else if (arg === '--sleep' && i + 1 < argv.length) { + } else if (arg === '--freeze' && i + 1 < argv.length) { args.sleep = argv[++i]; i++; - } else if (arg === '--wake' && i + 1 < argv.length) { + } else if (arg === '--unfreeze' && i + 1 < argv.length) { args.wake = argv[++i]; i++; } else if (arg === '--destroy' && i + 1 < argv.length) { @@ -585,6 +615,12 @@ function parseArgs(argv) { } else if (arg === '--command' && i + 1 < argv.length) { args.command_arg = argv[++i]; i++; + } else if (arg === '--dump-bootstrap' && i + 1 < argv.length) { + args.dumpBootstrap = argv[++i]; + i++; + } else if (arg === '--dump-file' && i + 1 < argv.length) { + args.dumpFile = argv[++i]; + i++; } else if (arg === '--extend') { args.extend = true; i++; @@ -648,11 +684,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: --extend Open browser to extend key expiration diff --git a/un.lua b/un.lua index 23d4f02..33f40ab 100644 --- a/un.lua +++ b/un.lua @@ -454,6 +454,35 @@ local function cmd_service(options) return end + if options.dump_bootstrap then + io.stderr:write("Fetching bootstrap script from " .. options.dump_bootstrap .. "...\n") + local payload = { command = "cat /tmp/bootstrap.sh" } + local result = api_request("/services/" .. options.dump_bootstrap .. "/execute", "POST", payload, api_key) + + if result.stdout then + local bootstrap = result.stdout + if options.dump_file then + -- Write to file + local file = io.open(options.dump_file, "w") + if not file then + io.stderr:write(RED .. "Error: Could not write to " .. options.dump_file .. RESET .. "\n") + os.exit(1) + end + file:write(bootstrap) + file:close() + os.execute("chmod 755 " .. options.dump_file) + print("Bootstrap saved to " .. options.dump_file) + else + -- Print to stdout + io.write(bootstrap) + end + else + io.stderr:write(RED .. "Error: Failed to fetch bootstrap (service not running or no bootstrap file)" .. RESET .. "\n") + os.exit(1) + end + return + end + if options.name then local payload = { name = options.name } if options.ports then @@ -527,6 +556,8 @@ local function main() destroy = nil, execute = nil, command = nil, + dump_bootstrap = nil, + dump_file = nil, extend = false } @@ -597,10 +628,10 @@ local function main() elseif a == "--tail" then i = i + 1 options.tail = arg[i] - elseif a == "--sleep" then + elseif a == "--freeze" then i = i + 1 options.sleep = arg[i] - elseif a == "--wake" then + elseif a == "--unfreeze" then i = i + 1 options.wake = arg[i] elseif a == "--destroy" then @@ -612,6 +643,12 @@ local function main() elseif a == "--command" then i = i + 1 options.command = arg[i] + elseif a == "--dump-bootstrap" then + i = i + 1 + options.dump_bootstrap = arg[i] + elseif a == "--dump-file" then + i = i + 1 + options.dump_file = arg[i] elseif a == "--extend" then options.extend = true elseif not a:match("^%-") then @@ -667,11 +704,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: --extend Open browser to extend/renew key diff --git a/un.php b/un.php index 25a8f22..ca31a19 100755 --- a/un.php +++ b/un.php @@ -436,6 +436,32 @@ function cmd_service($options) { return; } + if ($options['dump_bootstrap']) { + fwrite(STDERR, "Fetching bootstrap script from {$options['dump_bootstrap']}...\n"); + $payload = ['command' => 'cat /tmp/bootstrap.sh']; + $result = api_request("/services/{$options['dump_bootstrap']}/execute", 'POST', $payload, $api_key); + + if (!empty($result['stdout'])) { + $bootstrap = $result['stdout']; + if ($options['dump_file']) { + // Write to file + if (file_put_contents($options['dump_file'], $bootstrap) === false) { + fwrite(STDERR, RED . "Error: Could not write to {$options['dump_file']}" . RESET . "\n"); + exit(1); + } + chmod($options['dump_file'], 0755); + echo "Bootstrap saved to {$options['dump_file']}\n"; + } else { + // Print to stdout + echo $bootstrap; + } + } else { + fwrite(STDERR, RED . "Error: Failed to fetch bootstrap (service not running or no bootstrap file)" . RESET . "\n"); + exit(1); + } + return; + } + if ($options['name']) { $payload = ['name' => $options['name']]; if ($options['ports']) { @@ -500,6 +526,9 @@ function main() { 'wake' => null, 'destroy' => null, 'execute' => null, + 'command' => null, + 'dump_bootstrap' => null, + 'dump_file' => null, 'extend' => false ]; @@ -580,10 +609,10 @@ function main() { case '--tail': $options['tail'] = $argv[++$i]; break; - case '--sleep': + case '--freeze': $options['sleep'] = $argv[++$i]; break; - case '--wake': + case '--unfreeze': $options['wake'] = $argv[++$i]; break; case '--destroy': @@ -595,6 +624,12 @@ function main() { case '--command': $options['command'] = $argv[++$i]; break; + case '--dump-bootstrap': + $options['dump_bootstrap'] = $argv[++$i]; + break; + case '--dump-file': + $options['dump_file'] = $argv[++$i]; + break; case '--extend': $options['extend'] = true; break; @@ -651,11 +686,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: -k KEY API key (or use UNSANDBOX_API_KEY env var) diff --git a/un.pl b/un.pl index be1ead4..bbe726c 100644 --- a/un.pl +++ b/un.pl @@ -325,6 +325,34 @@ sub cmd_service { return; } + if ($options->{dump_bootstrap}) { + print STDERR "Fetching bootstrap script from $options->{dump_bootstrap}...\n"; + my $payload = { command => 'cat /tmp/bootstrap.sh' }; + my $result = api_request("/services/$options->{dump_bootstrap}/execute", 'POST', $payload, $api_key); + + if ($result->{stdout}) { + my $bootstrap = $result->{stdout}; + if ($options->{dump_file}) { + # Write to file + open my $fh, '>', $options->{dump_file} or do { + print STDERR "${RED}Error: Could not write to $options->{dump_file}: $!${RESET}\n"; + exit 1; + }; + print $fh $bootstrap; + close $fh; + chmod 0755, $options->{dump_file}; + print "Bootstrap saved to $options->{dump_file}\n"; + } else { + # Print to stdout + print $bootstrap; + } + } else { + print STDERR "${RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file)${RESET}\n"; + exit 1; + } + return; + } + if ($options->{name}) { my $payload = { name => $options->{name} }; if ($options->{ports}) { @@ -462,6 +490,8 @@ sub main { destroy => undef, execute => undef, command => undef, + dump_bootstrap => undef, + dump_file => undef, extend => 0 ); @@ -514,9 +544,9 @@ sub main { $options{logs} = $ARGV[++$i]; } elsif ($arg eq '--tail') { $options{tail} = $ARGV[++$i]; - } elsif ($arg eq '--sleep') { + } elsif ($arg eq '--freeze') { $options{sleep} = $ARGV[++$i]; - } elsif ($arg eq '--wake') { + } elsif ($arg eq '--unfreeze') { $options{wake} = $ARGV[++$i]; } elsif ($arg eq '--destroy') { $options{destroy} = $ARGV[++$i]; @@ -524,6 +554,10 @@ sub main { $options{execute} = $ARGV[++$i]; } elsif ($arg eq '--command') { $options{command} = $ARGV[++$i]; + } elsif ($arg eq '--dump-bootstrap') { + $options{dump_bootstrap} = $ARGV[++$i]; + } elsif ($arg eq '--dump-file') { + $options{dump_file} = $ARGV[++$i]; } elsif ($arg eq '--extend') { $options{extend} = 1; } elsif ($arg !~ /^-/) { @@ -577,11 +611,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: --extend Open browser to extend/renew key diff --git a/un.py b/un.py index 15d3043..f8f4002 100644 --- a/un.py +++ b/un.py @@ -392,6 +392,31 @@ def cmd_service(args): print(f"{RED}{result['stderr']}{RESET}", end='', file=sys.stderr) return + if args.dump_bootstrap: + print(f"Fetching bootstrap script from {args.dump_bootstrap}...", file=sys.stderr) + payload = {"command": "cat /tmp/bootstrap.sh"} + result = api_request(f"/services/{args.dump_bootstrap}/execute", method="POST", data=payload, api_key=api_key) + + if result.get("stdout"): + bootstrap = result["stdout"] + if args.dump_file: + # Write to file + try: + with open(args.dump_file, 'w') as f: + f.write(bootstrap) + os.chmod(args.dump_file, 0o755) + print(f"Bootstrap saved to {args.dump_file}") + except IOError as e: + print(f"{RED}Error: Could not write to {args.dump_file}: {e}{RESET}", file=sys.stderr) + sys.exit(1) + else: + # Print to stdout + print(bootstrap, end='') + else: + print(f"{RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file){RESET}", file=sys.stderr) + sys.exit(1) + return + # Create new service if args.name: payload = {"name": args.name} @@ -478,11 +503,13 @@ Examples: service_parser.add_argument("--info", metavar="ID", help="Get service details") service_parser.add_argument("--tail", metavar="ID", help="Get last 9000 lines of logs") service_parser.add_argument("--logs", metavar="ID", help="Get all logs") - service_parser.add_argument("--sleep", metavar="ID", help="Freeze service") - service_parser.add_argument("--wake", metavar="ID", help="Unfreeze service") + service_parser.add_argument("--freeze", metavar="ID", help="Freeze service") + service_parser.add_argument("--unfreeze", metavar="ID", help="Unfreeze service") service_parser.add_argument("--destroy", metavar="ID", help="Destroy service") service_parser.add_argument("--execute", metavar="ID", help="Execute command in service") service_parser.add_argument("--command", help="Command to execute (with --execute)") + service_parser.add_argument("--dump-bootstrap", metavar="ID", help="Dump bootstrap script") + service_parser.add_argument("--dump-file", metavar="FILE", help="File to save bootstrap (with --dump-bootstrap)") service_parser.add_argument("-n", "--network", choices=["zerotrust", "semitrusted"]) service_parser.add_argument("-v", "--vcpu", type=int, choices=range(1, 9)) service_parser.add_argument("-k", "--api-key") diff --git a/un.rb b/un.rb index 3960b30..10ab283 100644 --- a/un.rb +++ b/un.rb @@ -391,6 +391,34 @@ def cmd_service(options) return end + if options[:dump_bootstrap] + warn "Fetching bootstrap script from #{options[:dump_bootstrap]}..." + payload = { command: 'cat /tmp/bootstrap.sh' } + result = api_request("/services/#{options[:dump_bootstrap]}/execute", method: 'POST', data: payload, api_key: api_key) + + if result['stdout'] + bootstrap = result['stdout'] + if options[:dump_file] + # Write to file + begin + File.write(options[:dump_file], bootstrap) + File.chmod(0755, options[:dump_file]) + puts "Bootstrap saved to #{options[:dump_file]}" + rescue => e + warn "#{RED}Error: Could not write to #{options[:dump_file]}: #{e.message}#{RESET}" + exit 1 + end + else + # Print to stdout + print bootstrap + end + else + warn "#{RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file)#{RESET}" + exit 1 + end + return + end + if options[:name] payload = { name: options[:name] } payload[:ports] = options[:ports].split(',').map(&:to_i) if options[:ports] @@ -447,6 +475,8 @@ def main wake: nil, destroy: nil, execute: nil, + dump_bootstrap: nil, + dump_file: nil, extend: false } @@ -519,10 +549,10 @@ def main when '--tail' i += 1 options[:tail] = ARGV[i] - when '--sleep' + when '--freeze' i += 1 options[:sleep] = ARGV[i] - when '--wake' + when '--unfreeze' i += 1 options[:wake] = ARGV[i] when '--destroy' @@ -534,6 +564,12 @@ def main when '--command' i += 1 options[:command] = ARGV[i] + when '--dump-bootstrap' + i += 1 + options[:dump_bootstrap] = ARGV[i] + when '--dump-file' + i += 1 + options[:dump_file] = ARGV[i] when '--extend' options[:extend] = true else @@ -591,11 +627,13 @@ def main --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: -k KEY API key (or use UNSANDBOX_API_KEY env var) diff --git a/un.sh b/un.sh index 5af3869..35e6c3f 100644 --- a/un.sh +++ b/un.sh @@ -449,11 +449,11 @@ cmd_service() { tail="$2" shift 2 ;; - --sleep) + --freeze) sleep="$2" shift 2 ;; - --wake) + --unfreeze) wake="$2" shift 2 ;; @@ -469,6 +469,14 @@ cmd_service() { command="$2" shift 2 ;; + --dump-bootstrap) + dump_bootstrap="$2" + shift 2 + ;; + --dump-file) + dump_file="$2" + shift 2 + ;; -n) network="$2" shift 2 @@ -548,6 +556,29 @@ cmd_service() { return fi + if [[ -n "$dump_bootstrap" ]]; then + echo "Fetching bootstrap script from $dump_bootstrap..." >&2 + local payload=$(jq -n '{command: "cat /tmp/bootstrap.sh"}') + local result=$(api_request "/services/$dump_bootstrap/execute" "POST" "$payload" "$api_key") + local bootstrap=$(echo "$result" | jq -r '.stdout // empty') + + if [[ -n "$bootstrap" ]]; then + if [[ -n "$dump_file" ]]; then + # Write to file + echo "$bootstrap" > "$dump_file" + chmod 755 "$dump_file" + echo "Bootstrap saved to $dump_file" + else + # Print to stdout + echo -n "$bootstrap" + fi + else + echo -e "${RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file)${RESET}" >&2 + exit 1 + fi + return + fi + if [[ -n "$name" ]]; then local payload=$(jq -n --arg n "$name" '{name: $n}') @@ -774,11 +805,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: -k KEY API key to validate diff --git a/un.ts b/un.ts index f5a0060..3ce5163 100644 --- a/un.ts +++ b/un.ts @@ -393,6 +393,34 @@ async function cmdService(args: Args): Promise { return; } + if (args.dumpBootstrap) { + console.error(`Fetching bootstrap script from ${args.dumpBootstrap}...`); + const payload = { command: "cat /tmp/bootstrap.sh" }; + const result = await apiRequest(`/services/${args.dumpBootstrap}/execute`, "POST", payload, apiKey); + + if (result.stdout) { + const bootstrap = result.stdout; + if (args.dumpFile) { + // Write to file + try { + fs.writeFileSync(args.dumpFile, bootstrap); + fs.chmodSync(args.dumpFile, 0o755); + console.log(`Bootstrap saved to ${args.dumpFile}`); + } catch (e: any) { + console.error(`${RED}Error: Could not write to ${args.dumpFile}: ${e.message}${RESET}`); + process.exit(1); + } + } else { + // Print to stdout + process.stdout.write(bootstrap); + } + } else { + console.error(`${RED}Error: Failed to fetch bootstrap (service not running or no bootstrap file)${RESET}`); + process.exit(1); + } + return; + } + if (args.name) { const payload: any = { name: args.name }; if (args.ports) payload.ports = args.ports.split(',').map(p => parseInt(p.trim())); @@ -520,6 +548,8 @@ function parseArgs(argv: string[]): Args { destroy: null, execute: null, command_arg: null, + dumpBootstrap: null, + dumpFile: null, extend: false, }; @@ -596,10 +626,10 @@ function parseArgs(argv: string[]): Args { } else if (arg === '--tail' && i + 1 < argv.length) { args.tail = argv[++i]; i++; - } else if (arg === '--sleep' && i + 1 < argv.length) { + } else if (arg === '--freeze' && i + 1 < argv.length) { args.sleep = argv[++i]; i++; - } else if (arg === '--wake' && i + 1 < argv.length) { + } else if (arg === '--unfreeze' && i + 1 < argv.length) { args.wake = argv[++i]; i++; } else if (arg === '--destroy' && i + 1 < argv.length) { @@ -611,6 +641,12 @@ function parseArgs(argv: string[]): Args { } else if (arg === '--command' && i + 1 < argv.length) { args.command_arg = argv[++i]; i++; + } else if (arg === '--dump-bootstrap' && i + 1 < argv.length) { + args.dumpBootstrap = argv[++i]; + i++; + } else if (arg === '--dump-file' && i + 1 < argv.length) { + args.dumpFile = argv[++i]; + i++; } else if (arg === '--extend') { args.extend = true; i++; @@ -674,11 +710,13 @@ Service options: --info ID Get service details --logs ID Get all logs --tail ID Get last 9000 lines - --sleep ID Freeze service - --wake ID Unfreeze service + --freeze ID Freeze service + --unfreeze ID Unfreeze service --destroy ID Destroy service --execute ID Execute command in service --command CMD Command to execute (with --execute) + --dump-bootstrap ID Dump bootstrap script + --dump-file FILE File to save bootstrap (with --dump-bootstrap) Key options: --extend Open browser to extend key expiration