Merge ~dmulford/cloud-init:add-null-check into cloud-init:master

Proposed by David Mulford
Status: Superseded
Proposed branch: ~dmulford/cloud-init:add-null-check
Merge into: cloud-init:master
Diff against target: 168 lines (+43/-18)
2 files modified
cloudinit/config/cc_rh_subscription.py (+28/-18)
tests/unittests/test_rh_subscription.py (+15/-0)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Scott Moser Needs Information
Review via email: mp+332057@code.launchpad.net

This proposal has been superseded by a proposal from 2017-11-06.

Commit message

rh_subscription: perform null checks for enabled and disabled repos.

The rh_subscription module doesn't perform null checks when attempting to
iterate on the enabled and disable repos arrays. When only one is
specified, cloud-init fails to run.

Description of the change

The rh_subscription module doesn't perform null checks when attempting to iterate on the enabled and disable repos arrays. When only one is specified, cloud-init fails to run.

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

see comment inline.

review: Needs Information
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:85e01c57e6776a684cb257dea3826191ffbaac77
https://jenkins.ubuntu.com/server/job/cloud-init-ci/397/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/397/rebuild

review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

i put a few chagnes up in a branch of mine (based off yours)
 at
 https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+ref/fix/rh-subscription-add-null-check

see what you think and please test.

the logging changes aren't strictly necessary, but it was annoying that the SubscriptionManager didn't have a 'log' attribute unless the caller just set one.

Revision history for this message
Scott Moser (smoser) wrote :

Hi David,
Were you able to look at my branch at all?

Could you integrate my suggestions into your branch?

Thanks.

Scott

Revision history for this message
David Mulford (dmulford) wrote :

Hi Scott,

Thanks for the nudge. I'm looking at this today.

I hope to have an answer for you tomorrow.

Thanks!
Dave

~dmulford/cloud-init:add-null-check updated
a9294ce... by David Mulford

Integrated Scott Moser's proposed changes

Unmerged commits

a9294ce... by David Mulford

Integrated Scott Moser's proposed changes

85e01c5... by David Mulford

Fixed object identity check to 'is not' to pass the flake8 checks

1262f85... by David Mulford

Added null checks rh_subscription module to avoid needing to specify both enabled and disabled repos

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py
2index 7f36cf8..a9d21e7 100644
3--- a/cloudinit/config/cc_rh_subscription.py
4+++ b/cloudinit/config/cc_rh_subscription.py
5@@ -38,14 +38,16 @@ Subscription`` example config.
6 server-hostname: <hostname>
7 """
8
9+from cloudinit import log as logging
10 from cloudinit import util
11
12+LOG = logging.getLogger(__name__)
13+
14 distros = ['fedora', 'rhel']
15
16
17 def handle(name, cfg, _cloud, log, _args):
18- sm = SubscriptionManager(cfg)
19- sm.log = log
20+ sm = SubscriptionManager(cfg, log=log)
21 if not sm.is_configured():
22 log.debug("%s: module not configured.", name)
23 return None
24@@ -86,10 +88,9 @@ def handle(name, cfg, _cloud, log, _args):
25 if not return_stat:
26 raise SubscriptionError("Unable to attach pools {0}"
27 .format(sm.pools))
28- if (sm.enable_repo is not None) or (sm.disable_repo is not None):
29- return_stat = sm.update_repos(sm.enable_repo, sm.disable_repo)
30- if not return_stat:
31- raise SubscriptionError("Unable to add or remove repos")
32+ return_stat = sm.update_repos()
33+ if not return_stat:
34+ raise SubscriptionError("Unable to add or remove repos")
35 sm.log_success("rh_subscription plugin completed successfully")
36 except SubscriptionError as e:
37 sm.log_warn(str(e))
38@@ -108,7 +109,10 @@ class SubscriptionManager(object):
39 'rhsm-baseurl', 'server-hostname',
40 'auto-attach', 'service-level']
41
42- def __init__(self, cfg):
43+ def __init__(self, cfg, log=None):
44+ if log is None:
45+ log = LOG
46+ self.log = log
47 self.cfg = cfg
48 self.rhel_cfg = self.cfg.get('rh_subscription', {})
49 self.rhsm_baseurl = self.rhel_cfg.get('rhsm-baseurl')
50@@ -130,7 +134,7 @@ class SubscriptionManager(object):
51
52 def log_warn(self, msg):
53 '''Simple wrapper for logging warning messages. Useful for unittests'''
54- self.log.warn(msg)
55+ self.log.warning(msg)
56
57 def _verify_keys(self):
58 '''
59@@ -245,7 +249,7 @@ class SubscriptionManager(object):
60 return False
61
62 reg_id = return_out.split("ID: ")[1].rstrip()
63- self.log.debug("Registered successfully with ID {0}".format(reg_id))
64+ self.log.debug("Registered successfully with ID %s", reg_id)
65 return True
66
67 def _set_service_level(self):
68@@ -347,7 +351,7 @@ class SubscriptionManager(object):
69 try:
70 self._sub_man_cli(cmd)
71 self.log.debug("Attached the following pools to your "
72- "system: %s" % (", ".join(pool_list))
73+ "system: %s", (", ".join(pool_list))
74 .replace('--pool=', ''))
75 return True
76 except util.ProcessExecutionError as e:
77@@ -355,18 +359,24 @@ class SubscriptionManager(object):
78 "due to {1}".format(pool, e))
79 return False
80
81- def update_repos(self, erepos, drepos):
82+ def update_repos(self):
83 '''
84 Takes a list of yum repo ids that need to be disabled or enabled; then
85 it verifies if they are already enabled or disabled and finally
86 executes the action to disable or enable
87 '''
88
89- if (erepos is not None) and (not isinstance(erepos, list)):
90+ erepos = self.enable_repo
91+ drepos = self.disable_repo
92+ if erepos is None:
93+ erepos = []
94+ if drepos is None:
95+ drepos = []
96+ if not isinstance(erepos, list):
97 self.log_warn("Repo IDs must in the format of a list.")
98 return False
99
100- if (drepos is not None) and (not isinstance(drepos, list)):
101+ if not isinstance(drepos, list):
102 self.log_warn("Repo IDs must in the format of a list.")
103 return False
104
105@@ -399,14 +409,14 @@ class SubscriptionManager(object):
106 for fail in enable_list_fail:
107 # Check if the repo exists or not
108 if fail in active_repos:
109- self.log.debug("Repo {0} is already enabled".format(fail))
110+ self.log.debug("Repo %s is already enabled", fail)
111 else:
112 self.log_warn("Repo {0} does not appear to "
113 "exist".format(fail))
114 if len(disable_list_fail) > 0:
115 for fail in disable_list_fail:
116- self.log.debug("Repo {0} not disabled "
117- "because it is not enabled".format(fail))
118+ self.log.debug("Repo %s not disabled "
119+ "because it is not enabled", fail)
120
121 cmd = ['repos']
122 if len(disable_list) > 0:
123@@ -422,10 +432,10 @@ class SubscriptionManager(object):
124 return False
125
126 if len(enable_list) > 0:
127- self.log.debug("Enabled the following repos: %s" %
128+ self.log.debug("Enabled the following repos: %s",
129 (", ".join(enable_list)).replace('--enable=', ''))
130 if len(disable_list) > 0:
131- self.log.debug("Disabled the following repos: %s" %
132+ self.log.debug("Disabled the following repos: %s",
133 (", ".join(disable_list)).replace('--disable=', ''))
134 return True
135
136diff --git a/tests/unittests/test_rh_subscription.py b/tests/unittests/test_rh_subscription.py
137index e9d5702..2271810 100644
138--- a/tests/unittests/test_rh_subscription.py
139+++ b/tests/unittests/test_rh_subscription.py
140@@ -2,6 +2,7 @@
141
142 """Tests for registering RHEL subscription via rh_subscription."""
143
144+import copy
145 import logging
146
147 from cloudinit.config import cc_rh_subscription
148@@ -68,6 +69,20 @@ class GoodTests(TestCase):
149 self.assertEqual(self.SM.log_success.call_count, 1)
150 self.assertEqual(self.SM._sub_man_cli.call_count, 2)
151
152+ @mock.patch.object(cc_rh_subscription.SubscriptionManager, "_getRepos")
153+ @mock.patch.object(cc_rh_subscription.SubscriptionManager, "_sub_man_cli")
154+ def test_update_repos_disable_with_none(self, m_sub_man_cli, m_get_repos):
155+ cfg = copy.deepcopy(self.config)
156+ m_get_repos.return_value = ([], ['repo1'])
157+ m_sub_man_cli.return_value = (b'', b'')
158+ cfg['rh_subscription'].update(
159+ {'enable-repo': ['repo1'], 'disable-repo': None})
160+ mysm = cc_rh_subscription.SubscriptionManager(cfg)
161+ self.assertEqual(True, mysm.update_repos())
162+ m_get_repos.assert_called_with()
163+ self.assertEqual(m_sub_man_cli.call_args_list,
164+ [mock.call(['repos', '--enable=repo1'])])
165+
166 def test_full_registration(self):
167 '''
168 Registration with auto-attach, service-level, adding pools,

Subscribers

People subscribed via source and target branches