diff --git a/README.md b/README.md index 824a299..6d50bc0 100644 --- a/README.md +++ b/README.md @@ -31,15 +31,13 @@ In either case, saving the token to `$HOME/.actuated/PAT` will mean you can avoi ## View queued jobs ```bash -actuated-cli jobs \ - --owner actuated-samples +actuated-cli jobs actuated-samples ``` ## View runners for organization ```bash -actuated-cli runners \ - --owner actuated-samples +actuated-cli runners actuated-samples ``` ## View SSH sessions available: @@ -99,9 +97,9 @@ View the serial console and systemd output of the VMs launched on a specific ser ```bash actuated-cli logs \ - --host runner1 \ --owner actuated-samples \ - --age 15m + --age 15m \ + server1 ``` The age is specified as a Go duration i.e. `60m` or `24h`. @@ -110,9 +108,9 @@ You can also get the logs for a specific runner by using the `--id` flag. ```bash actuated-cli logs \ - --host runner1 \ --owner actuated-samples \ - --id ea5c285282620927689d90af3cfa3be2d5e2d004 + --id ea5c285282620927689d90af3cfa3be2d5e2d004 \ + --host server1 ``` ## Check the logs of the actuated agent service @@ -123,9 +121,9 @@ View VM launch times, etc. ```bash actuated-cli agent-logs \ - --host runner1 \ --owner actuated-samples \ - --age 15m + --age 15m \ + --host server1 ``` ## Schedule a repair to re-queue jobs @@ -138,7 +136,7 @@ Run with sparingly because it will launch one VM per job queued. ```bash actuated-cli repair \ - --owner actuated-samples + actuated-samples ``` ## Rescue a remote server @@ -148,7 +146,7 @@ Restart the agent by sending a `kill -9` signal: ```bash actuated-cli restart \ --owner actuated-samples \ - --host runner1 + server1 ``` Any inflight VMs will be killed, see also: `actuated-cli update --force` @@ -158,8 +156,8 @@ Reboot the machine, if in an unrecoverable position: ```bash actuated-cli restart \ --owner actuated-samples \ - --host runner1 \ - --reboot + --reboot \ + server1 ``` Use with caution, since this may not perform a safe and clean shutdown. diff --git a/cmd/agent-logs.go b/cmd/agent-logs.go index d76039a..5e281df 100644 --- a/cmd/agent-logs.go +++ b/cmd/agent-logs.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "os" + "strings" "time" "github.com/self-actuated/actuated-cli/pkg" @@ -12,21 +13,31 @@ import ( func makeAgentLogs() *cobra.Command { cmd := &cobra.Command{ - Use: "agent-logs", - Short: "Fetch logs from the agent's systemd service", + Use: "agent-logs", + Short: "Fetch logs from the agent's systemd service", + Example: ` # Latest logs for a given host: + actuated agent-logs --owner OWNER HOST + + # Latest logs for a given time-range + actuated agent-logs --owner OWNER --age 1h HOST + `, Aliases: []string{"service-logs"}, } cmd.RunE = runAgentLogsE cmd.Flags().StringP("owner", "o", "", "Owner for the logs") - cmd.Flags().String("host", "", "Host or name of server as displayed in actuated") cmd.Flags().DurationP("age", "a", time.Minute*15, "Age of logs to fetch") return cmd } func runAgentLogsE(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("specify the host as an argument") + } + host := strings.TrimSpace(args[0]) + pat, err := getPat(cmd) if err != nil { return err @@ -47,10 +58,6 @@ func runAgentLogsE(cmd *cobra.Command, args []string) error { return err } - host, err := cmd.Flags().GetString("host") - if err != nil { - return err - } if len(host) == 0 { return fmt.Errorf("host is required") } diff --git a/cmd/jobs.go b/cmd/jobs.go index fde60f4..7d231a8 100644 --- a/cmd/jobs.go +++ b/cmd/jobs.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "os" + "strings" "github.com/self-actuated/actuated-cli/pkg" "github.com/spf13/cobra" @@ -15,28 +16,37 @@ func makeJobs() *cobra.Command { cmd := &cobra.Command{ Use: "jobs", Short: "List jobs in the build queue", + Example: ` # Check queued and in_progress jobs for an organisation + actuated-cli jobs ORG + + # Get the same result, but in JSON format + actuated-cli jobs ORG --json + + # Check queued and in_progress jobs for a customer + actuated-cli jobs --staff CUSTOMER +`, } cmd.RunE = runJobsE - cmd.Flags().StringP("owner", "o", "", "List jobs owned by this user") cmd.Flags().Bool("json", false, "Request output in JSON format") return cmd } func runJobsE(cmd *cobra.Command, args []string) error { - pat, err := getPat(cmd) - if err != nil { - return err + + if len(args) < 1 { + return fmt.Errorf("give an owner as an argument") } + owner := strings.TrimSpace(args[0]) - staff, err := cmd.Flags().GetBool("staff") + pat, err := getPat(cmd) if err != nil { return err } - owner, err := cmd.Flags().GetString("owner") + staff, err := cmd.Flags().GetBool("staff") if err != nil { return err } diff --git a/cmd/logs.go b/cmd/logs.go index 8980038..f814903 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "os" + "strings" "time" "github.com/self-actuated/actuated-cli/pkg" @@ -18,17 +19,16 @@ func makeLogs() *cobra.Command { range of time.`, Example: `# Logs from all VMs over the past 15 minutes -actuated-cli logs --owner=OWNER --host=HOST --age=15m +actuated-cli logs --owner=OWNER --age=15m HOST # All logs from a specific VM using its hostname as the --id -actuated-cli logs --owner=OWNER --host=HOST --id=ID +actuated-cli logs --owner=OWNER --id=ID HOST `, } cmd.RunE = runLogsE cmd.Flags().StringP("owner", "o", "", "List logs owned by this user") - cmd.Flags().String("host", "", "Host or name of server as displayed in actuated") cmd.Flags().String("id", "", "ID variable for a specific runner VM hostname") cmd.Flags().DurationP("age", "a", time.Minute*15, "Age of logs to fetch") @@ -36,6 +36,11 @@ actuated-cli logs --owner=OWNER --host=HOST --id=ID } func runLogsE(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("specify the host as an argument") + } + host := strings.TrimSpace(args[0]) + pat, err := getPat(cmd) if err != nil { return err @@ -56,13 +61,11 @@ func runLogsE(cmd *cobra.Command, args []string) error { return err } - host, err := cmd.Flags().GetString("host") + id, err := cmd.Flags().GetString("id") if err != nil { return err } - id, err := cmd.Flags().GetString("id") - if len(host) == 0 { return fmt.Errorf("host is required") } diff --git a/cmd/repair.go b/cmd/repair.go index 56e62a3..48b3553 100644 --- a/cmd/repair.go +++ b/cmd/repair.go @@ -20,11 +20,16 @@ Use sparingly, check the build queue to see if there is a need for more VMs to be launched. Then, allow ample time for the new VMs to pick up a job by checking the build queue again for an in_progress status.`, + Example: ` ## Launch VMs for queued jobs in a given organisation + actuated repair OWNER + + ## Launch VMs for queued jobs in a given organisation for a customer + actuated repair --staff OWNER +`, } cmd.RunE = runRepairE - cmd.Flags().StringP("owner", "o", "", "List repair owned by this user") cmd.Flags().BoolP("staff", "s", false, "List staff repair") return cmd diff --git a/cmd/restart.go b/cmd/restart.go index f5c84ec..e493a41 100644 --- a/cmd/restart.go +++ b/cmd/restart.go @@ -17,11 +17,11 @@ func makeRestart() *cobra.Command { Example: ` # Request the agent to restart # This will drain any running jobs - do a forced upgrade if you want to # restart gracefully. - actuated-cli restart --owner ORG --host HOST + actuated-cli restart --owner ORG HOST # Reboot the machine, if the agent is not responding. # This will not drain any running jobs. - actuated-cli restart --owner ORG --host HOST --reboot + actuated-cli restart --owner ORG --reboot HOST `, } @@ -30,12 +30,16 @@ func makeRestart() *cobra.Command { cmd.Flags().StringP("owner", "o", "", "Owner") cmd.Flags().BoolP("staff", "s", false, "Staff flag") cmd.Flags().BoolP("reboot", "r", false, "Reboot the machine instead of just restarting the service") - cmd.Flags().String("host", "", "Host to restart") return cmd } func runRestartE(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return fmt.Errorf("specify the host as an argument") + } + host := strings.TrimSpace(args[0]) + pat, err := getPat(cmd) if err != nil { return err @@ -56,11 +60,6 @@ func runRestartE(cmd *cobra.Command, args []string) error { return err } - host, err := cmd.Flags().GetString("host") - if err != nil { - return err - } - if len(owner) == 0 { return fmt.Errorf("owner is required") } diff --git a/cmd/runners.go b/cmd/runners.go index 37969c1..422b7c6 100644 --- a/cmd/runners.go +++ b/cmd/runners.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "os" + "strings" "github.com/self-actuated/actuated-cli/pkg" "github.com/spf13/cobra" @@ -14,12 +15,20 @@ import ( func makeRunners() *cobra.Command { cmd := &cobra.Command{ Use: "runners", - Short: "List runners", + Short: "List runners for an organisation", + Example: ` # List runners for a given organisation + actuated-cli runners OWNER + + # List runners for all customers + actuated-cli runners --staff OWNER + + # List runners in JSON format + actuated-cli runners --json OWNER +`, } cmd.RunE = runRunnersE - cmd.Flags().StringP("owner", "o", "", "List runners owned by this user") cmd.Flags().BoolP("staff", "s", false, "List staff runners") cmd.Flags().Bool("json", false, "Request output in JSON format") @@ -27,17 +36,18 @@ func makeRunners() *cobra.Command { } func runRunnersE(cmd *cobra.Command, args []string) error { - pat, err := getPat(cmd) - if err != nil { - return err + + if len(args) < 1 { + return fmt.Errorf("give an owner as an argument") } + owner := strings.TrimSpace(args[0]) - staff, err := cmd.Flags().GetBool("staff") + pat, err := getPat(cmd) if err != nil { return err } - owner, err := cmd.Flags().GetString("owner") + staff, err := cmd.Flags().GetBool("staff") if err != nil { return err } diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 041eaf4..430650a 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -16,10 +16,10 @@ func makeUpgrade() *cobra.Command { Use: "upgrade", Short: "Upgrade an agent's kernel and root filesystem", Example: ` # Upgrade the agent if a newer one is available - actuated-cli upgrade --owner ORG --host HOST + actuated-cli upgrade --owner ORG HOST # Force an upgrade, even if on the latest version of the agent - actuated-cli upgrade --owner ORG --host HOST --host + actuated-cli upgrade --owner ORG --force HOST `, } @@ -28,13 +28,18 @@ func makeUpgrade() *cobra.Command { cmd.Flags().StringP("owner", "o", "", "Owner") cmd.Flags().BoolP("staff", "s", false, "Staff flag") cmd.Flags().BoolP("force", "f", false, "Force upgrade") - cmd.Flags().String("host", "", "Host to upgrade") cmd.Flags().BoolP("all", "a", false, "Upgrade all hosts instead of giving --host") return cmd } func runUpgradeE(cmd *cobra.Command, args []string) error { + + if len(args) < 1 { + return fmt.Errorf("specify the host as an argument") + } + host := strings.TrimSpace(args[0]) + pat, err := getPat(cmd) if err != nil { return err @@ -55,11 +60,6 @@ func runUpgradeE(cmd *cobra.Command, args []string) error { return err } - host, err := cmd.Flags().GetString("host") - if err != nil { - return err - } - allHosts, err := cmd.Flags().GetBool("all") if err != nil { return err