diff --git a/scripts/lib/image/canned-wks/uboot.wks
b/scripts/lib/image/canned-wks/uboot.wks
new file mode 100644
index 0000000..7de0572
--- /dev/null
+++ b/scripts/lib/image/canned-wks/uboot.wks
@@ -0,0 +1,17 @@
+# short-description: . Create a ramdisk image for U-Boot
+# long-description: Creates a ramdisk image for U-Boot that user
+# can directly load it into ram through tftp
+#
+# part - is a wic command that drive the process of generating a valid file
system
+# - --source=uboot : wic plugin that generates a ramdisk image for U-Boot
+# - --fstype=ext2 : file system type( ext2 / ext3 / ext 4)
+#
+# %packages %end - option to provide a list of packages that will be installed
+# into rootfs. All packages dependencies will be installed by
+# package manager(default opkg).
+
+
+part / --source=uboot --fstype=ext2 --label imageName --align 1024
+
+%packages
+%end
diff --git a/scripts/lib/image/config/wic.conf
b/scripts/lib/image/config/wic.conf
index e96d6ae..2a2750b 100644
--- a/scripts/lib/image/config/wic.conf
+++ b/scripts/lib/image/config/wic.conf
@@ -4,4 +4,8 @@ distro_name = OpenEmbedded
[create]
; settings for create subcommand
+; repourl=http://linux.com/ipk/all http://linux.com/ipk/target
http://linux.com/ipk/arch
+arch=powerpc
+pkgmgr=opkg
runtime=native
+install_pkgs=source
diff --git a/scripts/lib/image/engine.py b/scripts/lib/image/engine.py
index 3bda1bf..1256236 100644
--- a/scripts/lib/image/engine.py
+++ b/scripts/lib/image/engine.py
@@ -96,9 +96,10 @@ def build_canned_image_list(dl):
layers_path = get_bitbake_var("BBLAYERS")
canned_wks_layer_dirs = []
- for layer_path in layers_path.split():
- path = os.path.join(layer_path, SCRIPTS_CANNED_IMAGE_DIR)
- canned_wks_layer_dirs.append(path)
+ if layers_path is not None:
+ for layer_path in layers_path.split():
+ path = os.path.join(layer_path, SCRIPTS_CANNED_IMAGE_DIR)
+ canned_wks_layer_dirs.append(path)
path = os.path.join(dl, CANNED_IMAGE_DIR)
canned_wks_layer_dirs.append(path)
diff --git a/scripts/lib/mic/imager/direct.py b/scripts/lib/mic/imager/direct.py
index 2cf4c8d..fef9d0e 100644
--- a/scripts/lib/mic/imager/direct.py
+++ b/scripts/lib/mic/imager/direct.py
@@ -262,6 +262,10 @@ class DirectImageCreator(BaseImageCreator):
# when/if we need to actually do package selection we
# should modify things to use those objects, but for now
# we can avoid that.
+
+ p.install_pkgs(self, self.workdir, self.oe_builddir,
self.rootfs_dir,
+ self.bootimg_dir, self.kernel_dir,
self.native_sysroot)
+
p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
self.bootimg_dir, self.kernel_dir, self.native_sysroot)
diff --git a/scripts/lib/mic/kickstart/custom_commands/partition.py
b/scripts/lib/mic/kickstart/custom_commands/partition.py
index 6b575c0..450d2d4 100644
--- a/scripts/lib/mic/kickstart/custom_commands/partition.py
+++ b/scripts/lib/mic/kickstart/custom_commands/partition.py
@@ -31,7 +31,11 @@ from mic.utils.oe.misc import *
from mic.kickstart.custom_commands import *
from mic.plugin import pluginmgr
+import os
+from mic.utils.oe.package_manager import *
+
partition_methods = {
+ "do_install_pkgs":None,
"do_stage_partition":None,
"do_prepare_partition":None,
"do_configure_partition":None,
@@ -115,6 +119,102 @@ class Wic_PartData(Mic_PartData):
else:
return 0
+ def install_pkgs(self, creator, cr_workdir, oe_builddir, rootfs_dir,
+ bootimg_dir, kernel_dir, native_sysroot):
+ """
+ Prepare content for individual partitions, installing packages.
+ """
+
+ if not self.source:
+ return
+
+ self._source_methods =
pluginmgr.get_source_plugin_methods(self.source, partition_methods)
+ self._source_methods["do_install_pkgs"](self, creator,
+ cr_workdir,
+ oe_builddir,
+ rootfs_dir,
+ bootimg_dir,
+ kernel_dir,
+ native_sysroot)
+
+ def install_pkgs_ipk(self, cr_workdir, oe_builddir, rootfs_dir,
+ native_sysroot, packages, repourl):
+ """
+ Install packages specified into wks file using opkg package manager.
+ This method is dependend on bb module.
+ """
+
+ gVar = {}
+ gVar["DEPLOY_DIR_IPK"] = os.path.join(oe_builddir, "tmp/deploy/ipk")
+
+ # Run postinstall scripts even in offline mode
+ # Use the arch priority package rather than higher version one if more
than one candidate is found.
+ #d.setVar("OPKG_ARGS", "--force_postinstall --prefer-arch-to-version")
+ gVar["OPKG_ARGS"] = "--force_postinstall"
+
+ # OPKG path relative to /output_path
+ gVar["OPKGLIBDIR"] = "var/lib"
+
+ source_url = repourl.split()
+
+ # Generate feed uri's names, it doesn't seem to matter what name they
have
+ feed_uris = ""
+ cnt = 0
+ archs = ""
+ for url in source_url:
+ feed_uris += "cl_def_feed%d##%s\n" % (cnt, url)
+ cnt += 1
+ head, tail = os.path.split(url)
+ archs += " " + tail
+
+ # IPK_FEED_URIS with special formating defines the URI's used as
source for packages
+ gVar['IPK_FEED_URIS'] = feed_uris
+
+ gVar['BUILD_IMAGES_FROM_FEEDS'] = "1"
+
+ # We need to provide sysroot for utilities
+ gVar['STAGING_DIR_NATIVE'] = native_sysroot
+
+ # Set WORKDIR for output
+ gVar['WORKDIR'] = cr_workdir
+
+ # Set TMPDIR for output
+ gVar['TMPDIR'] = os.path.join(cr_workdir, "tmp")
+
+ if 'ROOTFS_DIR' in rootfs_dir:
+ target_dir = rootfs_dir['ROOTFS_DIR']
+ elif os.path.isdir(rootfs_dir):
+ target_dir = rootfs_dir
+ else:
+ msg = "Couldn't find --rootfs-dir=%s connection"
+ msg += " or it is not a valid path, exiting"
+ msger.error(msg % rootfs_dir)
+
+ # Need native sysroot /usr/bin/ for opkg-cl
+ # chnage PATH var to avoid issues with host tools
+ defpath = os.environ['PATH']
+ os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
+
+ pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
+ pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % target_dir
+ pseudo += "export PSEUDO_PASSWD=%s;" % target_dir
+ pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
+ pseudo += "%s/usr/bin/pseudo " % native_sysroot
+
+ pm = WicOpkgPM(gVar,
+ target_dir,
+ 'opkg.conf',
+ archs,
+ pseudo,
+ native_sysroot)
+
+ pm.update()
+
+ pm.install(packages)
+
+ os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
+
+
def prepare(self, cr, cr_workdir, oe_builddir, rootfs_dir, bootimg_dir,
kernel_dir, native_sysroot):
"""
@@ -225,6 +325,34 @@ class Wic_PartData(Mic_PartData):
return 0
+ def prepare_for_uboot(self, arch, cr_workdir, oe_builddir, rootfs_dir,
+ native_sysroot):
+ """
+ Generates u-boot image from source_file( ext2/3/4 )
+
+ """
+ pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
+ pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
+ pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
+ pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
+ pseudo += "%s/usr/bin/pseudo " % native_sysroot
+
+ # 1) compress image
+ rootfs = self.source_file
+ rootfs_gzip = "%s.gz" % rootfs
+ gzip_cmd = "gzip -f -9 -c %s > %s" % (rootfs, rootfs_gzip)
+ rc, out = exec_native_cmd(pseudo + gzip_cmd, native_sysroot)
+
+ # 2) image for U-Boot
+ rootfs_uboot = "%s.u-boot" % rootfs_gzip
+ mkimage_cmd = "mkimage -A %s -O linux -T ramdisk -C gzip -n %s -d %s
%s" % \
+ (arch, self.label, rootfs_gzip, rootfs_uboot)
+ rc, out = exec_native_cmd(pseudo + mkimage_cmd, native_sysroot)
+
+ msger.info("\n\n\tThe new U-Boot ramdisk image can be found
here:\n\t\t%s\n\n" % rootfs_uboot)
+
+ return 0
+
def prepare_rootfs_btrfs(self, cr_workdir, oe_builddir, rootfs_dir,
native_sysroot, pseudo):
"""
diff --git a/scripts/lib/mic/plugin.py b/scripts/lib/mic/plugin.py
index bec33d6..585fd6d 100644
--- a/scripts/lib/mic/plugin.py
+++ b/scripts/lib/mic/plugin.py
@@ -53,12 +53,13 @@ class PluginMgr(object):
self.layers_path = get_bitbake_var("BBLAYERS")
layer_dirs = []
- for layer_path in self.layers_path.split():
- path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype)
- layer_dirs.append(path)
+ if self.layers_path is not None:
+ for layer_path in self.layers_path.split():
+ path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype)
+ layer_dirs.append(path)
- path = os.path.join(dl, ptype)
- layer_dirs.append(path)
+ path = os.path.join(dl, ptype)
+ layer_dirs.append(path)
return layer_dirs
diff --git a/scripts/lib/mic/pluginbase.py b/scripts/lib/mic/pluginbase.py
index 9cf4c62..881d996 100644
--- a/scripts/lib/mic/pluginbase.py
+++ b/scripts/lib/mic/pluginbase.py
@@ -89,6 +89,15 @@ class SourcePlugin(_Plugin):
"""
@classmethod
+ def do_install_pkgs(self, part, creator, cr_workdir, oe_builddir,
rootfs_dir,
+ bootimg_dir, kernel_dir, native_sysroot):
+ """
+ Called before partitions have been prepared and assembled into a
+ disk image. Install packages into rootfs
+ """
+ msger.debug("SourcePlugin: do_install_pkgs: part %s" % part)
+
+ @classmethod
def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir,
bootimg_dir, kernel_dir, native_sysroot):
"""
diff --git a/scripts/lib/mic/plugins/source/uboot.py
b/scripts/lib/mic/plugins/source/uboot.py
new file mode 100644
index 0000000..57cb3cf
--- /dev/null
+++ b/scripts/lib/mic/plugins/source/uboot.py
@@ -0,0 +1,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/"
diff --git a/scripts/lib/mic/utils/oe/package_manager.py
b/scripts/lib/mic/utils/oe/package_manager.py
new file mode 100644
index 0000000..92ce98e
--- /dev/null
+++ b/scripts/lib/mic/utils/oe/package_manager.py
@@ -0,0 +1,810 @@
+# 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 opkg package manager wrapper as a combination of
+# meta/lib/oe/package_manager.py and bitbake/lib/bb/utils.py files and
+# adaptation of those files to 'wic'.
+#
+# AUTHORS
+# Adrian Calianu <adrian.calianu (at] enea.com>
+#
+# This file incorporates work covered by the following copyright and
+# permission notice:
+#
+# meta/COPYING.GPLv2 (GPLv2)
+# meta/COPYING.MIT (MIT)
+#
+# Copyright (C) 2004 Michael Lauer
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+from abc import ABCMeta, abstractmethod
+import os
+import glob
+import subprocess
+import shutil
+import multiprocessing
+import re
+import errno
+import fcntl
+
+from mic.utils.oe.misc import *
+from mic import msger
+
+def mkdirhier(directory):
+ """Create a directory like 'mkdir -p', but does not complain if
+ directory already exists like os.makedirs
+ """
+
+ try:
+ os.makedirs(directory)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise e
+
+def remove(path, recurse=False):
+ """Equivalent to rm -f or rm -rf"""
+ if not path:
+ return
+ if recurse:
+ # shutil.rmtree(name) would be ideal but its too slow
+ subprocess.call(['rm', '-rf'] + glob.glob(path))
+ return
+ for name in glob.glob(path):
+ try:
+ os.unlink(name)
+ except OSError as exc:
+ if exc.errno != errno.ENOENT:
+ raise
+
+def lockfile(name, shared=False, retry=True):
+ """
+ Use the file fn as a lock file, return when the lock has been acquired.
+ Returns a variable to pass to unlockfile().
+ """
+ dirname = os.path.dirname(name)
+ mkdirhier(dirname)
+
+ if not os.access(dirname, os.W_OK):
+ logger.error("Unable to acquire lock '%s', directory is not writable",
+ name)
+ sys.exit(1)
+
+ op = fcntl.LOCK_EX
+ if shared:
+ op = fcntl.LOCK_SH
+ if not retry:
+ op = op | fcntl.LOCK_NB
+
+ while True:
+ # If we leave the lockfiles lying around there is no problem
+ # but we should clean up after ourselves. This gives potential
+ # for races though. To work around this, when we acquire the lock
+ # we check the file we locked was still the lock file on disk.
+ # by comparing inode numbers. If they don't match or the lockfile
+ # no longer exists, we start again.
+
+ # This implementation is unfair since the last person to request the
+ # lock is the most likely to win it.
+
+ try:
+ lf = open(name, 'a+')
+ fileno = lf.fileno()
+ fcntl.flock(fileno, op)
+ statinfo = os.fstat(fileno)
+ if os.path.exists(lf.name):
+ statinfo2 = os.stat(lf.name)
+ if statinfo.st_ino == statinfo2.st_ino:
+ return lf
+ lf.close()
+ except Exception:
+ try:
+ lf.close()
+ except Exception:
+ pass
+ pass
+ if not retry:
+ return None
+
+def unlockfile(lf):
+ """
+ Unlock a file locked using lockfile()
+ """
+ try:
+ # If we had a shared lock, we need to promote to exclusive before
+ # removing the lockfile. Attempt this, ignore failures.
+ fcntl.flock(lf.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB)
+ os.unlink(lf.name)
+ except (IOError, OSError):
+ pass
+ fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
+ lf.close()
+
+def which(path, item, direction = 0, history = False):
+ """
+ Locate a file in a PATH
+ """
+
+ hist = []
+ paths = (path or "").split(':')
+ if direction != 0:
+ paths.reverse()
+
+ for p in paths:
+ next = os.path.join(p, item)
+ hist.append(next)
+ if os.path.exists(next):
+ if not os.path.isabs(next):
+ next = os.path.abspath(next)
+ if history:
+ return next, hist
+ return next
+
+ if history:
+ return "", hist
+ return ""
+
+
+
+# this can be used by all PM backends to create the index files in parallel
+def wic_create_index(arg):
+ index_cmd = arg
+
+ try:
+ msger.info("Executing '%s' ..." % index_cmd)
+ subprocess.check_output(index_cmd, stderr=subprocess.STDOUT,
shell=True)
+ except subprocess.CalledProcessError as e:
+ return("Index creation command '%s' failed with return code %d:\n%s" %
+ (e.cmd, e.returncode, e.output))
+
+ return None
+
+
+class WicIndexer(object):
+ __metaclass__ = ABCMeta
+
+ def __init__(self, d, deploy_dir):
+ self.d = d
+ self.deploy_dir = deploy_dir
+
+ @abstractmethod
+ def write_index(self):
+ pass
+
+class WicOpkgIndexer(WicIndexer):
+ def write_index(self):
+ arch_vars = ["ALL_MULTILIB_PACKAGE_ARCHS",
+ "SDK_PACKAGE_ARCHS",
+ "MULTILIB_ARCHS"]
+
+ opkg_index_cmd = which(os.getenv('PATH'), "opkg-make-index")
+
+ if not os.path.exists(os.path.join(self.deploy_dir, "Packages")):
+ open(os.path.join(self.deploy_dir, "Packages"), "w").close()
+
+ index_cmds = []
+ for arch_var in arch_vars:
+ if self.d.has_key(arch_var):
+ archs = self.d[arch_var]
+ else:
+ archs = None
+
+ if archs is None:
+ continue
+
+ for arch in archs.split():
+ pkgs_dir = os.path.join(self.deploy_dir, arch)
+ pkgs_file = os.path.join(pkgs_dir, "Packages")
+
+ if not os.path.isdir(pkgs_dir):
+ continue
+
+ if not os.path.exists(pkgs_file):
+ open(pkgs_file, "w").close()
+
+ index_cmds.append('%s -r %s -p %s -m %s' %
+ (opkg_index_cmd, pkgs_file, pkgs_file,
pkgs_dir))
+
+ if len(index_cmds) == 0:
+ msger.info("There are no packages in %s!" % self.deploy_dir)
+ return
+
+ nproc = multiprocessing.cpu_count()
+ pool = multiprocessing.Pool(nproc)
+ results = list(pool.imap(wic_create_index, index_cmds))
+ pool.close()
+ pool.join()
+
+ for result in results:
+ if result is not None:
+ return(result)
+
+class WicPkgsList(object):
+ __metaclass__ = ABCMeta
+
+ def __init__(self, d, rootfs_dir):
+ self.d = d
+ self.rootfs_dir = rootfs_dir
+
+ @abstractmethod
+ def list(self, format=None):
+ pass
+
+
+class WicOpkgPkgsList(WicPkgsList):
+ def __init__(self, d, rootfs_dir, config_file):
+ super(WicOpkgPkgsList, self).__init__(d, rootfs_dir)
+
+ self.opkg_cmd = which(os.getenv('PATH'), "opkg-cl")
+ self.opkg_args = "-f %s -o %s " % (config_file, rootfs_dir)
+ if self.d.has_key("OPKG_ARGS"):
+ self.opkg_args += self.d["OPKG_ARGS"]
+
+ def list(self, format=None):
+ opkg_query_cmd = which(os.getenv('PATH'), "opkg-query-helper.py")
+
+ if format == "arch":
+ cmd = "%s %s status | %s -a" % \
+ (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
+ elif format == "file":
+ cmd = "%s %s status | %s -f" % \
+ (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
+ elif format == "ver":
+ cmd = "%s %s status | %s -v" % \
+ (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
+ elif format == "deps":
+ cmd = "%s %s status | %s" % \
+ (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
+ else:
+ cmd = "%s %s list_installed | cut -d' ' -f1" % \
+ (self.opkg_cmd, self.opkg_args)
+
+ try:
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
shell=True).strip()
+ except subprocess.CalledProcessError as e:
+ msger.error("Cannot get the installed packages list. Command '%s' "
+ "returned %d:\n%s" % (cmd, e.returncode, e.output))
+
+ if output and format == "file":
+ tmp_output = ""
+ for line in output.split('\n'):
+ pkg, pkg_file, pkg_arch = line.split()
+ full_path = os.path.join(self.rootfs_dir, pkg_arch, pkg_file)
+ if os.path.exists(full_path):
+ tmp_output += "%s %s %s\n" % (pkg, full_path, pkg_arch)
+ else:
+ tmp_output += "%s %s %s\n" % (pkg, pkg_file, pkg_arch)
+
+ output = tmp_output
+
+ return output
+
+
+class WicPackageManager(object):
+ """
+ This is an abstract class. Do not instantiate this directly.
+ """
+ __metaclass__ = ABCMeta
+
+ def __init__(self, d, pseudo, native_sysroot):
+ self.d = d
+ self.deploy_dir = None
+ self.deploy_lock = None
+ if self.d.has_key('PACKAGE_FEED_URIS'):
+ self.feed_uris = self.d['PACKAGE_FEED_URIS']
+ else:
+ self.feed_uris = ""
+ self.pseudo = pseudo
+ self.native_sysroot = native_sysroot
+
+ """
+ Update the package manager package database.
+ """
+ @abstractmethod
+ def update(self):
+ pass
+
+ """
+ Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is
+ True, installation failures are ignored.
+ """
+ @abstractmethod
+ def install(self, pkgs, attempt_only=False):
+ pass
+
+ """
+ Remove a list of packages. 'pkgs' is a list object. If 'with_dependencies'
+ is False, the any dependencies are left in place.
+ """
+ @abstractmethod
+ def remove(self, pkgs, with_dependencies=True):
+ pass
+
+ """
+ This function creates the index files
+ """
+ @abstractmethod
+ def write_index(self):
+ pass
+
+ @abstractmethod
+ def remove_packaging_data(self):
+ pass
+
+ @abstractmethod
+ def list_installed(self, format=None):
+ pass
+
+ @abstractmethod
+ def insert_feeds_uris(self):
+ pass
+
+ """
+ Install complementary packages based upon the list of currently installed
+ packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install
+ these packages, if they don't exist then no error will occur. Note: every
+ backend needs to call this function explicitly after the normal package
+ installation
+ """
+ def install_complementary(self, globs=None):
+ # we need to write the list of installed packages to a file because the
+ # oe-pkgdata-util reads it from a file
+ if self.d.has_key('WORKDIR'):
+ installed_pkgs_file = os.path.join(self.d['WORKDIR'],
+ "installed_pkgs.txt")
+ else:
+ msger.error("No WORKDIR provided!")
+
+ with open(installed_pkgs_file, "w+") as installed_pkgs:
+ installed_pkgs.write(self.list_installed("arch"))
+
+ if globs is None:
+ if self.d.has_key('IMAGE_INSTALL_COMPLEMENTARY'):
+ globs = self.d['IMAGE_INSTALL_COMPLEMENTARY']
+ split_linguas = set()
+
+ if self.d.has_key('IMAGE_LINGUAS'):
+ for translation in self.d['IMAGE_LINGUAS'].split():
+ split_linguas.add(translation)
+ split_linguas.add(translation.split('-')[0])
+
+ split_linguas = sorted(split_linguas)
+
+ for lang in split_linguas:
+ globs += " *-locale-%s" % lang
+
+ if globs is None:
+ return
+
+ if not self.d.has_key('PKGDATA_DIR'):
+ msger.error("No PKGDATA_DIR provided!")
+
+ cmd = [which(os.getenv('PATH'), "oe-pkgdata-util"),
+ "glob", self.d['PKGDATA_DIR'], installed_pkgs_file,
+ globs]
+
+ rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
+ if rc != 0:
+ msger.error("Could not compute complementary packages list. Command
"
+ "'%s' returned %d" %
+ (' '.join(cmd), rc))
+
+ self.install(out.split(), attempt_only=True)
+
+
+ def deploy_dir_lock(self):
+ if self.deploy_dir is None:
+ raise RuntimeError("deploy_dir is not set!")
+
+ lock_file_name = os.path.join(self.deploy_dir, "deploy.lock")
+
+ self.deploy_lock = lockfile(lock_file_name)
+
+ def deploy_dir_unlock(self):
+ if self.deploy_lock is None:
+ return
+
+ unlockfile(self.deploy_lock)
+
+ self.deploy_lock = None
+
+
+class WicOpkgPM(WicPackageManager):
+ def __init__(self, d, target_rootfs, config_file, archs, pseudo,
native_sysroot, task_name='target'):
+ super(WicOpkgPM, self).__init__(d, pseudo, native_sysroot)
+
+ self.target_rootfs = target_rootfs
+ self.config_file = config_file
+ self.pkg_archs = archs
+ self.task_name = task_name
+
+ if self.d.has_key("DEPLOY_DIR_IPK"):
+ self.deploy_dir = self.d["DEPLOY_DIR_IPK"]
+
+ self.deploy_lock_file = os.path.join(self.deploy_dir, "deploy.lock")
+ self.opkg_cmd = which(os.getenv('PATH'), "opkg-cl")
+ self.opkg_args = "-f %s -o %s " % (self.config_file, target_rootfs)
+ if self.d.has_key("OPKG_ARGS"):
+ self.opkg_args += self.d["OPKG_ARGS"]
+
+ if self.d.has_key('OPKGLIBDIR'):
+ opkg_lib_dir = self.d['OPKGLIBDIR']
+ else:
+ opkg_lib_dir = ""
+
+ if opkg_lib_dir[0] == "/":
+ opkg_lib_dir = opkg_lib_dir[1:]
+
+ self.opkg_dir = os.path.join(target_rootfs, opkg_lib_dir, "opkg")
+
+ mkdirhier(self.opkg_dir)
+
+ if self.d.has_key("TMPDIR"):
+ tmp_dir = self.d["TMPDIR"]
+ else:
+ tmp_dir = ""
+
+ self.saved_opkg_dir = '%s/saved/%s' % (tmp_dir, self.task_name)
+ if not os.path.exists('%s/saved' % tmp_dir):
+ mkdirhier('%s/saved' % tmp_dir)
+
+ if self.d.has_key('BUILD_IMAGES_FROM_FEEDS') and
self.d['BUILD_IMAGES_FROM_FEEDS'] != "1":
+ self._create_config()
+ else:
+ self._create_custom_config()
+
+ self.indexer = WicOpkgIndexer(self.d, self.deploy_dir)
+
+ """
+ This function will change a package's status in /var/lib/opkg/status file.
+ If 'packages' is None then the new_status will be applied to all
+ packages
+ """
+ def mark_packages(self, status_tag, packages=None):
+ status_file = os.path.join(self.opkg_dir, "status")
+
+ with open(status_file, "r") as sf:
+ with open(status_file + ".tmp", "w+") as tmp_sf:
+ if packages is None:
+ tmp_sf.write(re.sub(r"Package: (.*?)\n((?:[^\n]+\n)*?)Status:
(.*)(?:unpacked|installed)",
+ r"Package: \1\n\2Status: \3%s" %
status_tag,
+ sf.read()))
+ else:
+ if type(packages).__name__ != "list":
+ raise TypeError("'packages' should be a list object")
+
+ status = sf.read()
+ for pkg in packages:
+ status = re.sub(r"Package: %s\n((?:[^\n]+\n)*?)Status:
(.*)(?:unpacked|installed)" % pkg,
+ r"Package: %s\n\1Status: \2%s" % (pkg,
status_tag),
+ status)
+
+ tmp_sf.write(status)
+
+ os.rename(status_file + ".tmp", status_file)
+
+ def _create_custom_config(self):
+ msger.info("Building from feeds activated!")
+
+ with open(self.config_file, "w+") as config_file:
+ priority = 1
+ for arch in self.pkg_archs.split():
+ config_file.write("arch %s %d\n" % (arch, priority))
+ priority += 5
+
+ if self.d.has_key('IPK_FEED_URIS'):
+ ipk_feed_uris = self.d['IPK_FEED_URIS']
+ else:
+ ipk_feed_uris = ""
+
+ for line in ipk_feed_uris.split():
+ feed_match = re.match("^[ \t]*(.*)##([^ \t]*)[ \t]*$", line)
+
+ if feed_match is not None:
+ feed_name = feed_match.group(1)
+ feed_uri = feed_match.group(2)
+
+ msger.info("Add %s feed with URL %s" % (feed_name,
feed_uri))
+
+ config_file.write("src/gz %s %s\n" % (feed_name, feed_uri))
+
+ """
+ Allow to use package deploy directory contents as quick
devel-testing
+ feed. This creates individual feed configs for each arch subdir of
those
+ specified as compatible for the current machine.
+ NOTE: Development-helper feature, NOT a full-fledged feed.
+ """
+ if self.d.has_key('FEED_DEPLOYDIR_BASE_URI'):
+ feed_deploydir_base_dir = self.d['FEED_DEPLOYDIR_BASE_URI']
+ else:
+ feed_deploydir_base_dir = ""
+
+ if feed_deploydir_base_dir != "":
+ for arch in self.pkg_archs.split():
+ if self.d.has_key("sysconfdir"):
+ sysconfdir = self.d["sysconfdir"]
+ else:
+ sysconfdir = None
+
+ cfg_file_name = os.path.join(self.target_rootfs,
+ sysconfdir,
+ "opkg",
+ "local-%s-feed.conf" % arch)
+
+ with open(cfg_file_name, "w+") as cfg_file:
+ cfg_file.write("src/gz local-%s %s/%s" %
+ arch,
+ feed_deploydir_base_dir,
+ arch)
+
+ def _create_config(self):
+ with open(self.config_file, "w+") as config_file:
+ priority = 1
+ for arch in self.pkg_archs.split():
+ config_file.write("arch %s %d\n" % (arch, priority))
+ priority += 5
+
+ config_file.write("src oe file:%s\n" % self.deploy_dir)
+
+ for arch in self.pkg_archs.split():
+ pkgs_dir = os.path.join(self.deploy_dir, arch)
+ if os.path.isdir(pkgs_dir):
+ config_file.write("src oe-%s file:%s\n" %
+ (arch, pkgs_dir))
+
+ def insert_feeds_uris(self):
+ if self.feed_uris == "":
+ return
+
+ rootfs_config = os.path.join('%s/etc/opkg/base-feeds.conf'
+ % self.target_rootfs)
+
+ with open(rootfs_config, "w+") as config_file:
+ uri_iterator = 0
+ for uri in self.feed_uris.split():
+ config_file.write("src/gz url-%d %s/ipk\n" %
+ (uri_iterator, uri))
+
+ for arch in self.pkg_archs.split():
+ if not os.path.exists(os.path.join(self.deploy_dir, arch)):
+ continue
+ msger.info('Note: adding opkg channel url-%s-%d (%s)' %
+ (arch, uri_iterator, uri))
+
+ config_file.write("src/gz uri-%s-%d %s/ipk/%s\n" %
+ (arch, uri_iterator, uri, arch))
+ uri_iterator += 1
+
+ def update(self):
+ self.deploy_dir_lock()
+
+ cmd = "%s %s update" % (self.opkg_cmd, self.opkg_args)
+
+ rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
+ if rc != 0:
+ self.deploy_dir_unlock()
+ msger.error("Unable to update the package index files. Command '%s'
"
+ "returned %d" % (cmd, rc))
+
+ self.deploy_dir_unlock()
+
+ def install(self, pkgs, attempt_only=False):
+ if attempt_only and len(pkgs) == 0:
+ return
+
+ cmd = "%s %s install %s" % (self.opkg_cmd, self.opkg_args, '
'.join(pkgs))
+
+ os.environ['D'] = self.target_rootfs
+ os.environ['OFFLINE_ROOT'] = self.target_rootfs
+ os.environ['IPKG_OFFLINE_ROOT'] = self.target_rootfs
+ os.environ['OPKG_OFFLINE_ROOT'] = self.target_rootfs
+ if self.d.has_key('WORKDIR'):
+ os.environ['INTERCEPT_DIR'] = os.path.join(self.d['WORKDIR'],
+ "intercept_scripts")
+ else:
+ os.environ['INTERCEPT_DIR'] = "."
+ msger.warning("No WORKDIR provided!")
+
+ if self.d.has_key('STAGING_DIR_NATIVE'):
+ os.environ['NATIVE_ROOT'] = self.d['STAGING_DIR_NATIVE']
+ else:
+ msger.error("No STAGING_DIR_NATIVE provided!")
+
+ rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
+ if rc != 0:
+ msger.error("Unable to install packages. "
+ "Command '%s' returned %d" % (cmd, rc))
+
+
+ def remove(self, pkgs, with_dependencies=True):
+ if with_dependencies:
+ cmd = "%s %s --force-depends --force-remove
--force-removal-of-dependent-packages remove %s" % \
+ (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
+ else:
+ cmd = "%s %s --force-depends remove %s" % \
+ (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
+
+ rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
+ if rc != 0:
+ msger.error("Unable to remove packages. Command '%s' "
+ "returned %d" % (cmd, rc))
+
+
+ def write_index(self):
+ self.deploy_dir_lock()
+
+ result = self.indexer.write_index()
+
+ self.deploy_dir_unlock()
+
+ if result is not None:
+ msger.error(result)
+
+ def remove_packaging_data(self):
+ remove(self.opkg_dir, True)
+ # create the directory back, it's needed by PM lock
+ mkdirhier(self.opkg_dir)
+
+ def list_installed(self, format=None):
+ return WicOpkgPkgsList(self.d, self.target_rootfs,
self.config_file).list(format)
+
+ def handle_bad_recommendations(self):
+ if self.d.has_key("BAD_RECOMMENDATIONS"):
+ bad_recommendations = self.d["BAD_RECOMMENDATIONS"]
+ else:
+ bad_recommendations = ""
+
+ if bad_recommendations.strip() == "":
+ return
+
+ status_file = os.path.join(self.opkg_dir, "status")
+
+ # If status file existed, it means the bad recommendations has already
+ # been handled
+ if os.path.exists(status_file):
+ return
+
+ cmd = "%s %s info " % (self.opkg_cmd, self.opkg_args)
+
+ with open(status_file, "w+") as status:
+ for pkg in bad_recommendations.split():
+ pkg_info = cmd + pkg
+
+ try:
+ output = subprocess.check_output(pkg_info.split(),
stderr=subprocess.STDOUT).strip()
+ except subprocess.CalledProcessError as e:
+ msger.error("Cannot get package info. Command '%s' "
+ "returned %d:\n%s" % (pkg_info, e.returncode,
e.output))
+
+ if output == "":
+ msger.info("Ignored bad recommendation: '%s' is "
+ "not a package" % pkg)
+ continue
+
+ for line in output.split('\n'):
+ if line.startswith("Status:"):
+ status.write("Status: deinstall hold not-installed\n")
+ else:
+ status.write(line + "\n")
+
+ '''
+ The following function dummy installs pkgs and returns the log of output.
+ '''
+ def dummy_install(self, pkgs):
+ if len(pkgs) == 0:
+ return
+
+ # Create an temp dir as opkg root for dummy installation
+ if self.d.has_key("TMPDIR"):
+ tmp_dir = self.d["TMPDIR"]
+ else:
+ tmp_dir = "."
+ msger.warning("No TMPDIR provided!")
+
+ temp_rootfs = '%s/opkg' % tmp_dir
+ temp_opkg_dir = os.path.join(temp_rootfs, 'var/lib/opkg')
+ mkdirhier(temp_opkg_dir)
+
+ opkg_args = "-f %s -o %s " % (self.config_file, temp_rootfs)
+ if self.d.has_key("OPKG_ARGS"):
+ opkg_args += self.d["OPKG_ARGS"]
+
+ cmd = "%s %s update" % (self.opkg_cmd, opkg_args)
+ try:
+ subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
+ except subprocess.CalledProcessError as e:
+ msger.error("Unable to update. Command '%s' "
+ "returned %d:\n%s" % (cmd, e.returncode, e.output))
+
+ # Dummy installation
+ cmd = "%s %s --noaction install %s " % (self.opkg_cmd,
+ opkg_args,
+ ' '.join(pkgs))
+ try:
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
shell=True)
+ except subprocess.CalledProcessError as e:
+ msger.error("Unable to dummy install packages. Command '%s' "
+ "returned %d:\n%s" % (cmd, e.returncode, e.output))
+
+ remove(temp_rootfs, True)
+
+ return output
+
+ def backup_packaging_data(self):
+ # Save the opkglib for increment ipk image generation
+ if os.path.exists(self.saved_opkg_dir):
+ remove(self.saved_opkg_dir, True)
+ shutil.copytree(self.opkg_dir,
+ self.saved_opkg_dir,
+ symlinks=True)
+
+ def recover_packaging_data(self):
+ # Move the opkglib back
+ if os.path.exists(self.saved_opkg_dir):
+ if os.path.exists(self.opkg_dir):
+ remove(self.opkg_dir, True)
+
+ msger.info('Recover packaging data')
+ shutil.copytree(self.saved_opkg_dir,
+ self.opkg_dir,
+ symlinks=True)
+
+
+def wic_generate_index_files(d):
+ if d.has_key('PACKAGE_CLASSES'):
+ classes = d['PACKAGE_CLASSES'].replace("package_", "").split()
+ else:
+ classes = ""
+ msger.warning("No PACKAGE_CLASSES provided!")
+
+ if d.has_key('DEPLOY_DIR_IPK'):
+ deploy_dir_ipk = d['DEPLOY_DIR_IPK']
+ else:
+ deploy_dir_ipk = None
+ msger.warning("No DEPLOY_DIR_IPK provided!")
+
+ indexer_map = {
+ "ipk": (WicOpkgIndexer, deploy_dir_ipk)
+ }
+
+ result = None
+
+ for pkg_class in classes:
+ if not pkg_class in indexer_map:
+ continue
+
+ if os.path.exists(indexer_map[pkg_class][1]):
+ result = indexer_map[pkg_class][0](d,
indexer_map[pkg_class][1]).write_index()
+
+ if result is not None:
+ msger.error(result)
diff --git a/scripts/wic b/scripts/wic
index 2d3fd09..b9c8756 100755
--- a/scripts/wic
+++ b/scripts/wic
@@ -99,6 +99,10 @@ def wic_create_subcommand(args, usage_str):
(options, args) = parser.parse_args(args)
+ if options.debug:
+ loglevel = logging.DEBUG
+ start_logging(loglevel)
+
if len(args) != 1:
logging.error("Wrong number of arguments, exiting\n")
parser.print_help()
@@ -107,9 +111,11 @@ def wic_create_subcommand(args, usage_str):
if not options.image_name and not (options.rootfs_dir and
options.bootimg_dir and
options.kernel_dir and
+ options.native_sysroot or
options.native_sysroot):
print "Build artifacts not completely specified, exiting."
- print " (Use 'wic -e' or 'wic -r -b -k -n' to specify artifacts)"
+ print " (Use 'wic -e' or 'wic -r -b -k -n' or 'wic -r -n' to specify
artifacts)"
+ print options
sys.exit(1)
if not options.image_name:
@@ -125,13 +131,16 @@ def wic_create_subcommand(args, usage_str):
print "Creating image(s)...\n"
- bitbake_env_lines = find_bitbake_env_lines(options.image_name)
- if not bitbake_env_lines:
- print "Couldn't get bitbake environment, exiting."
- sys.exit(1)
- set_bitbake_env_lines(bitbake_env_lines)
+ # If '-e' option is used the values are extracted from bitbake env.
+ if options.image_name:
+ bitbake_env_lines = find_bitbake_env_lines(options.image_name)
+ if not bitbake_env_lines:
+ print "Couldn't get bitbake environment, exiting."
+ sys.exit(1)
+ set_bitbake_env_lines(bitbake_env_lines)
bootimg_dir = staging_data_dir = hdddir = ""
+ rootfs_dir = native_sysroot = kernel_dir = image_output_dir = ""
if options.image_name:
(rootfs_dir, kernel_dir, hdddir, staging_data_dir, native_sysroot) = \
@@ -140,34 +149,65 @@ def wic_create_subcommand(args, usage_str):
wks_file = args[0]
if not wks_file.endswith(".wks"):
+ # Return full path of the .wks file
wks_file = find_canned_image(scripts_path, wks_file)
if not wks_file:
- print "No image named %s found, exiting. (Use 'wic list images' to
list available images, or specify a fully-qualified OE kickstart (.wks) filename)\n"
% wks_file
+ print "No image named %s found, exiting.\n" % wks_file
+ print "(Use 'wic list images' to list available images, or specify a
fully-qualified OE kickstart (.wks) filename)\n"
sys.exit(1)
- image_output_dir = ""
if options.outdir:
image_output_dir = options.outdir
- if not options.image_name:
- rootfs_dir = ''
- if 'ROOTFS_DIR' in options.rootfs_dir:
- rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
- bootimg_dir = options.bootimg_dir
- kernel_dir = options.kernel_dir
+ if options.native_sysroot:
native_sysroot = options.native_sysroot
- if rootfs_dir and not os.path.isdir(rootfs_dir):
- print "--roofs-dir (-r) not found, exiting\n"
- sys.exit(1)
- if not os.path.isdir(bootimg_dir):
- print "--bootimg-dir (-b) not found, exiting\n"
- sys.exit(1)
- if not os.path.isdir(kernel_dir):
- print "--kernel-dir (-k) not found, exiting\n"
- sys.exit(1)
+ print "Using native_sysroot from user command: %s" % native_sysroot
+
if not os.path.isdir(native_sysroot):
- print "--native-sysroot (-n) not found, exiting\n"
+ print "--native-sysroot (-n) not found, exiting"
sys.exit(1)
+
+ native_sysroot = os.path.abspath(native_sysroot)
+
+ if not options.image_name:
+ if (options.bootimg_dir and options.kernel_dir and
+ options.rootfs_dir and options.native_sysroot):
+ rootfs_dir = ''
+ if 'ROOTFS_DIR' in options.rootfs_dir:
+ rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
+ bootimg_dir = options.bootimg_dir
+ kernel_dir = options.kernel_dir
+ native_sysroot = options.native_sysroot
+
+ if rootfs_dir and not os.path.isdir(rootfs_dir):
+ print "--roofs-dir (-r) not found, exiting\n"
+ sys.exit(1)
+ if not os.path.isdir(bootimg_dir):
+ print "--bootimg-dir (-b) not found, exiting\n"
+ sys.exit(1)
+ if not os.path.isdir(kernel_dir):
+ print "--kernel-dir (-k) not found, exiting\n"
+ sys.exit(1)
+ if not os.path.isdir(native_sysroot):
+ print "--native-sysroot (-n) not found, exiting\n"
+ sys.exit(1)
+ else:
+ print 'Build image from rootfs and a package list using native
rootfs\n'
+ if options.rootfs_dir and 'ROOTFS_DIR' in options.rootfs_dir:
+ rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
+ elif options.rootfs_dir:
+ rootfs_dir = options.rootfs_dir
+ else:
+ rootfs_dir = ""
+
+ native_sysroot = options.native_sysroot
+
+ if rootfs_dir and not os.path.isdir(rootfs_dir):
+ print "--roofs-dir (-r) not found, exiting\n"
+ sys.exit(1)
+ if not os.path.isdir(native_sysroot):
+ print "--native-sysroot (-n) not found, exiting\n"
+ sys.exit(1)
else:
not_found = not_found_dir = ""
if not os.path.isdir(rootfs_dir):