forked from canonical/lxd
/
action.go
103 lines (84 loc) · 2.49 KB
/
action.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 main
import (
"fmt"
"github.com/lxc/lxd"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/gnuflag"
"github.com/lxc/lxd/shared/i18n"
)
type actionCmd struct {
action shared.ContainerAction
hasTimeout bool
visible bool
name string
timeout int
force bool
stateful bool
stateless bool
additionalHelp string
}
func (c *actionCmd) showByDefault() bool {
return c.visible
}
func (c *actionCmd) usage() string {
if c.additionalHelp != "" {
c.additionalHelp = fmt.Sprintf("\n\n%s", c.additionalHelp)
}
return fmt.Sprintf(i18n.G(
`Changes state of one or more containers to %s.
lxc %s <name> [<name>...]%s`), c.name, c.name, c.additionalHelp)
}
func (c *actionCmd) flags() {
if c.hasTimeout {
gnuflag.IntVar(&c.timeout, "timeout", -1, i18n.G("Time to wait for the container before killing it."))
gnuflag.BoolVar(&c.force, "f", false, i18n.G("Force the container to shutdown."))
gnuflag.BoolVar(&c.force, "force", false, i18n.G("Force the container to shutdown."))
}
gnuflag.BoolVar(&c.stateful, "stateful", false, i18n.G("Store the container state (only for stop)."))
gnuflag.BoolVar(&c.stateless, "stateless", false, i18n.G("Ignore the container state (only for start)."))
}
func (c *actionCmd) run(config *lxd.Config, args []string) error {
if len(args) == 0 {
return errArgs
}
state := false
// Only store state if asked to
if c.action == "stop" && c.stateful {
state = true
}
for _, nameArg := range args {
remote, name := config.ParseRemoteAndContainer(nameArg)
d, err := lxd.NewClient(config, remote)
if err != nil {
return err
}
if name == "" {
return fmt.Errorf(i18n.G("Must supply container name for: ")+"\"%s\"", nameArg)
}
if c.action == shared.Start {
current, err := d.ContainerInfo(name)
if err != nil {
return err
}
// "start" for a frozen container means "unfreeze"
if current.StatusCode == shared.Frozen {
c.action = shared.Unfreeze
}
// Always restore state (if present) unless asked not to
if c.action == shared.Start && current.Stateful && !c.stateless {
state = true
}
}
resp, err := d.Action(name, c.action, c.timeout, c.force, state)
if err != nil {
return err
}
if resp.Type != lxd.Async {
return fmt.Errorf(i18n.G("bad result type from action"))
}
if err := d.WaitForSuccess(resp.Operation); err != nil {
return fmt.Errorf("%s\n"+i18n.G("Try `lxc info --show-log %s` for more info"), err, nameArg)
}
}
return nil
}