Skip to content

Commit 05a38af

Browse files
authored
Merge pull request #141 from canonical/add_firmware_update_phase2
Add firmware_update phase
2 parents fad1598 + 5a55064 commit 05a38af

File tree

19 files changed

+429
-394
lines changed

19 files changed

+429
-394
lines changed

agent/testflinger_agent/agent.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,14 @@ def mark_device_offline(self):
120120

121121
def process_jobs(self):
122122
"""Coordinate checking for new jobs and handling them if they exists"""
123-
TEST_PHASES = ["setup", "provision", "test", "allocate", "reserve"]
123+
TEST_PHASES = [
124+
"setup",
125+
"provision",
126+
"firmware_update",
127+
"test",
128+
"allocate",
129+
"reserve",
130+
]
124131

125132
# First, see if we have any old results that we couldn't send last time
126133
self.retry_old_results()

agent/testflinger_agent/job.py

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ def run_test_phase(self, phase, rundir):
5959
if phase == "provision" and not self.job_data.get("provision_data"):
6060
logger.info("No provision_data defined in job data, skipping...")
6161
return 0
62+
if phase == "firmware_update" and not self.job_data.get(
63+
"firmware_update_data"
64+
):
65+
logger.info(
66+
"No firmware_update_data defined in job data, skipping..."
67+
)
68+
return 0
6269
if phase == "test" and not self.job_data.get("test_data"):
6370
logger.info("No test_data defined in job data, skipping...")
6471
return 0

agent/testflinger_agent/schema.py

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
voluptuous.Required("job_queues"): list,
3434
voluptuous.Required("setup_command", default=""): str,
3535
voluptuous.Required("provision_command", default=""): str,
36+
voluptuous.Required("firmware_update_command", default=""): str,
3637
voluptuous.Required("test_command", default=""): str,
3738
voluptuous.Required("allocate_command", default=""): str,
3839
voluptuous.Required("reserve_command", default=""): str,

device-connectors/src/testflinger_device_connectors/cmd.py

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def main():
3939
cmd_subparser = dev_subparser.add_subparsers()
4040
for cmd, func in (
4141
("provision", dev_module.provision),
42+
("firmware_update", dev_module.firmware_update),
4243
("runtest", dev_module.runtest),
4344
("allocate", dev_module.allocate),
4445
("reserve", dev_module.reserve),

device-connectors/src/testflinger_device_connectors/devices/__init__.py

+56
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import yaml
2727

2828
import testflinger_device_connectors
29+
from testflinger_device_connectors.fw_devices.firmware_update import (
30+
detect_device,
31+
)
2932

3033

3134
class ProvisioningError(Exception):
@@ -115,6 +118,59 @@ def stop(self):
115118

116119

117120
class DefaultDevice:
121+
def firmware_update(self, args):
122+
"""Default method for processing firmware update commands"""
123+
with open(args.config) as configfile:
124+
config = yaml.safe_load(configfile)
125+
testflinger_device_connectors.configure_logging(config)
126+
testflinger_device_connectors.logmsg(
127+
logging.INFO, "BEGIN firmware_update"
128+
)
129+
130+
test_opportunity = testflinger_device_connectors.get_test_opportunity(
131+
args.job_data
132+
)
133+
fw_config = test_opportunity.get("firmware_update_data")
134+
ignore_failure = fw_config.get("ignore_failure", False)
135+
version = fw_config.get("version")
136+
device_ip = config["device_ip"]
137+
target_device_username = "ubuntu"
138+
exitcode = 0
139+
supported_version = ["latest"]
140+
141+
if version not in supported_version:
142+
testflinger_device_connectors.logmsg(
143+
logging.INFO,
144+
"Fail to provide version in firmware_update_data. "
145+
+ "Current supported version: latest",
146+
)
147+
exitcode = 1
148+
else:
149+
try:
150+
target_device = detect_device(
151+
device_ip, target_device_username
152+
)
153+
target_device.get_fw_info()
154+
if version == "latest":
155+
reboot_required = target_device.upgrade()
156+
if reboot_required:
157+
target_device.reboot()
158+
update_succeeded = target_device.check_results()
159+
if not update_succeeded:
160+
exitcode = 1
161+
except Exception as e:
162+
testflinger_device_connectors.logmsg(
163+
logging.ERROR, f"Firmware Update failed: {str(e)}"
164+
)
165+
exitcode = 1
166+
finally:
167+
testflinger_device_connectors.logmsg(
168+
logging.INFO, "END firmware_update"
169+
)
170+
if ignore_failure:
171+
exitcode = 0
172+
return exitcode
173+
118174
def runtest(self, args):
119175
"""Default method for processing test commands"""
120176
with open(args.config) as configfile:

0 commit comments

Comments
 (0)