blob: 747d25312a692ffcfa02403dd5f31101e7df9195 [file] [log] [blame]
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A system module providing method to add start up jobs."""
import os
import factory_common # pylint: disable=unused-import
from cros.factory.device import types
from cros.factory.test.env import paths
class FactoryInit(types.DeviceComponent):
"""Provides method to add start up jobs using the factory framework.
The design is to apply the goofy startup flow used in most Chrome OS board.
In most Chrome OS board, ${FACTORY_ROOT}/init/startup is the entry point to
run all factory software after device boot. The script execs all executable
scripts under ${FACTORY_ROOT}/init/main.d and starts goofy.
Therefore, to add a start up job, we link scripts into the main.d directory,
and check if we have the startup script installed. If no, a stub startup
script is pushed to achive our goal.
For other boards, one can try to make a factory image that runs
${FACTORY_ROOT}/init/startup at booting, so the following code can be reused.
"""
def __init__(self, _dut=None):
super(FactoryInit, self).__init__(_dut)
self._factory_root = self._device.storage.GetFactoryRoot()
self._init_dir = self._device.path.join(self._factory_root, 'init')
self._init_script_dir = self._device.path.join(self._init_dir, 'main.d')
def AddFactoryStartUpApp(self, name, script_path):
"""Add a start up application to the board.
Args:
name: the name of the job, which can be used when we want to remove it.
script_path: the actual path of the script to be execute on the board.
Note that the path is a path on the DUT.
"""
# Chrome OS test image executes '${FACTORY_ROOT}/init/startup' if
# file '${FACTORY_ROOT}/enabled' exists.
self._device.CheckCall(
['touch', self._device.path.join(self._factory_root, 'enabled')])
# we first assume that factory toolkit exists, so we can use its startup
# mechanism. (see init/main.d/README for more detail)
job_path = self._device.path.join(self._init_script_dir, name + '.sh')
self._device.CheckCall(['mkdir', '-p', self._init_script_dir])
self._device.CheckCall(['ln', '-sf', script_path, job_path])
self._device.CheckCall(['chmod', '+x', job_path])
dut_startup_script = self._device.path.join(self._init_dir, 'startup')
if not self._device.path.exists(dut_startup_script):
# however, if the default startup script doesn't exists (e.g. factory
# toolkit is not installed), we will create a stub startup script.
station_startup_script = os.path.join(paths.FACTORY_DIR, 'sh',
'stub_startup.sh')
self._device.link.Push(station_startup_script, dut_startup_script)
self._device.CheckCall(['chmod', '+x', dut_startup_script])
def RemoveFactoryStartUpApp(self, name):
"""Remove a start up application on the board.
Args:
name: the name of the job used when creating the job.
"""
job_path = self._device.path.join(self._init_script_dir, name + '.sh')
self._device.CheckCall(['rm', '-f', job_path])