/
shutdown.go
103 lines (81 loc) · 2.62 KB
/
shutdown.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package server
import (
"errors"
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/hetznercloud/cli/internal/cmd/base"
"github.com/hetznercloud/cli/internal/cmd/cmpl"
"github.com/hetznercloud/cli/internal/hcapi2"
"github.com/hetznercloud/cli/internal/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
var ShutdownCmd = base.Cmd{
BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
const description = "Shuts down a Server gracefully by sending an ACPI shutdown request. " +
"The Server operating system must support ACPI and react to the request, " +
"otherwise the Server will not shut down. Use the --wait flag to wait for the " +
"server to shut down before returning."
cmd := &cobra.Command{
Use: "shutdown [options] <server>",
Short: "Shutdown a server",
Long: description,
ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)),
TraverseChildren: true,
DisableFlagsInUseLine: true,
}
cmd.Flags().Bool("wait", false, "Wait for the server to shut down before exiting")
cmd.Flags().Duration("wait-timeout", 30*time.Second, "Timeout for waiting for off state after shutdown")
return cmd
},
Run: func(s state.State, cmd *cobra.Command, args []string) error {
wait, _ := cmd.Flags().GetBool("wait")
timeout, _ := cmd.Flags().GetDuration("wait-timeout")
idOrName := args[0]
server, _, err := s.Client().Server().Get(s, idOrName)
if err != nil {
return err
}
if server == nil {
return fmt.Errorf("server not found: %s", idOrName)
}
action, _, err := s.Client().Server().Shutdown(s, server)
if err != nil {
return err
}
if err := s.ActionProgress(cmd, s, action); err != nil {
return err
}
cmd.Printf("Sent shutdown signal to server %d\n", server.ID)
if wait {
start := time.Now()
errCh := make(chan error)
interval, _ := cmd.Flags().GetDuration("poll-interval")
if interval < time.Second {
interval = time.Second
}
go func() {
defer close(errCh)
ticker := time.NewTicker(interval)
defer ticker.Stop()
for server.Status != hcloud.ServerStatusOff {
if now := <-ticker.C; now.Sub(start) >= timeout {
errCh <- errors.New("failed to shut down server")
return
}
server, _, err = s.Client().Server().GetByID(s, server.ID)
if err != nil {
errCh <- err
return
}
}
errCh <- nil
}()
if err := state.DisplayProgressCircle(cmd, errCh, "Waiting for server to shut down"); err != nil {
return err
}
cmd.Printf("Server %d shut down\n", server.ID)
}
return nil
},
}