~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/lxc/lxd/lxc/publish.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package main
 
2
 
 
3
import (
 
4
        "fmt"
 
5
        "strings"
 
6
 
 
7
        "github.com/lxc/lxd"
 
8
        "github.com/lxc/lxd/shared/gnuflag"
 
9
        "github.com/lxc/lxd/shared/i18n"
 
10
 
 
11
        "github.com/lxc/lxd/shared"
 
12
)
 
13
 
 
14
type publishCmd struct {
 
15
        pAliases   aliasList // aliasList defined in lxc/image.go
 
16
        makePublic bool
 
17
        Force      bool
 
18
}
 
19
 
 
20
func (c *publishCmd) showByDefault() bool {
 
21
        return true
 
22
}
 
23
 
 
24
func (c *publishCmd) usage() string {
 
25
        return i18n.G(
 
26
                `Publish containers as images.
 
27
 
 
28
lxc publish [remote:]container [remote:] [--alias=ALIAS]... [prop-key=prop-value]...`)
 
29
}
 
30
 
 
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"))
 
36
}
 
37
 
 
38
func (c *publishCmd) run(config *lxd.Config, args []string) error {
 
39
        var cRemote string
 
40
        var cName string
 
41
        iName := ""
 
42
        iRemote := ""
 
43
        properties := map[string]string{}
 
44
        firstprop := 1 // first property is arg[2] if arg[1] is image remote, else arg[1]
 
45
 
 
46
        if len(args) < 1 {
 
47
                return errArgs
 
48
        }
 
49
 
 
50
        cRemote, cName = config.ParseRemoteAndContainer(args[0])
 
51
        if len(args) >= 2 && !strings.Contains(args[1], "=") {
 
52
                firstprop = 2
 
53
                iRemote, iName = config.ParseRemoteAndContainer(args[1])
 
54
        } else {
 
55
                iRemote, iName = config.ParseRemoteAndContainer("")
 
56
        }
 
57
 
 
58
        if cName == "" {
 
59
                return fmt.Errorf(i18n.G("Container name is mandatory"))
 
60
        }
 
61
        if iName != "" {
 
62
                return fmt.Errorf(i18n.G("There is no \"image name\".  Did you want an alias?"))
 
63
        }
 
64
 
 
65
        d, err := lxd.NewClient(config, iRemote)
 
66
        if err != nil {
 
67
                return err
 
68
        }
 
69
 
 
70
        s := d
 
71
        if cRemote != iRemote {
 
72
                s, err = lxd.NewClient(config, cRemote)
 
73
                if err != nil {
 
74
                        return err
 
75
                }
 
76
        }
 
77
 
 
78
        if !shared.IsSnapshot(cName) {
 
79
                ct, err := s.ContainerInfo(cName)
 
80
                if err != nil {
 
81
                        return err
 
82
                }
 
83
 
 
84
                wasRunning := ct.StatusCode != 0 && ct.StatusCode != shared.Stopped
 
85
                wasEphemeral := ct.Ephemeral
 
86
 
 
87
                if wasRunning {
 
88
                        if !c.Force {
 
89
                                return fmt.Errorf(i18n.G("The container is currently running. Use --force to have it stopped and restarted."))
 
90
                        }
 
91
 
 
92
                        if ct.Ephemeral {
 
93
                                ct.Ephemeral = false
 
94
                                err := s.UpdateContainerConfig(cName, ct.Brief())
 
95
                                if err != nil {
 
96
                                        return err
 
97
                                }
 
98
                        }
 
99
 
 
100
                        resp, err := s.Action(cName, shared.Stop, -1, true, false)
 
101
                        if err != nil {
 
102
                                return err
 
103
                        }
 
104
 
 
105
                        op, err := s.WaitFor(resp.Operation)
 
106
                        if err != nil {
 
107
                                return err
 
108
                        }
 
109
 
 
110
                        if op.StatusCode == shared.Failure {
 
111
                                return fmt.Errorf(i18n.G("Stopping container failed!"))
 
112
                        }
 
113
                        defer s.Action(cName, shared.Start, -1, true, false)
 
114
 
 
115
                        if wasEphemeral {
 
116
                                ct.Ephemeral = true
 
117
                                err := s.UpdateContainerConfig(cName, ct.Brief())
 
118
                                if err != nil {
 
119
                                        return err
 
120
                                }
 
121
                        }
 
122
                }
 
123
        }
 
124
 
 
125
        for i := firstprop; i < len(args); i++ {
 
126
                entry := strings.SplitN(args[i], "=", 2)
 
127
                if len(entry) < 2 {
 
128
                        return errArgs
 
129
                }
 
130
                properties[entry[0]] = entry[1]
 
131
        }
 
132
 
 
133
        var fp string
 
134
 
 
135
        // Optimized local publish
 
136
        if cRemote == iRemote {
 
137
                fp, err = d.ImageFromContainer(cName, c.makePublic, c.pAliases, properties)
 
138
                if err != nil {
 
139
                        return err
 
140
                }
 
141
                fmt.Printf(i18n.G("Container published with fingerprint: %s")+"\n", fp)
 
142
                return nil
 
143
        }
 
144
 
 
145
        fp, err = s.ImageFromContainer(cName, false, nil, properties)
 
146
        if err != nil {
 
147
                return err
 
148
        }
 
149
        defer s.DeleteImage(fp)
 
150
 
 
151
        err = s.CopyImage(fp, d, false, c.pAliases, c.makePublic, false, nil)
 
152
        if err != nil {
 
153
                return err
 
154
        }
 
155
 
 
156
        fmt.Printf(i18n.G("Container published with fingerprint: %s")+"\n", fp)
 
157
 
 
158
        return nil
 
159
}