[autotest] Require lock reason to lock device
When locking a device, a locking reason now must be provided.
This applies to both adding a new device, and modifying an
existing device from both the web frontend and the atest
command-line tool.
BUG=chromium:336805
DEPLOY=migrate
TEST=Tested adding locked/unlocked devices and locking/unlocking devices
from both the web frontend and using the 'atest host ...' command-line tools.
Change-Id: I3a8cd8891a2999f026dd709ae8a79e2b8cbc251a
Reviewed-on: https://chromium-review.googlesource.com/267595
Tested-by: Matthew Sartori <[email protected]>
Reviewed-by: Dan Shi <[email protected]>
Commit-Queue: Matthew Sartori <[email protected]>
diff --git a/cli/host.py b/cli/host.py
index 53d572d..df82996 100644
--- a/cli/host.py
+++ b/cli/host.py
@@ -63,8 +63,12 @@
self.messages.append('Locked host')
elif options.unlock:
self.data['locked'] = False
+ self.data['lock_reason'] = ''
self.messages.append('Unlocked host')
+ if options.lock and options.lock_reason:
+ self.data['lock_reason'] = options.lock_reason
+
def _cleanup_labels(self, labels, platform=None):
"""Removes the platform label from the overall labels"""
@@ -196,7 +200,7 @@
self.print_list(results, key='hostname')
else:
keys = ['hostname', 'status',
- 'shard', 'locked', 'platform', 'labels']
+ 'shard', 'locked', 'lock_reason', 'platform', 'labels']
super(host_list, self).output(results, keys=keys)
@@ -240,7 +244,7 @@
self.print_fields(stats,
keys=['hostname', 'platform',
'status', 'locked', 'locked_by',
- 'lock_time', 'protection',])
+ 'lock_time', 'lock_reason', 'protection',])
self.print_by_ids(acls, 'ACLs', line_before=True)
labels = self._cleanup_labels(labels)
self.print_by_ids(labels, 'Labels', line_before=True)
@@ -325,6 +329,9 @@
self.parser.add_option('-u', '--unlock',
help='Unlock hosts',
action='store_true')
+ self.parser.add_option('-r', '--lock_reason',
+ help='Reason for locking hosts',
+ default='')
self.parser.add_option('-p', '--protection', type='choice',
help=('Set the protection level on a host. '
'Must be one of: %s' %
@@ -405,6 +412,9 @@
help='Create the hosts as '
'unlocked (default)',
action='store_true')
+ self.parser.add_option('-r', '--lock_reason',
+ help='Reason for locking hosts',
+ default='')
self.parser.add_option('-t', '--platform',
help='Sets the platform label')
self.parser.add_option('-b', '--labels',
@@ -449,8 +459,12 @@
def _execute_add_one_host(self, host):
# Always add the hosts as locked to avoid the host
- # being picked up by the scheduler before it's ACL'ed
+ # being picked up by the scheduler before it's ACL'ed.
+ # We enforce lock reasons for each lock, so we
+ # provide a 'dummy' if we are intending to unlock after.
self.data['locked'] = True
+ if not self.locked:
+ self.data['lock_reason'] = 'Forced lock on device creation'
self.execute_rpc('add_host', hostname=host,
status="Ready", **self.data)
@@ -473,7 +487,8 @@
if not self.locked:
for host in successful_hosts:
- self.execute_rpc('modify_host', id=host, locked=False)
+ self.execute_rpc('modify_host', id=host, locked=False,
+ lock_reason='')
return successful_hosts
diff --git a/cli/host_unittest.py b/cli/host_unittest.py
index a9bdd90..a8c6f98 100755
--- a/cli/host_unittest.py
+++ b/cli/host_unittest.py
@@ -123,6 +123,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [],
u'invalid': False,
u'synch_id': None,
@@ -134,6 +135,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -153,6 +155,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label0', u'label1'],
u'invalid': False,
u'synch_id': None,
@@ -164,6 +167,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -185,6 +189,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -209,6 +214,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -220,6 +226,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -245,6 +252,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -280,6 +288,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -291,6 +300,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'shard': None,
@@ -314,6 +324,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat0'],
u'invalid': False,
u'synch_id': None,
@@ -325,6 +336,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label2', u'plat2'],
u'invalid': False,
u'synch_id': None,
@@ -349,6 +361,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label2', u'label4',
u'plat1'],
u'invalid': False,
@@ -374,6 +387,7 @@
u'shard': None,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label2', u'label4',
u'plat1'],
u'invalid': 0,
@@ -409,6 +423,7 @@
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
u'labels': [u'label2', u'label3', u'plat1'],
+ u'lock_reason': u'',
u'invalid': False,
u'synch_id': None,
u'platform': u'plat1',
@@ -419,6 +434,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -453,6 +469,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -464,6 +481,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -488,6 +506,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -499,6 +518,7 @@
u'locked': True,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -547,6 +567,7 @@
u'hostname': u'host1',
u'locked': True,
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'lock_time': u'2008-07-23 12:54:15',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
@@ -558,6 +579,7 @@
u'hostname': u'host2',
u'locked': True,
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'lock_time': u'2008-07-23 12:54:15',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
@@ -581,6 +603,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label2', u'label3', u'plat1'],
u'invalid': False,
u'synch_id': None,
@@ -592,6 +615,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
u'shard': None,
@@ -616,6 +640,7 @@
u'locked': True,
u'lock_time': u'2008-07-23 12:54:15',
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'protection': 'No protection',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
@@ -631,6 +656,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'protection': u'No protection',
u'labels': [u'label0', u'plat0'],
u'invalid': False,
@@ -694,6 +720,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'protection': u'No protection',
u'labels': [u'label0', u'plat0'],
u'invalid': False,
@@ -745,6 +772,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'protection': u'No protection',
u'labels': [u'label0', u'plat0'],
u'invalid': False,
@@ -794,6 +822,7 @@
u'locked': True,
u'lock_time': u'2008-07-23 12:54:15',
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'protection': 'No protection',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
@@ -806,6 +835,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'protection': u'No protection',
u'labels': [u'label0', u'plat0'],
u'invalid': False,
@@ -866,6 +896,7 @@
u'locked': False,
u'locked_by': 'user0',
u'lock_time': u'2008-07-23 12:54:15',
+ u'lock_reason': u'',
u'protection': u'No protection',
u'labels': [u'label0', u'plat0'],
u'invalid': False,
@@ -880,6 +911,7 @@
u'locked': True,
u'lock_time': u'2008-07-23 12:54:15',
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'protection': 'No protection',
u'labels': [u'label3', u'label4', u'plat1'],
u'invalid': False,
@@ -891,6 +923,7 @@
u'hostname': u'host0',
u'locked': False,
u'locked_by': 'user0',
+ u'lock_reason': u'',
u'protection': 'No protection',
u'lock_time': u'2008-07-23 12:54:15',
u'labels': [u'label0', u'plat0'],
@@ -1264,9 +1297,11 @@
def test_execute_unlock_two_hosts(self):
self.run_cmd(argv=['atest', 'host', 'mod',
'-u', 'host0,host1', '--ignore_site_file'],
- rpcs=[('modify_host', {'id': 'host1', 'locked': False},
+ rpcs=[('modify_host', {'id': 'host1', 'locked': False,
+ 'lock_reason': ''},
True, None),
- ('modify_host', {'id': 'host0', 'locked': False},
+ ('modify_host', {'id': 'host0', 'locked': False,
+ 'lock_reason': ''},
True, None)],
out_words_ok=['Unlocked', 'host0', 'host1'])
@@ -1371,14 +1406,16 @@
True, 5),
('add_host', {'hostname': 'host1',
'status': 'Ready',
- 'locked': True},
+ 'locked': True,
+ 'lock_reason': 'Forced lock on device creation'},
True, 42),
('host_add_labels', {'id': 'host1',
'labels': ['label0']},
True, None),
('add_host', {'hostname': 'host0',
'status': 'Ready',
- 'locked': True},
+ 'locked': True,
+ 'lock_reason': 'Forced lock on device creation'},
True, 42),
('host_add_labels', {'id': 'host0',
'labels': ['label0']},
@@ -1386,9 +1423,11 @@
('acl_group_add_hosts',
{'id': 'acl0', 'hosts': ['host1', 'host0']},
True, None),
- ('modify_host', {'id': 'host1', 'locked': False},
+ ('modify_host', {'id': 'host1', 'locked': False,
+ 'lock_reason': ''},
True, None),
- ('modify_host', {'id': 'host0', 'locked': False},
+ ('modify_host', {'id': 'host0', 'locked': False,
+ 'lock_reason': ''},
True, None)],
out_words_ok=['host0', 'host1'])
@@ -1425,7 +1464,8 @@
True, 5),
('add_host', {'hostname': 'host1',
'status': 'Ready',
- 'locked': True},
+ 'locked': True,
+ 'lock_reason': 'Forced lock on device creation'},
True, 42),
('host_add_labels', {'id': 'host1',
'labels': ['label0', 'label,1',
@@ -1433,7 +1473,8 @@
True, None),
('add_host', {'hostname': 'host0',
'status': 'Ready',
- 'locked': True},
+ 'locked': True,
+ 'lock_reason': 'Forced lock on device creation'},
True, 42),
('host_add_labels', {'id': 'host0',
'labels': ['label0', 'label,1',
@@ -1442,9 +1483,11 @@
('acl_group_add_hosts',
{'id': 'acl0', 'hosts': ['host1', 'host0']},
True, None),
- ('modify_host', {'id': 'host1', 'locked': False},
+ ('modify_host', {'id': 'host1', 'locked': False,
+ 'lock_reason': ''},
True, None),
- ('modify_host', {'id': 'host0', 'locked': False},
+ ('modify_host', {'id': 'host0', 'locked': False,
+ 'lock_reason': ''},
True, None)],
out_words_ok=['host0', 'host1'])
diff --git a/cli/site_host.py b/cli/site_host.py
index a1853c9..c732ca5 100644
--- a/cli/site_host.py
+++ b/cli/site_host.py
@@ -31,7 +31,7 @@
@classmethod
def construct_without_parse(
cls, web_server, hosts, platform=None,
- locked=False, labels=[], acls=[],
+ locked=False, lock_reason='', labels=[], acls=[],
protection=host_protections.Protection.NO_PROTECTION):
"""Construct an site_host_create object and fill in data from args.
@@ -44,6 +44,7 @@
@param hosts: A list of hostnames as strings.
@param platform: A string or None.
@param locked: A boolean.
+ @param lock_reason: A string.
@param labels: A list of labels as strings.
@param acls: A list of acls as strings.
@param protection: An enum defined in host_protections.
@@ -58,6 +59,8 @@
obj.hosts = hosts
obj.platform = platform
obj.locked = locked
+ if locked and lock_reason.strip():
+ obj.data['lock_reason'] = lock_reason.strip()
obj.labels = labels
obj.acls = acls
if protection:
@@ -69,6 +72,8 @@
# Always add the hosts as locked to avoid the host
# being picked up by the scheduler before it's ACL'ed.
self.data['locked'] = True
+ if not self.locked:
+ self.data['lock_reason'] = 'Forced lock on device creation'
self.execute_rpc('add_host', hostname=host,
status="Ready", **self.data)
# If there are labels avaliable for host, use them.
diff --git a/cli/topic_common.py b/cli/topic_common.py
index b191e6c..7762a75 100644
--- a/cli/topic_common.py
+++ b/cli/topic_common.py
@@ -74,6 +74,7 @@
'locked': 'Locked',
'locked_by': 'Locked by',
'lock_time': 'Locked time',
+ 'lock_reason': 'Lock Reason',
'labels': 'Labels',
'description': 'Description',
'hosts': 'Hosts',