~gmdduf/lava-dispatcher/gauss-support

« back to all changes in this revision

Viewing changes to lava_dispatcher/device/target.py

Update l-m-c cmdline options

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2012 Linaro Limited
2
 
#
3
 
# Author: Andy Doan <andy.doan@linaro.org>
4
 
#
5
 
# This file is part of LAVA Dispatcher.
6
 
#
7
 
# LAVA Dispatcher is free software; you can redistribute it and/or modify
8
 
# it under the terms of the GNU General Public License as published by
9
 
# the Free Software Foundation; either version 2 of the License, or
10
 
# (at your option) any later version.
11
 
#
12
 
# LAVA Dispatcher is distributed in the hope that it will be useful,
13
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
# GNU General Public License for more details.
16
 
#
17
 
# You should have received a copy of the GNU General Public License
18
 
# along
19
 
# with this program; if not, see <http://www.gnu.org/licenses>.
20
 
 
21
 
import contextlib
22
 
import os
23
 
 
24
 
from lava_dispatcher.client.lmc_utils import (
25
 
    image_partition_mounted,
26
 
    )
27
 
import lava_dispatcher.utils as utils
28
 
 
29
 
 
30
 
def get_target(context, device_config):
31
 
    ipath = 'lava_dispatcher.device.%s' % device_config.client_type
32
 
    m = __import__(ipath, fromlist=[ipath])
33
 
    return m.target_class(context, device_config)
34
 
 
35
 
 
36
 
class Target(object):
37
 
    """ Defines the contract needed by the dispatcher for dealing with a
38
 
    target device
39
 
    """
40
 
 
41
 
    ANDROID_TESTER_PS1 = "root@linaro# "
42
 
 
43
 
    # The target deployment functions will point self.deployment_data to
44
 
    # the appropriate dictionary below. Code such as actions can contribute
45
 
    # to these structures with special handling logic
46
 
    android_deployment_data = {
47
 
        'TESTER_PS1': ANDROID_TESTER_PS1,
48
 
        'TESTER_PS1_PATTERN': ANDROID_TESTER_PS1,
49
 
        'TESTER_PS1_INCLUDES_RC': False,
50
 
        }
51
 
    ubuntu_deployment_data = {
52
 
        'TESTER_PS1': "linaro-test [rc=$(echo \$?)]# ",
53
 
        'TESTER_PS1_PATTERN': "linaro-test \[rc=(\d+)\]# ",
54
 
        'TESTER_PS1_INCLUDES_RC': True,
55
 
    }
56
 
    oe_deployment_data = {
57
 
        'TESTER_PS1': "linaro-test [rc=$(echo \$?)]# ",
58
 
        'TESTER_PS1_PATTERN': "linaro-test \[rc=(\d+)\]# ",
59
 
        'TESTER_PS1_INCLUDES_RC': True,
60
 
    }
61
 
    fedora_deployment_data = {
62
 
        'TESTER_PS1': "linaro-test [rc=$(echo \$?)]# ",
63
 
        'TESTER_PS1_PATTERN': "linaro-test \[rc=(\d+)\]# ",
64
 
        'TESTER_PS1_INCLUDES_RC': True,
65
 
    }
66
 
 
67
 
    def __init__(self, context, device_config):
68
 
        self.context = context
69
 
        self.config = device_config
70
 
 
71
 
        self.boot_options = []
72
 
        self._scratch_dir = None
73
 
        self.deployment_data = {}
74
 
 
75
 
    @property
76
 
    def scratch_dir(self):
77
 
        if self._scratch_dir is None:
78
 
            self._scratch_dir = utils.mkdtemp(
79
 
                self.context.config.lava_image_tmpdir)
80
 
        return self._scratch_dir
81
 
 
82
 
    def power_on(self):
83
 
        """ responsible for powering on the target device and returning an
84
 
        instance of a pexpect session
85
 
        """
86
 
        raise NotImplementedError('power_on')
87
 
 
88
 
    def deploy_linaro(self, hwpack, rfs):
89
 
        raise NotImplementedError('deploy_image')
90
 
 
91
 
    def deploy_android(self, boot, system, userdata):
92
 
        raise NotImplementedError('deploy_android_image')
93
 
 
94
 
    def deploy_linaro_prebuilt(self, image):
95
 
        raise NotImplementedError('deploy_linaro_prebuilt')
96
 
 
97
 
    def power_off(self, proc):
98
 
        if proc is not None:
99
 
            proc.close()
100
 
 
101
 
    @contextlib.contextmanager
102
 
    def file_system(self, partition, directory):
103
 
        """ Allows the caller to interact directly with a directory on
104
 
        the target. This method yields a directory where the caller can
105
 
        interact from. Upon the exit of this context, the changes will be
106
 
        applied to the target.
107
 
 
108
 
        The partition parameter refers to partition number the directory
109
 
        would reside in as created by linaro-media-create. ie - the boot
110
 
        partition would be 1. In the case of something like the master
111
 
        image, the target implementation must map this number to the actual
112
 
        partition its using.
113
 
 
114
 
        NOTE: due to difference in target implementations, the caller should
115
 
        try and interact with the smallest directory locations possible.
116
 
        """
117
 
        raise NotImplementedError('file_system')
118
 
 
119
 
    def extract_tarball(self, tarball_url, partition, directory='/'):
120
 
        """ This is similar to the file_system API but is optimized for the
121
 
        scenario when you just need explode a potentially large tarball on
122
 
        the target device. The file_system API isn't really suitable for this
123
 
        when thinking about an implementation like master.py
124
 
        """
125
 
        raise NotImplementedError('extract_tarball')
126
 
 
127
 
    @contextlib.contextmanager
128
 
    def runner(self):
129
 
        """ Powers on the target, returning a CommandRunner object and will
130
 
        power off the target when the context is exited
131
 
        """
132
 
        proc = runner = None
133
 
        try:
134
 
            proc = self.power_on()
135
 
            runner = self._get_runner(proc)
136
 
            yield runner
137
 
        finally:
138
 
            if proc and runner:
139
 
                self.power_off(proc)
140
 
 
141
 
    def _get_runner(self, proc):
142
 
        from lava_dispatcher.client.base import CommandRunner
143
 
        pat = self.deployment_data['TESTER_PS1_PATTERN']
144
 
        incrc = self.deployment_data['TESTER_PS1_INCLUDES_RC']
145
 
        return CommandRunner(proc, pat, incrc)
146
 
 
147
 
    def get_test_data_attachments(self):
148
 
        return []
149
 
 
150
 
    def get_device_version(self):
151
 
        """ Returns the device version associated with the device, i.e. version
152
 
        of emulation software, or version of master image. Must be overriden in
153
 
        subclasses.
154
 
        """
155
 
        return 'unknown'
156
 
 
157
 
    def _customize_ubuntu(self, rootdir):
158
 
        self.deployment_data = Target.ubuntu_deployment_data
159
 
        with open('%s/root/.bashrc' % rootdir, 'a') as f:
160
 
            f.write('export PS1="%s"\n' % self.deployment_data['TESTER_PS1'])
161
 
        with open('%s/etc/hostname' % rootdir, 'w') as f:
162
 
            f.write('%s\n' % self.config.hostname)
163
 
 
164
 
    def _customize_oe(self, rootdir):
165
 
        self.deployment_data = Target.oe_deployment_data
166
 
        with open('%s/etc/profile' % rootdir, 'a') as f:
167
 
            f.write('export PS1="%s"\n' % self.deployment_data['TESTER_PS1'])
168
 
        with open('%s/etc/hostname' % rootdir, 'w') as f:
169
 
            f.write('%s\n' % self.config.hostname)
170
 
 
171
 
    def _customize_fedora(self, rootdir):
172
 
        self.deployment_data = Target.fedora_deployment_data
173
 
        with open('%s/etc/profile' % rootdir, 'a') as f:
174
 
            f.write('export PS1="%s"\n' % self.deployment_data['TESTER_PS1'])
175
 
        with open('%s/etc/hostname' % rootdir, 'w') as f:
176
 
            f.write('%s\n' % self.config.hostname)
177
 
 
178
 
    def _customize_linux(self, image):
179
 
        root_part = self.config.root_part
180
 
        os_release_id = 'linux'
181
 
        with image_partition_mounted(image, root_part) as mnt:
182
 
            os_release_file = '%s/etc/os-release' % mnt
183
 
            if os.path.exists(os_release_file):
184
 
                for line in open(os_release_file):
185
 
                    if line.startswith('ID='):
186
 
                        os_release_id = line[(len('ID=')):]
187
 
                        os_release_id = os_release_id.strip('\"\n')
188
 
                        break
189
 
 
190
 
            if os_release_id == 'debian' or os_release_id == 'ubuntu' or \
191
 
                    os.path.exists('%s/etc/debian_version' % mnt):
192
 
                self._customize_ubuntu(mnt)
193
 
            elif os_release_id == 'fedora':
194
 
                self._customize_fedora(mnt)
195
 
            else:
196
 
                # assume an OE based image. This is actually pretty safe
197
 
                # because we are doing pretty standard linux stuff, just
198
 
                # just no upstart or dash assumptions
199
 
                self._customize_oe(mnt)