OLD | NEW |
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package manual | 4 package manual |
5 | 5 |
6 import ( | 6 import ( |
7 "bytes" | 7 "bytes" |
8 "fmt" | 8 "fmt" |
9 "io" | 9 "io" |
10 "regexp" | 10 "regexp" |
11 "strconv" | 11 "strconv" |
12 "strings" | 12 "strings" |
13 | 13 |
| 14 "github.com/juju/errgo/errors" |
| 15 |
14 "launchpad.net/juju-core/instance" | 16 "launchpad.net/juju-core/instance" |
15 "launchpad.net/juju-core/utils" | 17 "launchpad.net/juju-core/utils" |
16 "launchpad.net/juju-core/utils/ssh" | 18 "launchpad.net/juju-core/utils/ssh" |
17 ) | 19 ) |
18 | 20 |
19 // checkProvisionedScript is the script to run on the remote machine | 21 // checkProvisionedScript is the script to run on the remote machine |
20 // to check if a machine has already been provisioned. | 22 // to check if a machine has already been provisioned. |
21 // | 23 // |
22 // This is a little convoluted to avoid returning an error in the | 24 // This is a little convoluted to avoid returning an error in the |
23 // common case of no matching files. | 25 // common case of no matching files. |
24 const checkProvisionedScript = "ls /etc/init/ | grep juju.*\\.conf || exit 0" | 26 const checkProvisionedScript = "ls /etc/init/ | grep juju.*\\.conf || exit 0" |
25 | 27 |
26 // checkProvisioned checks if any juju upstart jobs already | 28 // checkProvisioned checks if any juju upstart jobs already |
27 // exist on the host machine. | 29 // exist on the host machine. |
28 func checkProvisioned(host string) (bool, error) { | 30 func checkProvisioned(host string) (bool, error) { |
29 logger.Infof("Checking if %s is already provisioned", host) | 31 logger.Infof("Checking if %s is already provisioned", host) |
30 cmd := ssh.Command("ubuntu@"+host, []string{"/bin/bash"}, nil) | 32 cmd := ssh.Command("ubuntu@"+host, []string{"/bin/bash"}, nil) |
31 var stdout, stderr bytes.Buffer | 33 var stdout, stderr bytes.Buffer |
32 cmd.Stdout = &stdout | 34 cmd.Stdout = &stdout |
33 cmd.Stderr = &stderr | 35 cmd.Stderr = &stderr |
34 cmd.Stdin = strings.NewReader(checkProvisionedScript) | 36 cmd.Stdin = strings.NewReader(checkProvisionedScript) |
35 if err := cmd.Run(); err != nil { | 37 if err := cmd.Run(); err != nil { |
36 if stderr.Len() != 0 { | 38 if stderr.Len() != 0 { |
37 » » » err = fmt.Errorf("%v (%v)", err, strings.TrimSpace(stder
r.String())) | 39 » » » err = errors.Newf("%v (%v)", err, strings.TrimSpace(stde
rr.String())) |
38 } | 40 } |
39 return false, err | 41 return false, err |
40 } | 42 } |
41 output := strings.TrimSpace(stdout.String()) | 43 output := strings.TrimSpace(stdout.String()) |
42 provisioned := len(output) > 0 | 44 provisioned := len(output) > 0 |
43 if provisioned { | 45 if provisioned { |
44 logger.Infof("%s is already provisioned [%q]", host, output) | 46 logger.Infof("%s is already provisioned [%q]", host, output) |
45 } else { | 47 } else { |
46 logger.Infof("%s is not provisioned", host) | 48 logger.Infof("%s is not provisioned", host) |
47 } | 49 } |
48 return provisioned, nil | 50 return provisioned, nil |
49 } | 51 } |
50 | 52 |
51 // DetectSeriesAndHardwareCharacteristics detects the OS | 53 // DetectSeriesAndHardwareCharacteristics detects the OS |
52 // series and hardware characteristics of the remote machine | 54 // series and hardware characteristics of the remote machine |
53 // by connecting to the machine and executing a bash script. | 55 // by connecting to the machine and executing a bash script. |
54 func DetectSeriesAndHardwareCharacteristics(host string) (hc instance.HardwareCh
aracteristics, series string, err error) { | 56 func DetectSeriesAndHardwareCharacteristics(host string) (hc instance.HardwareCh
aracteristics, series string, err error) { |
55 logger.Infof("Detecting series and characteristics on %s", host) | 57 logger.Infof("Detecting series and characteristics on %s", host) |
56 cmd := ssh.Command("ubuntu@"+host, []string{"/bin/bash"}, nil) | 58 cmd := ssh.Command("ubuntu@"+host, []string{"/bin/bash"}, nil) |
57 var stdout, stderr bytes.Buffer | 59 var stdout, stderr bytes.Buffer |
58 cmd.Stdout = &stdout | 60 cmd.Stdout = &stdout |
59 cmd.Stderr = &stderr | 61 cmd.Stderr = &stderr |
60 cmd.Stdin = bytes.NewBufferString(detectionScript) | 62 cmd.Stdin = bytes.NewBufferString(detectionScript) |
61 if err := cmd.Run(); err != nil { | 63 if err := cmd.Run(); err != nil { |
62 if stderr.Len() != 0 { | 64 if stderr.Len() != 0 { |
63 » » » err = fmt.Errorf("%v (%v)", err, strings.TrimSpace(stder
r.String())) | 65 » » » err = errors.Newf("%v (%v)", err, strings.TrimSpace(stde
rr.String())) |
64 } | 66 } |
65 return hc, "", err | 67 return hc, "", err |
66 } | 68 } |
67 lines := strings.Split(stdout.String(), "\n") | 69 lines := strings.Split(stdout.String(), "\n") |
68 series = strings.TrimSpace(lines[0]) | 70 series = strings.TrimSpace(lines[0]) |
69 | 71 |
70 // Normalise arch. | 72 // Normalise arch. |
71 arch := strings.TrimSpace(lines[1]) | 73 arch := strings.TrimSpace(lines[1]) |
72 for _, re := range archREs { | 74 for _, re := range archREs { |
73 if re.Match([]byte(arch)) { | 75 if re.Match([]byte(arch)) { |
74 hc.Arch = &re.arch | 76 hc.Arch = &re.arch |
75 break | 77 break |
76 } | 78 } |
77 } | 79 } |
78 if hc.Arch == nil { | 80 if hc.Arch == nil { |
79 » » err = fmt.Errorf("unrecognised architecture: %s", arch) | 81 » » err = errors.Newf("unrecognised architecture: %s", arch) |
80 return hc, "", err | 82 return hc, "", err |
81 } | 83 } |
82 | 84 |
83 // HardwareCharacteristics wants memory in megabytes, | 85 // HardwareCharacteristics wants memory in megabytes, |
84 // meminfo reports it in kilobytes. | 86 // meminfo reports it in kilobytes. |
85 memkB := strings.Fields(lines[2])[1] // "MemTotal: NNN kB" | 87 memkB := strings.Fields(lines[2])[1] // "MemTotal: NNN kB" |
86 hc.Mem = new(uint64) | 88 hc.Mem = new(uint64) |
87 *hc.Mem, err = strconv.ParseUint(memkB, 10, 0) | 89 *hc.Mem, err = strconv.ParseUint(memkB, 10, 0) |
88 *hc.Mem /= 1024 | 90 *hc.Mem /= 1024 |
89 | 91 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 var options ssh.Options | 178 var options ssh.Options |
177 options.AllowPasswordAuthentication() | 179 options.AllowPasswordAuthentication() |
178 options.EnablePTY() | 180 options.EnablePTY() |
179 cmd = ssh.Command(host, []string{"sudo", "/bin/bash -c " + utils.ShQuote
(script)}, &options) | 181 cmd = ssh.Command(host, []string{"sudo", "/bin/bash -c " + utils.ShQuote
(script)}, &options) |
180 var stderr bytes.Buffer | 182 var stderr bytes.Buffer |
181 cmd.Stdin = stdin | 183 cmd.Stdin = stdin |
182 cmd.Stdout = stdout // for sudo prompt | 184 cmd.Stdout = stdout // for sudo prompt |
183 cmd.Stderr = &stderr | 185 cmd.Stderr = &stderr |
184 if err := cmd.Run(); err != nil { | 186 if err := cmd.Run(); err != nil { |
185 if stderr.Len() != 0 { | 187 if stderr.Len() != 0 { |
186 » » » err = fmt.Errorf("%v (%v)", err, strings.TrimSpace(stder
r.String())) | 188 » » » err = errors.Newf("%v (%v)", err, strings.TrimSpace(stde
rr.String())) |
187 } | 189 } |
188 return err | 190 return err |
189 } | 191 } |
190 return nil | 192 return nil |
191 } | 193 } |
192 | 194 |
193 const initUbuntuScript = ` | 195 const initUbuntuScript = ` |
194 set -e | 196 set -e |
195 (id ubuntu &> /dev/null) || useradd -m ubuntu | 197 (id ubuntu &> /dev/null) || useradd -m ubuntu |
196 umask 0077 | 198 umask 0077 |
197 temp=$(mktemp) | 199 temp=$(mktemp) |
198 echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > $temp | 200 echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > $temp |
199 install -m 0440 $temp /etc/sudoers.d/90-juju-ubuntu | 201 install -m 0440 $temp /etc/sudoers.d/90-juju-ubuntu |
200 rm $temp | 202 rm $temp |
201 su ubuntu -c 'install -D -m 0600 /dev/null ~/.ssh/authorized_keys' | 203 su ubuntu -c 'install -D -m 0600 /dev/null ~/.ssh/authorized_keys' |
202 export authorized_keys=%s | 204 export authorized_keys=%s |
203 if [ ! -z "$authorized_keys" ]; then | 205 if [ ! -z "$authorized_keys" ]; then |
204 su ubuntu -c 'printf "%%s\n" "$authorized_keys" >> ~/.ssh/authorized_keys' | 206 su ubuntu -c 'printf "%%s\n" "$authorized_keys" >> ~/.ssh/authorized_keys' |
205 fi` | 207 fi` |
OLD | NEW |