summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic/plugins/source/uboot.py
blob: 57cb3cf8fea3f819775b8765b5d03d2e2e8d516d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2014, Enea AB.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# DESCRIPTION
# This implements the 'uboot' source plugin class for 'wic'
#
# AUTHORS
# Adrian Calianu <adrian.calianu (at] enea.com>
#

import os
import shutil
import re
import tempfile

from mic import kickstart, chroot, msger
from mic.utils import misc, fs_related, errors, runner, cmdln
from mic.conf import configmgr
from mic.plugin import pluginmgr
from mic.utils.partitionedfs import PartitionedMount
import mic.imager.direct as direct
from mic.pluginbase import SourcePlugin
from mic.utils.oe.misc import *
from mic.imager.direct import DirectImageCreator

def create_local_rootfs(part, creator, cr_workdir, krootfs_dir, native_sysroot):
    # In order to have a full control over rootfs we will make a local copy under workdir
    # and change rootfs_dir to new location.
    # In this way we can install more than one ROOTFS_DIRs and/or use
    # an empty rootfs to install packages, so a rootfs could be generated only from pkgs
    # TBD: create workdir/rootfs ; copy rootfs-> workdir/rootfs; set rootfs=workdir/rootfs

    cr_workdir = os.path.abspath(cr_workdir)
    new_rootfs_dir = "%s/rootfs_%s" % (cr_workdir, creator.name)

    rootfs_exists = 1
    if part.rootfs is None:
        if not 'ROOTFS_DIR' in krootfs_dir:
            msg = "Couldn't find --rootfs-dir, exiting, "
            msger.info(msg)
            rootfs_exists = 0
        rootfs_dir = krootfs_dir['ROOTFS_DIR']
        creator.rootfs_dir['ROOTFS_DIR'] = new_rootfs_dir
    else:
        if part.rootfs in krootfs_dir:
            rootfs_dir = krootfs_dir[part.rootfs]
            creator.rootfs_dir[part.rootfs] = new_rootfs_dir
        elif os.path.isdir(part.rootfs):
            rootfs_dir = part.rootfs
            part.rootfs = new_rootfs_dir
        else:
            msg = "Couldn't find --rootfs-dir=%s connection"
            msg += " or it is not a valid path, exiting"
            msger.info(msg % part.rootfs)
            rootfs_exists = 0
            creator.rootfs_dir['ROOTFS_DIR'] = new_rootfs_dir

    pseudox = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
    pseudox += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % new_rootfs_dir
    pseudox += "export PSEUDO_PASSWD=%s;" % new_rootfs_dir
    pseudox += "export PSEUDO_NOSYMLINKEXP=1;"
    pseudox += "%s/usr/bin/pseudo " % native_sysroot

    mkdir_cmd = "mkdir %s" % (new_rootfs_dir)
    # rc, out = exec_native_cmd(pseudox + mkdir_cmd, native_sysroot)
    rc, out = exec_cmd(mkdir_cmd, True)

    if rootfs_exists == 1 and os.path.isdir(rootfs_dir):
        defpath = os.environ['PATH']
        os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"

        rootfs_dir = os.path.abspath(rootfs_dir)

        pseudoc = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
        pseudoc += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
        pseudoc += "export PSEUDO_PASSWD=%s;" % rootfs_dir
        pseudoc += "export PSEUDO_NOSYMLINKEXP=1;"
        pseudoc += "%s/usr/bin/pseudo " % native_sysroot

        tarc_cmd = "tar cvpf %s/rootfs.tar -C %s ." % (cr_workdir, rootfs_dir)
        rc, out = exec_native_cmd(pseudoc + tarc_cmd, native_sysroot)

        tarx_cmd = "tar xpvf %s/rootfs.tar -C %s" % (cr_workdir, new_rootfs_dir)
        rc, out = exec_native_cmd(pseudox + tarx_cmd, native_sysroot)

        rm_cmd = "rm %s/rootfs.tar" % cr_workdir
        rc, out = exec_cmd(rm_cmd, True)

        os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"

    return new_rootfs_dir

class UBootPlugin(SourcePlugin):
    name = 'uboot'

    @classmethod
    def do_install_pkgs(self, part, creator, cr_workdir, oe_builddir, krootfs_dir,
                        bootimg_dir, kernel_dir, native_sysroot):
        """
        Called before all partitions have been prepared and assembled into a
        disk image. Intall packages based on wic configuration.
        """

        # set new rootfs_dir
        rootfs_dir = create_local_rootfs(part, creator, cr_workdir, krootfs_dir, native_sysroot)

        # wks file parsing
        packages = kickstart.get_packages(creator.ks)

        # wic.conf file parsing = found under 'creator'
        local_pkgs_path = creator._local_pkgs_path
        repourl = creator.repourl
        pkgmgr = creator.pkgmgr_name

        # install packages
        if packages and pkgmgr in ["opkg"]:
            if len(repourl) > 0 :
                part.install_pkgs_ipk(cr_workdir, oe_builddir, rootfs_dir, native_sysroot,
                                  packages, repourl)
            else:
                msger.error("No packages repository provided in wic.conf")

    @classmethod
    def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
                             kernel_dir, krootfs_dir, native_sysroot):
        """
        Called to do the actual content population for a partition i.e. it
        'prepares' the partition to be incorporated into the image.
        In this case, prepare content for legacy bios boot partition.
        """
        if part.rootfs is None:
            if not 'ROOTFS_DIR' in krootfs_dir:
                msg = "Couldn't find --rootfs-dir, exiting"
                msger.error(msg)
            rootfs_dir = krootfs_dir['ROOTFS_DIR']
        else:
            if part.rootfs in krootfs_dir:
                rootfs_dir = krootfs_dir[part.rootfs]
            elif os.path.isdir(part.rootfs):
                rootfs_dir = part.rootfs
            else:
                msg = "Couldn't find --rootfs-dir=%s connection"
                msg += " or it is not a valid path, exiting"
                msger.error(msg % part.rootfs)

        part.set_rootfs(rootfs_dir)

        # change partition label wich will reflect into the final rootfs image name
        part.label = "%s_%s" % (part.label, cr.name)

        defpath = os.environ['PATH']
        os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"

        part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, native_sysroot)
        part.prepare_for_uboot(cr.target_arch,cr_workdir, oe_builddir, rootfs_dir, native_sysroot)

        os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"