8
"github.com/lxc/lxd/shared/gnuflag"
9
"github.com/lxc/lxd/shared/i18n"
11
"github.com/lxc/lxd/shared"
14
type publishCmd struct {
15
pAliases aliasList // aliasList defined in lxc/image.go
20
func (c *publishCmd) showByDefault() bool {
24
func (c *publishCmd) usage() string {
26
`Publish containers as images.
28
lxc publish [remote:]container [remote:] [--alias=ALIAS]... [prop-key=prop-value]...`)
31
func (c *publishCmd) flags() {
32
gnuflag.BoolVar(&c.makePublic, "public", false, i18n.G("Make the image public"))
33
gnuflag.Var(&c.pAliases, "alias", i18n.G("New alias to define at target"))
34
gnuflag.BoolVar(&c.Force, "force", false, i18n.G("Stop the container if currently running"))
35
gnuflag.BoolVar(&c.Force, "f", false, i18n.G("Stop the container if currently running"))
38
func (c *publishCmd) run(config *lxd.Config, args []string) error {
43
properties := map[string]string{}
44
firstprop := 1 // first property is arg[2] if arg[1] is image remote, else arg[1]
50
cRemote, cName = config.ParseRemoteAndContainer(args[0])
51
if len(args) >= 2 && !strings.Contains(args[1], "=") {
53
iRemote, iName = config.ParseRemoteAndContainer(args[1])
55
iRemote, iName = config.ParseRemoteAndContainer("")
59
return fmt.Errorf(i18n.G("Container name is mandatory"))
62
return fmt.Errorf(i18n.G("There is no \"image name\". Did you want an alias?"))
65
d, err := lxd.NewClient(config, iRemote)
71
if cRemote != iRemote {
72
s, err = lxd.NewClient(config, cRemote)
78
if !shared.IsSnapshot(cName) {
79
ct, err := s.ContainerInfo(cName)
84
wasRunning := ct.StatusCode != 0 && ct.StatusCode != shared.Stopped
85
wasEphemeral := ct.Ephemeral
89
return fmt.Errorf(i18n.G("The container is currently running. Use --force to have it stopped and restarted."))
94
err := s.UpdateContainerConfig(cName, ct.Brief())
100
resp, err := s.Action(cName, shared.Stop, -1, true, false)
105
op, err := s.WaitFor(resp.Operation)
110
if op.StatusCode == shared.Failure {
111
return fmt.Errorf(i18n.G("Stopping container failed!"))
113
defer s.Action(cName, shared.Start, -1, true, false)
117
err := s.UpdateContainerConfig(cName, ct.Brief())
125
for i := firstprop; i < len(args); i++ {
126
entry := strings.SplitN(args[i], "=", 2)
130
properties[entry[0]] = entry[1]
135
// Optimized local publish
136
if cRemote == iRemote {
137
fp, err = d.ImageFromContainer(cName, c.makePublic, c.pAliases, properties)
141
fmt.Printf(i18n.G("Container published with fingerprint: %s")+"\n", fp)
145
fp, err = s.ImageFromContainer(cName, false, nil, properties)
149
defer s.DeleteImage(fp)
151
err = s.CopyImage(fp, d, false, c.pAliases, c.makePublic, false, nil)
156
fmt.Printf(i18n.G("Container published with fingerprint: %s")+"\n", fp)