Merge lp:~doanac/utah/uuid_check_rsyslog into lp:utah

Proposed by Andy Doan
Status: Merged
Approved by: Javier Collado
Approved revision: 892
Merged at revision: 913
Proposed branch: lp:~doanac/utah/uuid_check_rsyslog
Merge into: lp:utah
Diff against target: 350 lines (+89/-37) (has conflicts)
8 files modified
templates/install-commands.jinja2 (+23/-0)
tests/test_rsyslog.py (+34/-11)
utah/config.py (+4/-7)
utah/provisioning/baremetal/bamboofeeder.py (+1/-1)
utah/provisioning/baremetal/cobbler.py (+1/-1)
utah/provisioning/provisioning.py (+0/-12)
utah/provisioning/rsyslog.py (+25/-4)
utah/provisioning/vm.py (+1/-1)
Text conflict in utah/provisioning/rsyslog.py
To merge this branch: bzr merge lp:~doanac/utah/uuid_check_rsyslog
Reviewer Review Type Date Requested Status
Andy Doan (community) Needs Resubmitting
Review via email: mp+162423@code.launchpad.net

Description of the change

get the uuid from rsyslog at system boot rather than using ssh.

To post a comment you must log in.
Revision history for this message
Max Brustkern (nuclearbob) wrote :

I've read that $() is better than `` for portability, but we do appear to be using `` in other spots in the code, so it's obviously not breaking anything right now.

I have two more substantive concerns. Are we going to receive a UUID on systems where the wait_for_booted isn't working? Is it safe to change the incorrect uuid behavior from an Exception to logging an error? The intent of this check is to ensure we're actually running on the system we installed, and I don't think logging an error and then continuing the test is necessarily an appropriate response. We could consider doing a retry, but I think continuing is a problem.

Revision history for this message
Javier Collado (javier.collado) wrote :

Line 228 in the diff will conflict with:
https://code.launchpad.net/~javier.collado/utah/bug1176076/+merge/162382

In this merge proposal 'match.string' is used while 'pattern' is used in mine.

Any of them is probably fine, but I think 'pattern' is slightly better because the error message says "matched future pattern" instead of something like "matched text". Anyway, I think that change should be removed from this merge request since it's already included in the other one. Do you agree on this?

Aside from this, it isn't completely clear to me what the 'uuid: True' line in the configuration file does. Maybe and explanation about it should be added to the docstring in wait_for_install where an example of valid steps is provided.

Revision history for this message
Andy Doan (doanac) wrote :

On 05/03/2013 10:29 AM, Max Brustkern wrote:

> I have two more substantive concerns. Are we going to receive a UUID
> on systems where the wait_for_booted isn't working?

no

> Is it safe to
> change the incorrect uuid behavior from an Exception to logging an
> error? The intent of this check is to ensure we're actually running
> on the system we installed, and I don't think logging an error and
> then continuing the test is necessarily an appropriate response. We
> could consider doing a retry, but I think continuing is a problem.

so - I'm probably downplaying the importance of the UUID here.
Originally I liked this better but this is probably worth debate.

The *real* reason I shuffled this around is because this need to make an
SSH connection to the target after install gets in the way of doing an
autostart of UTAH from rc.local. So if we make a retry type thing here,
its still going to be a problem for my next planned patchset.

Revision history for this message
Andy Doan (doanac) wrote :

On 05/03/2013 10:30 AM, Javier Collado wrote:
> Any of them is probably fine, but I think 'pattern' is slightly better because the error message says "matched future pattern" instead of something like "matched text". Anyway, I think that change should be removed from this merge request since it's already included in the other one. Do you agree on this?

your way is better.

> Aside from this, it isn't completely clear to me what the 'uuid: True' line in the configuration file does. Maybe and explanation about it should be added to the docstring in wait_for_install where an example of valid steps is provided.

+1

lp:~doanac/utah/uuid_check_rsyslog updated
888. By Andy Doan

as per max's review

this raises an exception when UUID mismatches since its a provisioning
issue.

889. By Andy Doan

add a comment about uuid conf as per javier

890. By Andy Doan

improve timeout logic with regards to future_patterns

The future pattern logic works correctly. However, it hinges on the
pattern being hit within the limits of the previous timeout interval.
This change adds up the future timeouts and makes us wait that whole
duration so we can properly detect future messages. This happens most
often on the wait_for_booted logic.

891. By Andy Doan

wait for network before running install commands

in the case of this running during the installer, nothing will change.
in the case of booting an image and running from rc.local, we should
be safer now and always get the rsyslog messages.

This seems to fix the issues we had with wait_for_booted not always
working.

Revision history for this message
Andy Doan (doanac) wrote :

I think this fixes the main issues.

verified with saucy server/desktop

revno 891 - is pretty big fix. This seems to ensure rc.local's rsyslog messages will make it to UTAH.
revno 890 - makes our wait_for timeout smarter by taking into account future pattern timeout values.

review: Needs Resubmitting
lp:~doanac/utah/uuid_check_rsyslog updated
892. By Andy Doan

restart rsyslog when network comes alive

I've seen an issue mostly with server images and rsyslog. The issue
is that rsyslog starts running before the network is up. It seems
to detect this and at some point stop trying to send things to the
remote syslog server (or at least waits a bit before trying again).
This is causing our first few syslog messages to not always show up,
and these messages are critical for UTAH to understand how things
are working.

This restarts rsyslogd after we know the network is up so that we
can reliably get these messages.

Revision history for this message
Andy Doan (doanac) wrote :

This branch is stable now and has been tested most of the week. revno 892 seems to be the magic commit that makes things reliable.

review: Needs Resubmitting
Revision history for this message
Max Brustkern (nuclearbob) wrote :

If rsyslog is now reliable enough for the uuid check, we should remove the workaround to log a warning instead of timing out during wait_for_booted. I think in the current code, a timeout would issue a warning and then possibly cause the system to proceed with no uuid check occurring.

Revision history for this message
Javier Collado (javier.collado) wrote :

I've tested with a desktop i386 image and the pass runlist and it worked fine.
However, I have the feeling that there's some duplication in the code that is a
little bit confusing. In particular, I've seen that the machine UUID is written
twice to the syslog file.

The reason for this is that the commands in `install-commands.jinja2` are
written both to the late command script and also to `/etc/rc.local`. Given that
UUID is expected to be captured during the boot sequence, I believe it should
only be in `/etc/rc.local`, not in the late command script.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Maybe we should move the install commands into rc.local only? I think we've been discussing relying less on the preseed for a while.

Revision history for this message
Andy Doan (doanac) wrote :

On 05/16/2013 10:35 AM, Max Brustkern wrote:
> If rsyslog is now reliable enough for the uuid check, we should remove the workaround to log a warning instead of timing out during wait_for_booted. I think in the current code, a timeout would issue a warning and then possibly cause the system to proceed with no uuid check occurring.

I *think* it probably is, but I was kind of wanting to see this in wild
first ie in 0.13 and then make that an error for 0.14 just to be safe.

Revision history for this message
Andy Doan (doanac) wrote :

On 05/16/2013 11:15 AM, Javier Collado wrote:
> I've tested with a desktop i386 image and the pass runlist and it worked fine.
> However, I have the feeling that there's some duplication in the code that is a
> little bit confusing. In particular, I've seen that the machine UUID is written
> twice to the syslog file.
>
> The reason for this is that the commands in `install-commands.jinja2` are
> written both to the late command script and also to `/etc/rc.local`. Given that
> UUID is expected to be captured during the boot sequence, I believe it should
> only be in `/etc/rc.local`, not in the late command script.

I think sending it twice is harmless. I have another branch that's
dependent on this that does some more refactoring around this area that
might be a better place to address.

On 05/16/2013 01:33 PM, Max Brustkern wrote:
 > Maybe we should move the install commands into rc.local only? I
 > think we've been discussing relying less on the preseed for a while.

I think this is what we should shoot for. I'm not totally sure we should
do it in this change though?

Revision history for this message
Max Brustkern (nuclearbob) wrote :

> On 05/16/2013 11:15 AM, Javier Collado wrote:
> > I've tested with a desktop i386 image and the pass runlist and it worked
> fine.
> > However, I have the feeling that there's some duplication in the code that
> is a
> > little bit confusing. In particular, I've seen that the machine UUID is
> written
> > twice to the syslog file.
> >
> > The reason for this is that the commands in `install-commands.jinja2` are
> > written both to the late command script and also to `/etc/rc.local`. Given
> that
> > UUID is expected to be captured during the boot sequence, I believe it
> should
> > only be in `/etc/rc.local`, not in the late command script.
>

I think you may be right about that being out of scope here, but I'm also worried about a temporary situation that's less reliable than where we were before and where we're going. Am I crazy for imagining a situation where some rogue preseed fakes us into thinking that the install is done in the latecommand, and then we check the uuid, declare it valid, and then reboot into a system that hasn't installed correctly? That seems pretty unlikely I guess.
> I think sending it twice is harmless. I have another branch that's
> dependent on this that does some more refactoring around this area that
> might be a better place to address.
>
> On 05/16/2013 01:33 PM, Max Brustkern wrote:
> > Maybe we should move the install commands into rc.local only? I
> > think we've been discussing relying less on the preseed for a while.
>
> I think this is what we should shoot for. I'm not totally sure we should
> do it in this change though?

Revision history for this message
Andy Doan (doanac) wrote :

On 05/16/2013 03:03 PM, Max Brustkern wrote:
> I think you may be right about that being out of scope here, but I'm
> also worried about a temporary situation that's less reliable than
> where we were before and where we're going.

sounds good

> Am I crazy for imagining
> a situation where some rogue preseed fakes us into thinking that the
> install is done in the latecommand, and then we check the uuid,
> declare it valid, and then reboot into a system that hasn't installed
> correctly?

I don't think this is possible. We only check for UUID in the
boot_steps, not the install_steps. So UUID is basically ignored if
printed during the install.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

> > Am I crazy for imagining
> > a situation where some rogue preseed fakes us into thinking that the
> > install is done in the latecommand, and then we check the uuid,
> > declare it valid, and then reboot into a system that hasn't installed
> > correctly?
>
> I don't think this is possible. We only check for UUID in the
> boot_steps, not the install_steps. So UUID is basically ignored if
> printed during the install.

That's what I'm trying to figure out: is there any way we could think the install is done before it is?

Revision history for this message
Andy Doan (doanac) wrote :

On 05/16/2013 03:17 PM, Max Brustkern wrote:
> That's what I'm trying to figure out: is there any way we could think the install is done before it is?

I don't see how.

Revision history for this message
Javier Collado (javier.collado) wrote :

> I don't see how.

I think I agree on this because of the separation of the install and boot
steps. Otherwise, it would be possible to match a pattern in the future for the
first uuid that is printed and consider that the boot up is done.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

Okay, we should be in good shape to merge, then.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'templates/install-commands.jinja2'
--- templates/install-commands.jinja2 2013-02-27 11:10:59 +0000
+++ templates/install-commands.jinja2 2013-05-10 15:36:27 +0000
@@ -7,6 +7,24 @@
7 {{ check_locks_command() | indent }}7 {{ check_locks_command() | indent }}
8}8}
99
10wait_for_net()
11{
12 log "waiting for network"
13 timeout 2m sh <<EOF
14 gw=""
15 while [ -z "\$gw" ] ; do
16 sleep 2
17 gw=\`ip route | grep default\`
18 done
19
20 # rsyslog may start skipping remote logging if it got too many
21 # messages to send before the network was up. This makes it
22 # start afresh and deliver our messages.
23 restart rsyslog
24 sleep 1
25EOF
26}
27
10install_package() {28install_package() {
11 package=$129 package=$1
12 check_locks30 check_locks
@@ -22,5 +40,10 @@
22 done40 done
23}41}
2442
43wait_for_net
25install_packages {{packages | join(' ')}}44install_packages {{packages | join(' ')}}
45
46# NOTE: do syslog at the end, so we do not try and start connecting via
47# ssh or running other stuff before the target is ready
48log "Machine UUID: `cat /etc/utah/uuid`"
26{%- endmacro %}49{%- endmacro %}
2750
=== modified file 'tests/test_rsyslog.py'
--- tests/test_rsyslog.py 2013-05-01 20:51:33 +0000
+++ tests/test_rsyslog.py 2013-05-10 15:36:27 +0000
@@ -18,15 +18,18 @@
1818
19import itertools19import itertools
20import logging20import logging
21import mock
21import socket22import socket
22import time23import time
23import tempfile24import tempfile
24import threading25import threading
25import unittest26import unittest
27import uuid
2628
27from mock import patch29from mock import patch
2830
29from utah.exceptions import UTAHException31from utah.exceptions import UTAHException
32from utah.provisioning.exceptions import UTAHProvisioningException
30from utah.provisioning.rsyslog import RSyslog33from utah.provisioning.rsyslog import RSyslog
31from utah.timeout import UTAHTimeout34from utah.timeout import UTAHTimeout
3235
@@ -109,7 +112,9 @@
109 {112 {
110 "message": "test_future",113 "message": "test_future",
111 "pattern": ".*log source = /proc/kmsg started",114 "pattern": ".*log source = /proc/kmsg started",
112 "timeout": 120,115 # set a really small timeout to prove we properly calculate
116 # future timeout logic
117 "timeout": 0.01,
113 "booted": True,118 "booted": True,
114 },119 },
115 {120 {
@@ -194,24 +199,39 @@
194 self.assertTrue(self.test_callbacks_booted, 'booted callback not made')199 self.assertTrue(self.test_callbacks_booted, 'booted callback not made')
195 self.assertTrue(self.test_callbacks_blah, 'blah callback not made')200 self.assertTrue(self.test_callbacks_blah, 'blah callback not made')
196201
197 def test_booted(self):202 @mock.patch('test_rsyslog.TestRsyslog.logger')
203 def test_booted(self, logger):
198 """Make sure wait_for_booted works."""204 """Make sure wait_for_booted works."""
205 tst_uuid = str(uuid.uuid4())
199 steps = [206 steps = [
200 {207 {
201 "message": "test booted",208 "message": "test booted",
202 "pattern": ".*log source = /proc/kmsg started",209 "pattern": ".*log source = /proc/kmsg started",
203 "timeout": 120,210 "timeout": 120,
204 },211 },
212 {
213 "message": "test uuid",
214 "uuid": True,
215 "pattern": '.*Machine UUID:\s+(.*)',
216 "timeout": 2,
217 },
205 ]218 ]
206219
207 messages = [220 messages = [
208 'test 1',221 'test 1',
209 '<13>Feb 20 13:38:55 host user: log source = /proc/kmsg started',222 '<13>Feb 20 13:38:55 host user: log source = /proc/kmsg started',
223 '<13>Feb 21 13:40:55 host user: Machine UUID: {}'.format(tst_uuid),
210 ]224 ]
211225
212 r = RSyslog("utah-test", '/tmp')226 r = RSyslog("utah-test", '/tmp')
213 threading.Thread(target=self.producer, args=(r.port, messages)).start()227 r.logger = logger
214 r.wait_for_booted(steps)228 threading.Thread(target=self.producer, args=(r.port, messages)).start()
229 r.wait_for_booted(steps, tst_uuid)
230 self.assertFalse(logger.error.called)
231
232 threading.Thread(target=self.producer, args=(r.port, messages)).start()
233 with self.assertRaises(UTAHProvisioningException):
234 r.wait_for_booted(steps, 'bad')
215235
216 def test_booted_workaround(self):236 def test_booted_workaround(self):
217 """Test that wait_for_booted doesn't raise an exception on timeout."""237 """Test that wait_for_booted doesn't raise an exception on timeout."""
@@ -225,7 +245,7 @@
225245
226 r = RSyslog("utah-test", '/tmp')246 r = RSyslog("utah-test", '/tmp')
227247
228 r.wait_for_booted(steps)248 r.wait_for_booted(steps, None)
229249
230 def usefile(self, truncate):250 def usefile(self, truncate):
231 """Make sure wait_for_booted works when tailing a file."""251 """Make sure wait_for_booted works when tailing a file."""
@@ -246,10 +266,12 @@
246266
247 with tempfile.NamedTemporaryFile() as f:267 with tempfile.NamedTemporaryFile() as f:
248 r = RSyslog("utah-test", '/tmp', f.name)268 r = RSyslog("utah-test", '/tmp', f.name)
249 threading.Thread(269 t = threading.Thread(
250 target=self.file_producer,270 target=self.file_producer,
251 args=(f, messages, truncate)).start()271 args=(f, messages, truncate))
252 r.wait_for_booted(steps)272 t.start()
273 r.wait_for_booted(steps, None)
274 t.join()
253275
254 def test_usefile(self):276 def test_usefile(self):
255 """Test tailing a file."""277 """Test tailing a file."""
@@ -270,18 +292,19 @@
270 {292 {
271 "message": "message_2",293 "message": "message_2",
272 "pattern": "pattern",294 "pattern": "pattern",
295 "timeout": 1,
273 },296 },
274 {297 {
275 "message": "message_3",298 "message": "message_3",
276 "pattern": "pattern",299 "pattern": "pattern",
300 "timeout": 1,
277 },301 },
278 ]302 ]
279303
280 messages = itertools.repeat('log example')304 messages = itertools.repeat('log example')
281 pattern = (r'Timeout \({}\) occurred for {} message.\n'305 pattern = (r'Timeout \(\d+\) occurred for {} message.\n'
282 r'Remaining messages: {}'306 r'Remaining messages: {}'
283 .format(steps[0]['timeout'],307 .format(steps[0]['message'],
284 steps[0]['message'],
285 ', '.join([step['message']308 ', '.join([step['message']
286 for step in steps[1:]])))309 for step in steps[1:]])))
287310
288311
=== modified file 'utah/config.py'
--- utah/config.py 2013-05-03 23:07:50 +0000
+++ utah/config.py 2013-05-10 15:36:27 +0000
@@ -228,14 +228,11 @@
228 'timeout': 180,228 'timeout': 180,
229 },229 },
230 {230 {
231 'message': 'network active',231 'message': 'UTAH uuid received',
232 'pattern': [232 'uuid': True, # binds this to the callback for wait_for_booted
233 '.*NetworkManager',233 'pattern': '.*Machine UUID:\s+(.*)',
234 '.*dhclient: bound to', # needed for minimal server installs
235 ],
236
237 'timeout': 180,234 'timeout': 180,
238 }235 },
239 ],236 ],
240)237)
241238
242239
=== modified file 'utah/provisioning/baremetal/bamboofeeder.py'
--- utah/provisioning/baremetal/bamboofeeder.py 2013-04-26 13:36:08 +0000
+++ utah/provisioning/baremetal/bamboofeeder.py 2013-05-10 15:36:27 +0000
@@ -276,7 +276,7 @@
276 self.logger.info('System installing')276 self.logger.info('System installing')
277277
278 self.rsyslog.wait_for_install(config.install_steps)278 self.rsyslog.wait_for_install(config.install_steps)
279 self.rsyslog.wait_for_booted(config.boot_steps)279 self.rsyslog.wait_for_booted(config.boot_steps, self.uuid)
280 retry(self.sshcheck, logmethod=self.logger.info,280 retry(self.sshcheck, logmethod=self.logger.info,
281 retry_timeout=config.checktimeout)281 retry_timeout=config.checktimeout)
282282
283283
=== modified file 'utah/provisioning/baremetal/cobbler.py'
--- utah/provisioning/baremetal/cobbler.py 2013-04-26 13:36:08 +0000
+++ utah/provisioning/baremetal/cobbler.py 2013-05-10 15:36:27 +0000
@@ -206,7 +206,7 @@
206 # ps-unity-autopilot-release-testing/140/label=autopilot-nvidia/206 # ps-unity-autopilot-release-testing/140/label=autopilot-nvidia/
207 # For now, it seems to be a problem on all installs, so we're going to207 # For now, it seems to be a problem on all installs, so we're going to
208 # handle it in rsyslog.py208 # handle it in rsyslog.py
209 self.rsyslog.wait_for_booted(config.boot_steps)209 self.rsyslog.wait_for_booted(config.boot_steps, self.uuid)
210210
211 retry(self.sshcheck, logmethod=self.logger.info,211 retry(self.sshcheck, logmethod=self.logger.info,
212 retry_timeout=config.checktimeout)212 retry_timeout=config.checktimeout)
213213
=== modified file 'utah/provisioning/provisioning.py'
--- utah/provisioning/provisioning.py 2013-05-03 23:08:37 +0000
+++ utah/provisioning/provisioning.py 2013-05-10 15:36:27 +0000
@@ -398,7 +398,6 @@
398 self.logger.debug('Failed to load machine: %s', str(err))398 self.logger.debug('Failed to load machine: %s', str(err))
399 self._create()399 self._create()
400 self.provisioned = True400 self.provisioned = True
401 self._uuid_check()
402401
403 def _create(self):402 def _create(self):
404 # TODO: discuss separation of this vs. start when separating Install403 # TODO: discuss separation of this vs. start when separating Install
@@ -590,17 +589,6 @@
590 if self.clean:589 if self.clean:
591 cleanup.add_command(cmd)590 cleanup.add_command(cmd)
592591
593 def _uuid_check(self):
594 """Check uuid to verify we've installed correctly."""
595 uuid_check_command = ('[ "{uuid}" == "$(cat /etc/utah/uuid)" ]'
596 .format(uuid=self.uuid))
597 if self.run(uuid_check_command)[0] != 0:
598 self.provisioned = False
599 raise UTAHProvisioningException(
600 'Installed UUID differs from Machine UUID; '
601 'installation probably failed. '
602 'Try rerunning install.')
603
604592
605class CustomInstallMixin(object):593class CustomInstallMixin(object):
606594
607595
=== modified file 'utah/provisioning/rsyslog.py'
--- utah/provisioning/rsyslog.py 2013-05-03 15:58:24 +0000
+++ utah/provisioning/rsyslog.py 2013-05-10 15:36:27 +0000
@@ -24,6 +24,7 @@
24import time24import time
2525
26from utah.exceptions import UTAHException26from utah.exceptions import UTAHException
27from utah.provisioning.exceptions import UTAHProvisioningException
27from utah.timeout import UTAHTimeout28from utah.timeout import UTAHTimeout
2829
2930
@@ -113,7 +114,7 @@
113 callbacks = {'booted': booted_callback}114 callbacks = {'booted': booted_callback}
114 self._wait_for_steps(steps, logfile, callbacks)115 self._wait_for_steps(steps, logfile, callbacks)
115116
116 def wait_for_booted(self, steps):117 def wait_for_booted(self, steps, uuid):
117 """Monitor rsyslog during boot up.118 """Monitor rsyslog during boot up.
118119
119 Works the same as the :meth:`wait_for_install` method but takes in120 Works the same as the :meth:`wait_for_install` method but takes in
@@ -122,16 +123,29 @@
122123
123 :param steps: Set of steps that the boot up will go through.124 :param steps: Set of steps that the boot up will go through.
124 :type steps: list(dict)125 :type steps: list(dict)
126 :param uuid: The UUID generated by provisioning code.
127 :type uuid: string
125128
126 .. seealso:: :meth:`wait_for_install`129 .. seealso:: :meth:`wait_for_install`
127130
128 """131 """
129 logfile = '{}/{}-boot.log'.format(self._logpath, self._host)132 logfile = '{}/{}-boot.log'.format(self._logpath, self._host)
130 callbacks = {}133
134 def _cb(match):
135 if match:
136 _cb.uuid = match.group(1).strip()
137
138 _cb.uuid = None
139 callbacks = {'uuid': _cb}
131 # TODO: Resolve the issues around this and get it back to normal140 # TODO: Resolve the issues around this and get it back to normal
132 # i.e. LP#1100386141 # i.e. LP#1100386
133 try:142 try:
134 self._wait_for_steps(steps, logfile, callbacks)143 self._wait_for_steps(steps, logfile, callbacks)
144 if not _cb.uuid:
145 self.logger.error('UUID not sent from target')
146 elif uuid and uuid != _cb.uuid:
147 msg = 'Incorrect UUID: {} != {}'.format(uuid, _cb.uuid)
148 raise UTAHProvisioningException(msg)
135 except UTAHTimeout:149 except UTAHTimeout:
136 self.logger.warning('Timed out waiting for boot, but continuing')150 self.logger.warning('Timed out waiting for boot, but continuing')
137151
@@ -149,9 +163,10 @@
149 if not isinstance(fail_pattern, list):163 if not isinstance(fail_pattern, list):
150 fail_pattern = [fail_pattern]164 fail_pattern = [fail_pattern]
151 pattern.extend(fail_pattern)165 pattern.extend(fail_pattern)
152 future_pats = self._future_patterns(steps, x)166 future_pats, future_timeout = self._future_patterns(steps, x)
153 pattern.extend(future_pats)167 pattern.extend(future_pats)
154 self.logger.info('Waiting %ds for: %s', timeout, message)168 self.logger.info('Waiting %ds for: %s', timeout, message)
169 timeout += future_timeout
155 pattern, match = self._wait_for(f, pattern, message, timeout)170 pattern, match = self._wait_for(f, pattern, message, timeout)
156 if match is None:171 if match is None:
157 remaining_messages = [step['message']172 remaining_messages = [step['message']
@@ -170,7 +185,11 @@
170 .format(pattern))185 .format(pattern))
171 if pattern in future_pats:186 if pattern in future_pats:
172 msg = 'Expected pattern missed, matched future pattern: %s'187 msg = 'Expected pattern missed, matched future pattern: %s'
188<<<<<<< TREE
173 self.logger.warn(msg, pattern)189 self.logger.warn(msg, pattern)
190=======
191 self.logger.warn(msg, match.string)
192>>>>>>> MERGE-SOURCE
174 x = self._fast_forward(steps, pattern, match, callbacks)193 x = self._fast_forward(steps, pattern, match, callbacks)
175 else:194 else:
176 self.logger.info('Matched pattern %r for %r message',195 self.logger.info('Matched pattern %r for %r message',
@@ -188,14 +207,16 @@
188 @staticmethod207 @staticmethod
189 def _future_patterns(steps, index):208 def _future_patterns(steps, index):
190 patterns = []209 patterns = []
210 timeout = 0
191 index += 1211 index += 1
192 for step in steps[index:]:212 for step in steps[index:]:
193 pattern = step['pattern']213 pattern = step['pattern']
214 timeout += step['timeout']
194 if not isinstance(pattern, list):215 if not isinstance(pattern, list):
195 patterns.append(pattern)216 patterns.append(pattern)
196 else:217 else:
197 patterns.extend(pattern)218 patterns.extend(pattern)
198 return patterns219 return patterns, timeout
199220
200 @staticmethod221 @staticmethod
201 def _fast_forward(steps, pattern, match, callbacks):222 def _fast_forward(steps, pattern, match, callbacks):
202223
=== modified file 'utah/provisioning/vm.py'
--- utah/provisioning/vm.py 2013-05-09 19:51:42 +0000
+++ utah/provisioning/vm.py 2013-05-10 15:36:27 +0000
@@ -546,7 +546,7 @@
546 else:546 else:
547 raise UTAHVMProvisioningException('Failed to provision VM')547 raise UTAHVMProvisioningException('Failed to provision VM')
548548
549 self.rsyslog.wait_for_booted(config.boot_steps)549 self.rsyslog.wait_for_booted(config.boot_steps, self.uuid)
550 try:550 try:
551 self.logger.info(551 self.logger.info(
552 'Waiting %d seconds for ping response', self.boottimeout)552 'Waiting %d seconds for ping response', self.boottimeout)

Subscribers

People subscribed via source and target branches

to all changes: