Merge lp:~hduran-8/juju-core/upgrade_restore_for_replicaset into lp:~go-bot/juju-core/trunk

Proposed by Horacio Durán
Status: Merged
Approved by: Horacio Durán
Approved revision: no longer in the source branch.
Merged at revision: 2725
Proposed branch: lp:~hduran-8/juju-core/upgrade_restore_for_replicaset
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 197 lines (+87/-25)
2 files modified
cmd/plugins/juju-backup/juju-backup (+3/-0)
cmd/plugins/juju-restore/restore.go (+84/-25)
To merge this branch: bzr merge lp:~hduran-8/juju-core/upgrade_restore_for_replicaset
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+218998@code.launchpad.net

Commit message

Corrected restore tu support current juju code

Current restore plugin, takes a backup which contains
a dump of the mongodb for the backed up machine and
several configuration files, it bootstraps a new
machine and:
Deletes the fresh db
Loads the dump
Places the files instead of the fresh machine ones
Restarts services.
Since replicaset was introduced the db load was not
working properly. A replicaset initiate with a fresh
config was added to solve it.

https://codereview.appspot.com/94330043/

R=jameinel, klyachin

Description of the change

Corrected restore tu support current juju code

Current restore plugin, takes a backup which contains
a dump of the mongodb for the backed up machine and
several configuration files, it bootstraps a new
machine and:
Deletes the fresh db
Loads the dump
Places the files instead of the fresh machine ones
Restarts services.
Since replicaset was introduced the db load was not
working properly. A replicaset initiate with a fresh
config was added to solve it.

https://codereview.appspot.com/94330043/

To post a comment you must log in.
Revision history for this message
Horacio Durán (hduran-8) wrote :

Reviewers: mp+218998_code.launchpad.net,

Message:
Please take a look.

Description:
Corrected restore tu support current juju code

Current restore plugin, takes a backup which contains
a dump of the mongodb for the backed up machine and
several configuration files, it bootstraps a new
machine and:
Deletes the fresh db
Loads the dump
Places the files instead of the fresh machine ones
Restarts services.
Since replicaset was introduced the db load was not
working properly. A replicaset initiate with a fresh
config was added to solve it.

https://code.launchpad.net/~hduran-8/juju-core/upgrade_restore_for_replicaset/+merge/218998

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/94330043/

Affected files (+89, -25 lines):
   A [revision details]
   M cmd/plugins/juju-restore/restore.go

Revision history for this message
Vladislav Klyachin (klyachin) wrote :

LGTM with some notices

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go
File cmd/plugins/juju-restore/restore.go (right):

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode107
cmd/plugins/juju-restore/restore.go:107: set -x
I consider -e as good practice option
If you want to ignore result code of command, use:
command || true

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode120
cmd/plugins/juju-restore/restore.go:120: mkdir /tmp/oldbackup/inits
Use mkdir -p to get ok result code if directory exists and to create
several directories
Although, in this place, I would remove old backup before moving the new
one.
I am nor sure that /tmp is a good place for backups. Ofhen /tmp is
located on ramdisk and it will consume the memory. I would use
/var/lib/juju.backup.
The second 'mv' has invalid indent (spaces vs tabs).

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode131
cmd/plugins/juju-restore/restore.go:131: fi
IMHO export is not needed here and before

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode137
cmd/plugins/juju-restore/restore.go:137: mongo --ssl -u admin -p
{{.Creds.OldPassword | printf "%q" }} localhost:37017/admin --eval "$1"
I would use 'shquote' instead of 'printf "%q"' here and further, because
'string' is better than "string" , because bash processes '/' and '$'
inside of "string".

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode146
cmd/plugins/juju-restore/restore.go:146: for i in $(seq 1 50)
Shortcut for $(seq 1 50): {1..50}

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode348
cmd/plugins/juju-restore/restore.go:348: OldPassword string
OldPassword is confusing, why not use AdminPassword

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode387
cmd/plugins/juju-restore/restore.go:387: if !ok || password == "" {
Go style is oldPassword rather than olspassword
typo: oldpassword == ""

https://codereview.appspot.com/94330043/

Revision history for this message
Horacio Durán (hduran-8) wrote :

Please take a look.

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go
File cmd/plugins/juju-restore/restore.go (right):

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode120
cmd/plugins/juju-restore/restore.go:120: mkdir /tmp/oldbackup/inits
On 2014/05/09 15:33:49, vladislav.klyachin wrote:
> Use mkdir -p to get ok result code if directory exists and to create
several
> directories
> Although, in this place, I would remove old backup before moving the
new one.
> I am nor sure that /tmp is a good place for backups. Ofhen /tmp is
located on
> ramdisk and it will consume the memory. I would use
/var/lib/juju.backup.
> The second 'mv' has invalid indent (spaces vs tabs).

Done.

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode146
cmd/plugins/juju-restore/restore.go:146: for i in $(seq 1 50)
On 2014/05/09 15:33:49, vladislav.klyachin wrote:
> Shortcut for $(seq 1 50): {1..50}

Noted although I will try to keep the other way since it seems more
likely that less bash savvy people will understand it.

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode348
cmd/plugins/juju-restore/restore.go:348: OldPassword string
On 2014/05/09 15:33:49, vladislav.klyachin wrote:
> OldPassword is confusing, why not use AdminPassword
Because this is referred to as old password everywhere, since it is the
old mongo access password (used for admin)

https://codereview.appspot.com/94330043/diff/1/cmd/plugins/juju-restore/restore.go#newcode387
cmd/plugins/juju-restore/restore.go:387: if !ok || password == "" {
On 2014/05/09 15:33:49, vladislav.klyachin wrote:
> Go style is oldPassword rather than olspassword
> typo: oldpassword == ""

Done.

https://codereview.appspot.com/94330043/

Revision history for this message
John A Meinel (jameinel) wrote :

I have a couple of suggestions, if you're fine with them, then the rest
LGTM. (if you can justify why we want to get rid of 'set -e' that can be
ok, but I do think we want -u for sure, and I'd really like -e unless
there is a strong reason not to.)

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go
File cmd/plugins/juju-restore/restore.go (right):

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode107
cmd/plugins/juju-restore/restore.go:107: set -x
I'd rather see us use || true syntax than let failing things be missed
by the script.
Also, we should be setting -u (treat unknown environment variables as an
error rather than silently passing "").

for -e, I'm guessing we are worried that we might set something up but
fail to cleanup afterwards?

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode118
cmd/plugins/juju-restore/restore.go:118: rm -r /var/log/juju
it looks like you mixed tabs and spaces here, its probably better to be
consistent.

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode142
cmd/plugins/juju-restore/restore.go:142: for i in $(seq 1 50)
this change seems odd to me, is it just to make testing faster?

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode316
cmd/plugins/juju-restore/restore.go:316: paddr, err :=
conn.State.Client().PrivateAddress("0")
I really think we should be grabbing the Client() as a variable and
using it repeatedly, rather than re-instantiating it for each call.

https://codereview.appspot.com/94330043/

Revision history for this message
Horacio Durán (hduran-8) wrote :

Please take a look.

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go
File cmd/plugins/juju-restore/restore.go (right):

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode107
cmd/plugins/juju-restore/restore.go:107: set -x
On 2014/05/12 12:59:53, jameinel wrote:
> I'd rather see us use || true syntax than let failing things be missed
by the
> script.
> Also, we should be setting -u (treat unknown environment variables as
an error
> rather than silently passing "").

> for -e, I'm guessing we are worried that we might set something up but
fail to
> cleanup afterwards?

Done.

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode118
cmd/plugins/juju-restore/restore.go:118: rm -r /var/log/juju
On 2014/05/12 12:59:53, jameinel wrote:
> it looks like you mixed tabs and spaces here, its probably better to
be
> consistent.

Done.

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode142
cmd/plugins/juju-restore/restore.go:142: for i in $(seq 1 50)
On 2014/05/12 12:59:53, jameinel wrote:
> this change seems odd to me, is it just to make testing faster?

This was a bug, I made the change to actually produce a failure and
forgot to remove it. Tx for spotting it.

https://codereview.appspot.com/94330043/diff/20001/cmd/plugins/juju-restore/restore.go#newcode316
cmd/plugins/juju-restore/restore.go:316: paddr, err :=
conn.State.Client().PrivateAddress("0")
On 2014/05/12 12:59:53, jameinel wrote:
> I really think we should be grabbing the Client() as a variable and
using it
> repeatedly, rather than re-instantiating it for each call.

Done.

https://codereview.appspot.com/94330043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmd/plugins/juju-backup/juju-backup'
2--- cmd/plugins/juju-backup/juju-backup 2014-04-23 15:10:58 +0000
3+++ cmd/plugins/juju-backup/juju-backup 2014-05-12 16:40:42 +0000
4@@ -85,6 +85,9 @@
5 $LIBJUJU/agents/machine-* \
6 $LIBJUJU/tools \
7 $LIBJUJU/server.pem \
8+ $LIBJUJU/system-identity \
9+ $LIBJUJU/nonce.txt \
10+ $LIBJUJU/shared-secret \
11 ~/.ssh/authorized_keys \
12 /etc/rsyslog.d/*juju.conf \
13 /var/log/juju/all-machines.log \
14
15=== modified file 'cmd/plugins/juju-restore/restore.go'
16--- cmd/plugins/juju-restore/restore.go 2014-05-09 13:24:50 +0000
17+++ cmd/plugins/juju-restore/restore.go 2014-05-12 16:40:42 +0000
18@@ -103,42 +103,89 @@
19 }
20
21 var updateBootstrapMachineTemplate = mustParseTemplate(`
22- set -e -x
23+ set -exu
24+
25+ export LC_ALL=C
26 tar xzf juju-backup.tgz
27 test -d juju-backup
28-
29+ apt-get --option=Dpkg::Options::=--force-confold --option=Dpkg::options::=--force-unsafe-io --assume-yes --quiet install mongodb-clients
30+
31 initctl stop jujud-machine-0
32
33 initctl stop juju-db
34- rm -r /var/lib/juju /var/log/juju
35+ rm -r /var/lib/juju
36+ rm -r /var/log/juju
37+
38 tar -C / -xvp -f juju-backup/root.tar
39 mkdir -p /var/lib/juju/db
40- export LC_ALL=C
41- mongorestore --drop --dbpath /var/lib/juju/db juju-backup/dump
42+
43+ # Prefer jujud-mongodb binaries if available
44+ export MONGORESTORE=mongorestore
45+ if [ -f /usr/lib/juju/bin/mongorestore ]; then
46+ export MONGORESTORE=/usr/lib/juju/bin/mongorestore;
47+ fi
48+ $MONGORESTORE --drop --dbpath /var/lib/juju/db juju-backup/dump
49+
50 initctl start juju-db
51
52+ mongoAdminEval() {
53+ mongo --ssl -u admin -p {{.Creds.OldPassword | shquote}} localhost:37017/admin --eval "$1"
54+ }
55+
56+
57 mongoEval() {
58 mongo --ssl -u {{.Creds.Tag}} -p {{.Creds.Password | shquote}} localhost:37017/juju --eval "$1"
59 }
60+
61 # wait for mongo to come up after starting the juju-db upstart service.
62 for i in $(seq 1 100)
63 do
64 mongoEval ' ' && break
65 sleep 5
66 done
67+
68 mongoEval '
69 db = db.getSiblingDB("juju")
70- db.machines.update({_id: "0"}, {$set: {instanceid: '{{.NewInstanceId | printf "%q" | shquote}}' } })
71- db.instanceData.update({_id: "0"}, {$set: {instanceid: '{{.NewInstanceId | printf "%q"| shquote}}' } })
72- '
73+ db.machines.update({_id: "0"}, {$set: {instanceid: {{.NewInstanceId | printf "%q" }} } })
74+ db.instanceData.update({_id: "0"}, {$set: {instanceid: {{.NewInstanceId | printf "%q" }} } })
75+ '
76+
77+ # Create a new replicaSet conf and re initiate it
78+ mongoAdminEval '
79+ conf = { "_id" : "juju", "version" : 1, "members" : [ { "_id" : 1, "host" : "{{ .PrivateAddress | printf "%s:37017" }}" , "tags" : { "juju-machine-id" : "0" } }]}
80+ rs.initiate(conf)
81+ '
82+
83+ # Give time to replset to initiate
84+ for i in $(seq 1 20)
85+ do
86+ mongoEval ' ' && break
87+ sleep 5
88+ done
89+
90+ initctl stop juju-db
91+
92+ # Update the agent.conf for machine-0 with the new addresses
93+ cd /var/lib/juju/agents
94+ sed -i.old -r -e "/^(stateaddresses):/{
95+ n
96+ s/- .*(:[0-9]+)/- {{.Address}}\1/
97+ }" -e "/^(apiaddresses):/{
98+ n
99+ s/- .*(:[0-9]+)/- {{.PrivateAddress}}\1/
100+ }" machine-0/agent.conf
101+
102+ initctl start juju-db
103 initctl start jujud-machine-0
104 `)
105
106-func updateBootstrapMachineScript(instanceId instance.Id, creds credentials) string {
107+func updateBootstrapMachineScript(instanceId instance.Id, creds credentials, addr, paddr string) string {
108 return execTemplate(updateBootstrapMachineTemplate, struct {
109- NewInstanceId instance.Id
110- Creds credentials
111- }{instanceId, creds})
112+ NewInstanceId instance.Id
113+ Creds credentials
114+ Address string
115+ PrivateAddress string
116+ }{instanceId, creds, addr, paddr})
117 }
118
119 func (c *restoreCommand) Run(ctx *cmd.Context) error {
120@@ -261,11 +308,16 @@
121 }
122
123 func restoreBootstrapMachine(conn *juju.APIConn, backupFile string, creds credentials) (newInstId instance.Id, addr string, err error) {
124- addr, err = conn.State.Client().PublicAddress("0")
125+ client := conn.State.Client()
126+ addr, err = client.PublicAddress("0")
127 if err != nil {
128 return "", "", fmt.Errorf("cannot get public address of bootstrap machine: %v", err)
129 }
130- status, err := conn.State.Client().Status(nil)
131+ paddr, err := client.PrivateAddress("0")
132+ if err != nil {
133+ return "", "", fmt.Errorf("cannot get private address of bootstrap machine: %v", err)
134+ }
135+ status, err := client.Status(nil)
136 if err != nil {
137 return "", "", fmt.Errorf("cannot get environment status: %v", err)
138 }
139@@ -280,15 +332,16 @@
140 return "", "", fmt.Errorf("cannot copy backup file to bootstrap instance: %v", err)
141 }
142 progress("updating bootstrap machine")
143- if err := runViaSsh(addr, updateBootstrapMachineScript(newInstId, creds)); err != nil {
144+ if err := runViaSsh(addr, updateBootstrapMachineScript(newInstId, creds, addr, paddr)); err != nil {
145 return "", "", fmt.Errorf("update script failed: %v", err)
146 }
147 return newInstId, addr, nil
148 }
149
150 type credentials struct {
151- Tag string
152- Password string
153+ Tag string
154+ Password string
155+ OldPassword string
156 }
157
158 func extractCreds(backupFile string) (credentials, error) {
159@@ -326,9 +379,15 @@
160 if !ok || password == "" {
161 return credentials{}, fmt.Errorf("agent password not found in configuration")
162 }
163+ oldPassword, ok := m["oldpassword"].(string)
164+ if !ok || oldPassword == "" {
165+ return credentials{}, fmt.Errorf("agent old password not found in configuration")
166+ }
167+
168 return credentials{
169- Tag: "machine-0",
170- Password: password,
171+ Tag: "machine-0",
172+ Password: password,
173+ OldPassword: oldPassword,
174 }, nil
175 }
176
177@@ -356,14 +415,14 @@
178 s/- .*(:[0-9]+)/- {{.Address}}\1/
179 }" $agent/agent.conf
180
181- # If we're processing a unit agent's directly
182- # and it has some relations, reset
183- # the stored version of all of them to
184- # ensure that any relation hooks will
185- # fire.
186+ # If we're processing a unit agent's directly
187+ # and it has some relations, reset
188+ # the stored version of all of them to
189+ # ensure that any relation hooks will
190+ # fire.
191 if [[ $agent = unit-* ]]
192 then
193- find $agent/state/relations -type f -exec sed -i -r 's/change-version: [0-9]+$/change-version: 0/' {} \;
194+ find $agent/state/relations -type f -exec sed -i -r 's/change-version: [0-9]+$/change-version: 0/' {} \;
195 fi
196 initctl start jujud-$agent
197 done

Subscribers

People subscribed via source and target branches

to status/vote changes: