Commit 1fa9f682 authored by Aurélien Dunand's avatar Aurélien Dunand Committed by Seblu

Add embedded lib in image

Only support pure python module in lib/, package (like foo.bar) don't work.
Signed-off-by: Seblu's avatarSébastien Luttringer <sebastien.luttringer@smartjog.com>
parent ee4959b8
......@@ -337,7 +337,7 @@ InstallSystems use two kind of images:
**source image**
Each image available in repositories has to be build. The image before building is called a source image. In a source image, there are four directories and two files. Each images make the distinction between scripts and payloads.
Each image available in repositories has to be build. The image before building is called a source image. In a source image, there are five directories and two files. Each images make the distinction between scripts and payloads.
build/
Scripts to customize the build process for the image.
......@@ -348,6 +348,9 @@ InstallSystems use two kind of images:
setup/
The scripts with logical steps of the install are in this directory.
lib/
Python modules which are embeded in image.
payload/
This directory embeds one or more payloads (typically rootfs) for the image.
......
......@@ -33,6 +33,7 @@ import re
import shutil
import stat
import subprocess
import sys
import tarfile
import time
import installsystems
......@@ -78,6 +79,36 @@ class Image(object):
'''
return istools.compare_versions(v1, v2)
def _load_modules(self, lib_list, get_str):
'''
Load python module embedded in image
Return a dict of {module_name: module object}
'''
if not lib_list:
return {}
arrow(u"Load libs")
old_level = arrowlevel(1)
gl ={}
# order matter!
lib_list.sort()
for filename in lib_list:
arrow(os.path.basename(filename))
name = os.path.basename(filename).split('-', 1)[1][:-3]
if name in gl:
error('Module %s already loaded' % name)
# extract source code
try:
code = get_str(filename)
except Exception as e:
raise ISError(u"Extracting lib %s fail: %s" %
(filename, e))
gl[name] = istools.string2module(name, code, filename)
# avoid ImportError when exec 'import name'
sys.modules[name] = gl[name]
arrowlevel(level=old_level)
return gl
class SourceImage(Image):
'''
Image source manipulation class
......@@ -96,10 +127,12 @@ class SourceImage(Image):
parser_path = os.path.join(path, "parser")
setup_path = os.path.join(path, "setup")
payload_path = os.path.join(path, "payload")
lib_path = os.path.join(path, "lib")
# create base directories
arrow("Creating base directories")
try:
for d in (path, build_path, parser_path, setup_path, payload_path):
for d in (path, build_path, parser_path, setup_path, payload_path,
lib_path):
if not os.path.exists(d) or not os.path.isdir(d):
os.mkdir(d)
except Exception as e:
......@@ -153,7 +186,7 @@ class SourceImage(Image):
raise NotImplementedError("SourceImage must be local")
Image.__init__(self)
self.base_path = os.path.abspath(path)
for pathtype in ("build", "parser", "setup", "payload"):
for pathtype in ("build", "parser", "setup", "payload", "lib"):
setattr(self, u"%s_path" % pathtype, os.path.join(self.base_path, pathtype))
self.check_source_image()
self.description = self.parse_description()
......@@ -168,7 +201,7 @@ class SourceImage(Image):
Check if we are a valid SourceImage directories
'''
for d in (self.base_path, self.build_path, self.parser_path,
self.setup_path, self.payload_path):
self.setup_path, self.payload_path, self.lib_path):
if not os.path.exists(d):
raise ISError(u"Invalid source image: directory %s is missing" % d)
if not os.path.isdir(d):
......@@ -187,9 +220,9 @@ class SourceImage(Image):
raise ISError("Tarball already exists. Remove it before")
# check python scripts
if check:
self.check_scripts(self.build_path)
self.check_scripts(self.parser_path)
self.check_scripts(self.setup_path)
for d in (self.build_path, self.parser_path, self.setup_path,
self.lib_path):
self.check_scripts(d)
# remove list
rl = set()
# run build script
......@@ -235,6 +268,8 @@ class SourceImage(Image):
self.add_scripts(tarball, self.parser_path)
# add setup scripts
self.add_scripts(tarball, self.setup_path)
# add lib
self.add_scripts(tarball, self.lib_path)
# closing tarball file
tarball.close()
except (SystemExit, KeyboardInterrupt):
......@@ -421,6 +456,11 @@ class SourceImage(Image):
rebuild_list = []
cwd = os.getcwd()
arrowlevel(1)
# load modules
lib_list = [fp.encode(locale.getpreferredencoding())
for fp, fn in self.select_scripts(self.lib_path)]
func = lambda f: open(f).read()
modules = self._load_modules(lib_list, func)
for fp, fn in self.select_scripts(script_directory):
arrow(fn)
os.chdir(exec_directory)
......@@ -433,6 +473,8 @@ class SourceImage(Image):
# define execution context
gl = {"rebuild": rebuild_list,
"image": self}
# add embedded modules
gl.update(modules)
# execute source code
try:
exec o_scripts in gl
......@@ -845,6 +887,9 @@ class PackageImage(Image):
'''
arrow(u"Run %s scripts" % directory)
arrowlevel(1)
# load modules
lib_list = self._tarball.getnames(re_pattern="lib/.*\.py")
modules = self._load_modules(lib_list, self._tarball.get_str)
# get list of parser scripts
l_scripts = self._tarball.getnames(re_pattern="%s/.*\.py" % directory)
# order matter!
......@@ -868,6 +913,8 @@ class PackageImage(Image):
for k in kwargs:
gl[k] = kwargs[k]
gl["image"] = self
# Add embedded modules
gl.update(modules)
# execute source code
try:
exec o_scripts in gl
......
......@@ -21,6 +21,7 @@ InstallSystems Generic Tools Library
'''
import hashlib
import imp
import jinja2
import locale
import math
......@@ -669,3 +670,19 @@ def render_templates(target, context, tpl_ext=".istpl", force=False, keep=False)
os.chmod(file_path, st.st_mode)
if not keep:
os.unlink(tpl_path)
def string2module(name, code, filename):
'''
Create a python module from a string
'''
# create an empty module
module = imp.new_module(name)
# compile module code
try:
bytecode = compile(code, filename, "exec")
except Exception as e:
raise ISError(u"Unable to compile %s fail: %s" %
(filename, e))
# fill module
exec bytecode in module.__dict__
return module
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment