1##########################################################################
2# Copyright (c) 2009, 2010, 2011, 2016, ETH Zurich.
3# All rights reserved.
4#
5# This file is distributed under the terms in the attached LICENSE file.
6# If you do not find this file, copies can be found by writing to:
7# ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
8##########################################################################
9
10import os.path
11
12class Module(object):
13    def __init__(self, module, args):
14        self.module = module
15        self.args = args
16
17class BootModules(object):
18    """Modules to boot (ie. the menu.lst file)"""
19
20    def __init__(self, machine, prefix, kernel):
21        self.hypervisor = None
22        self.prefix = prefix
23        self.kernel = os.path.join(prefix, kernel)
24        self.kernelArgs = []
25        self.cpu_driver = None
26        self.boot_driver = None
27        self.boot_driver_args = []
28        self.modules = []
29        self.machine = machine
30
31    def set_kernel(self, kernel, args=[]):
32        if kernel == None:
33            self.kernel = None
34        else:
35            self.kernel = os.path.join(self.prefix, kernel)
36        if args is None:
37            args = []
38        self.kernelArgs = args
39
40    def add_kernel_args(self, args):
41        if args:
42            self.kernelArgs.extend(args)
43
44    def set_cpu_driver(self, cpu_driver, args=[]):
45        if cpu_driver == None :
46            self.cpu_driver = None
47            self.kernelArgs = []
48        else :
49            self.cpu_driver = os.path.join(self.prefix, cpu_driver)
50            if args is None:
51                args = []
52            self.kernelArgs = args
53
54    def set_boot_driver(self, boot_driver,  args=[]):
55        if boot_driver == None :
56            self.boot_driver = None
57            self.boot_driver_args = []
58        else :
59            self.boot_driver = os.path.join(self.prefix, boot_driver);
60            if args is None:
61                args = []
62            self.boot_driver_args = args
63
64    def set_boot_driver_args(self, args):
65        self.boot_driver_args.extend(args)
66
67    def set_hypervisor(self, h):
68        self.hypervisor = h
69
70    # does modulespec describe modulename?
71    def _module_matches(self, modulename, modulespec):
72        if '/' in modulespec: # if the spec contains a path, they must be the same
73            return modulespec == modulename
74        else: # otherwise, we look at the last part of the name only
75            return modulespec == modulename.rsplit('/',1)[-1]
76
77    def add_module(self, module, args=[]):
78        if module.startswith('/'):
79            # absolute path are converted to relative and left as-is
80            module = module[1:]
81        else:
82            # relative paths are prepended with the prefix
83            module = os.path.join(self.prefix, module)
84        mod = Module(module, args)
85        self.modules.append(mod)
86        return mod
87
88    def add_module_arg(self, modulename, arg):
89        for mod in self.modules:
90            if self._module_matches(mod.module, modulename):
91                mod.args.append(arg)
92
93    def get_menu_data(self, path, root="(nd)"):
94        assert(self.kernel != None
95                or (self.boot_driver != None and self.cpu_driver != None))
96        r = "timeout 0\n"
97        r += "title Harness image\n"
98        r += "root %s\n" % root
99        if self.boot_driver :
100            r += "bootdriver %s %s\n" % (
101                os.path.join(path, self.boot_driver), " ".join(self.boot_driver_args))
102        if self.cpu_driver :
103            r += "cpudriver %s %s\n" % (
104                os.path.join(path, self.cpu_driver), " ".join(self.kernelArgs))
105        if self.hypervisor:
106            r += "hypervisor %s\n" % os.path.join(path, self.prefix, self.hypervisor)
107
108        if self.kernel :
109            r += "kernel %s %s\n" % (
110                os.path.join(path, self.kernel), " ".join(self.kernelArgs))
111        for module in self.modules:
112            r += "modulenounzip %s %s\n" % (os.path.join(path, module.module), " ".join(map(str, module.args)))
113
114        return r
115
116    # what targets do we need to build/install to run this test?
117    def get_build_targets(self):
118        ret = list(set([ module.module for module in self.modules] ))
119
120        if self.kernel :
121            ret.append(self.kernel)
122        if self.cpu_driver :
123            ret.append(self.cpu_driver)
124        if self.boot_driver :
125            ret.append(self.boot_driver)
126        if self.hypervisor:
127            ret.append(self.hypervisor)
128
129        return ret
130