blob: 1e6abe316e35e0ad2ad74df4c24cfb03c47f2ca3 [file] [log] [blame]
Keun Soo Yimb293fdb2016-09-21 16:03:44 -07001#!/usr/bin/env python
2#
3# Copyright 2016 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070016"""Kernel Swapper.
17
18This class manages swapping kernel images for a Cloud Android instance.
19"""
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070020import subprocess
21
Sam Chiu7de3b232018-12-06 19:45:52 +080022from acloud import errors
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070023from acloud.public import report
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070024from acloud.internal.lib import android_compute_client
25from acloud.internal.lib import auth
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070026from acloud.internal.lib import utils
27
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070028# ssh flags used to communicate with the Cloud Android instance.
29SSH_FLAGS = [
30 '-q', '-o UserKnownHostsFile=/dev/null', '-o "StrictHostKeyChecking no"',
31 '-o ServerAliveInterval=10'
32]
33
34# Shell commands run on target.
35MOUNT_CMD = ('if mountpoint -q /boot ; then umount /boot ; fi ; '
36 'mount -t ext4 /dev/block/sda1 /boot')
37REBOOT_CMD = 'nohup reboot > /dev/null 2>&1 &'
38
39
40class KernelSwapper(object):
41 """A class that manages swapping a kernel image on a Cloud Android instance.
42
43 Attributes:
44 _compute_client: AndroidCopmuteClient object, manages AVD.
cylan0d77ae12018-05-18 08:36:48 +000045 _instance_name: tring, name of Cloud Android Instance.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070046 _target_ip: string, IP address of Cloud Android instance.
47 _ssh_flags: string list, flags to be used with ssh and scp.
48 """
49
50 def __init__(self, cfg, instance_name):
51 """Initialize.
52
53 Args:
54 cfg: AcloudConfig object, used to create credentials.
55 instance_name: string, instance name.
56 """
Sam Chiu4d9bb4b2018-10-26 11:38:23 +080057 credentials = auth.CreateCredentials(cfg)
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070058 self._compute_client = android_compute_client.AndroidComputeClient(
59 cfg, credentials)
60 # Name of the Cloud Android instance.
61 self._instance_name = instance_name
62 # IP of the Cloud Android instance.
63 self._target_ip = self._compute_client.GetInstanceIP(instance_name)
64
65 def SwapKernel(self, local_kernel_image):
66 """Swaps the kernel image on target AVD with given kernel.
67
68 Mounts boot image containing the kernel image to the filesystem, then
69 overwrites that kernel image with a new kernel image, then reboots the
70 Cloud Android instance.
71
72 Args:
73 local_kernel_image: string, local path to a kernel image.
74
75 Returns:
76 A Report instance.
77 """
cylan0d77ae12018-05-18 08:36:48 +000078 reboot_image = report.Report(command='swap_kernel')
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070079 try:
80 self._ShellCmdOnTarget(MOUNT_CMD)
81 self.PushFile(local_kernel_image, '/boot')
82 self.RebootTarget()
83 except subprocess.CalledProcessError as e:
cylan0d77ae12018-05-18 08:36:48 +000084 reboot_image.AddError(str(e))
85 reboot_image.SetStatus(report.Status.FAIL)
86 return reboot_image
Kevin Chengb5963882018-05-09 00:06:27 -070087 except errors.DeviceBootError as e:
cylan0d77ae12018-05-18 08:36:48 +000088 reboot_image.AddError(str(e))
89 reboot_image.SetStatus(report.Status.BOOT_FAIL)
90 return reboot_image
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070091
cylan0d77ae12018-05-18 08:36:48 +000092 reboot_image.SetStatus(report.Status.SUCCESS)
93 return reboot_image
Keun Soo Yimb293fdb2016-09-21 16:03:44 -070094
95 def PushFile(self, src_path, dest_path):
96 """Pushes local file to target Cloud Android instance.
97
98 Args:
99 src_path: string, local path to file to be pushed.
100 dest_path: string, path on target where to push the file to.
101
102 Raises:
103 subprocess.CalledProcessError: see _ShellCmd.
104 """
105 cmd = 'scp %s %s root@%s:%s' % (' '.join(SSH_FLAGS), src_path,
106 self._target_ip, dest_path)
107 self._ShellCmd(cmd)
108
109 def RebootTarget(self):
110 """Reboots the target Cloud Android instance and waits for boot.
111
112 Raises:
113 subprocess.CalledProcessError: see _ShellCmd.
Kevin Chengb5963882018-05-09 00:06:27 -0700114 errors.DeviceBootError: if target fails to boot.
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700115 """
116 self._ShellCmdOnTarget(REBOOT_CMD)
117 self._compute_client.WaitForBoot(self._instance_name)
118
119 def _ShellCmdOnTarget(self, target_cmd):
120 """Runs a shell command on target Cloud Android instance.
121
122 Args:
123 target_cmd: string, shell command to be run on target.
124
125 Raises:
126 subprocess.CalledProcessError: see _ShellCmd.
127 """
128 ssh_cmd = 'ssh %s root@%s' % (' '.join(SSH_FLAGS), self._target_ip)
129 host_cmd = ' '.join([ssh_cmd, '"%s"' % target_cmd])
130 self._ShellCmd(host_cmd)
131
cylan0d77ae12018-05-18 08:36:48 +0000132 @staticmethod
133 def _ShellCmd(host_cmd):
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700134 """Runs a shell command on host device.
135
136 Args:
137 host_cmd: string, shell command to be run on host.
138
139 Raises:
140 subprocess.CalledProcessError: For any non-zero return code of
141 host_cmd.
142 """
Fang Dengf24be082018-02-10 10:09:55 -0800143 utils.Retry(
Sam Chiu4d9bb4b2018-10-26 11:38:23 +0800144 retry_checker=lambda e: isinstance(e, subprocess.CalledProcessError),
Fang Dengf24be082018-02-10 10:09:55 -0800145 max_retries=2,
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700146 functor=lambda cmd: subprocess.check_call(cmd, shell=True),
cylan0d77ae12018-05-18 08:36:48 +0000147 sleep_multiplier=0,
148 retry_backoff_factor=1,
Keun Soo Yimb293fdb2016-09-21 16:03:44 -0700149 cmd=host_cmd)