Skip to content

Commit 1d8c327

Browse files
committed
Fix potential cases of uninitialized variables.
While addressing undeclared variable in 'cloud-init status', I also fixed the errors raised by automated code reviews against cloud-init master at https://lgtm.com/projects/g/cloud-init/cloud-init/alerts The following items are addressed:  * Fix 'cloud-init status':     * Only report 'running' state when any stage in /run/cloud-init/status.json has a start time but no finished time. Default start time to 0 if null.     * undeclared variable 'reason' now reports 'Cloud-init enabled by systemd cloud-init-generator' when systemd enables cloud-init  * cc_rh_subscription.py util.subp return values aren't set during if an exception is raised, use ProcessExecution as e instead.  * distros/freebsd.py:    * Drop repetitive looping over ipv4 and ipv6 nic lists.    * Initialize bsddev to 'NOTFOUND' in the event that no devs are discovered    * declare nics_with_addresses = set() in broader scope outside check_downable conditional  * cloudinit/util.py: Raise TypeError if mtype parameter isn't string, iterable or None. LP: #1744796
1 parent bc84f50 commit 1d8c327

File tree

6 files changed

+33
-16
lines changed

6 files changed

+33
-16
lines changed

cloudinit/cmd/status.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ def _is_cloudinit_disabled(disable_file, paths):
9393
elif not os.path.exists(os.path.join(paths.run_dir, 'enabled')):
9494
is_disabled = True
9595
reason = 'Cloud-init disabled by cloud-init-generator'
96+
else:
97+
reason = 'Cloud-init enabled by systemd cloud-init-generator'
9698
return (is_disabled, reason)
9799

98100

@@ -127,10 +129,11 @@ def _get_status_details(paths):
127129
status_detail = value
128130
elif isinstance(value, dict):
129131
errors.extend(value.get('errors', []))
132+
start = value.get('start') or 0
130133
finished = value.get('finished') or 0
131-
if finished == 0:
134+
if finished == 0 and start != 0:
132135
status = STATUS_RUNNING
133-
event_time = max(value.get('start', 0), finished)
136+
event_time = max(start, finished)
134137
if event_time > latest_event:
135138
latest_event = event_time
136139
if errors:

cloudinit/cmd/tests/test_status.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ def test__is_cloudinit_disabled_true_when_generator_disables(self):
9393
self.assertTrue(is_disabled, 'expected disabled cloud-init')
9494
self.assertEqual('Cloud-init disabled by cloud-init-generator', reason)
9595

96+
def test__is_cloudinit_disabled_false_when_enabled_in_systemd(self):
97+
'''Report enabled when systemd generator creates the enabled file.'''
98+
enabled_file = os.path.join(self.paths.run_dir, 'enabled')
99+
write_file(enabled_file, '')
100+
(is_disabled, reason) = wrap_and_call(
101+
'cloudinit.cmd.status',
102+
{'uses_systemd': True,
103+
'get_cmdline': 'something ignored'},
104+
status._is_cloudinit_disabled, self.disable_file, self.paths)
105+
self.assertFalse(is_disabled, 'expected enabled cloud-init')
106+
self.assertEqual(
107+
'Cloud-init enabled by systemd cloud-init-generator', reason)
108+
96109
def test_status_returns_not_run(self):
97110
'''When status.json does not exist yet, return 'not run'.'''
98111
self.assertFalse(
@@ -137,8 +150,9 @@ def fakeexists(filepath):
137150
self.assertEqual(expected, m_stdout.getvalue())
138151

139152
def test_status_returns_running(self):
140-
'''Report running when status file exists but isn't finished.'''
141-
write_json(self.status_file, {'v1': {'init': {'finished': None}}})
153+
'''Report running when status exists with an unfinished stage.'''
154+
write_json(self.status_file,
155+
{'v1': {'init': {'start': 1, 'finished': None}}})
142156
cmdargs = myargs(long=False, wait=False)
143157
with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
144158
retcode = wrap_and_call(
@@ -338,7 +352,8 @@ def fake_sleep(interval):
338352

339353
def test_status_main(self):
340354
'''status.main can be run as a standalone script.'''
341-
write_json(self.status_file, {'v1': {'init': {'finished': None}}})
355+
write_json(self.status_file,
356+
{'v1': {'init': {'start': 1, 'finished': None}}})
342357
with self.assertRaises(SystemExit) as context_manager:
343358
with mock.patch('sys.stdout', new_callable=StringIO) as m_stdout:
344359
wrap_and_call(

cloudinit/config/cc_power_state_change.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ def doexit(sysexit):
194194

195195

196196
def execmd(exe_args, output=None, data_in=None):
197+
ret = 1
197198
try:
198199
proc = subprocess.Popen(exe_args, stdin=subprocess.PIPE,
199200
stdout=output, stderr=subprocess.STDOUT)

cloudinit/config/cc_rh_subscription.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,8 @@ def _set_auto_attach(self):
276276
cmd = ['attach', '--auto']
277277
try:
278278
return_out, return_err = self._sub_man_cli(cmd)
279-
except util.ProcessExecutionError:
280-
self.log_warn("Auto-attach failed with: "
281-
"{0}]".format(return_err.strip()))
279+
except util.ProcessExecutionError as e:
280+
self.log_warn("Auto-attach failed with: {0}".format(e))
282281
return False
283282
for line in return_out.split("\n"):
284283
if line is not "":

cloudinit/distros/freebsd.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def getnetifname(self, dev):
116116
(out, err) = util.subp(['ifconfig', '-a'])
117117
ifconfigoutput = [x for x in (out.strip()).splitlines()
118118
if len(x.split()) > 0]
119+
bsddev = 'NOT_FOUND'
119120
for line in ifconfigoutput:
120121
m = re.match('^\w+', line)
121122
if m:
@@ -347,15 +348,9 @@ def _get_current_rename_info(self, check_downable=True):
347348
bymac[Distro.get_interface_mac(n)] = {
348349
'name': n, 'up': self.is_up(n), 'downable': None}
349350

351+
nics_with_addresses = set()
350352
if check_downable:
351-
nics_with_addresses = set()
352-
ipv6 = self.get_ipv6()
353-
ipv4 = self.get_ipv4()
354-
for bytes_out in (ipv6, ipv4):
355-
for i in ipv6:
356-
nics_with_addresses.update(i)
357-
for i in ipv4:
358-
nics_with_addresses.update(i)
353+
nics_with_addresses = set(self.get_ipv4() + self.get_ipv6())
359354

360355
for d in bymac.values():
361356
d['downable'] = (d['up'] is False or

cloudinit/util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,10 @@ def mount_cb(device, callback, data=None, rw=False, mtype=None, sync=True):
15871587
mtypes = list(mtype)
15881588
elif mtype is None:
15891589
mtypes = None
1590+
else:
1591+
raise TypeError(
1592+
'Unsupported type provided for mtype parameter: {_type}'.format(
1593+
_type=type(mtype)))
15901594

15911595
# clean up 'mtype' input a bit based on platform.
15921596
platsys = platform.system().lower()

0 commit comments

Comments
 (0)