Molecule:

- first chunk of code
- general infrastructure done
- spec file parser done


git-svn-id: http://svn.sabayonlinux.org/projects/molecule/trunk@2977 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
lxnay
2009-01-31 21:57:47 +00:00
commit 1cda81a93d
9 changed files with 964 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
# Molecule example .spec file
# pre chroot command, example, for 32bit chroots on 64bit system, you always have to append "linux32"
# prechroot: linux32
# Release string
# release_string: Sabayon Linux
# Release Version
# release_version: 4
# Release Version string description
# release_desc: Lite MCE
# Release file (inside chroot)
# release_file: /etc/sabayon-edition
# Source chroot directory, where files are pulled from
# source_chroot: /var/tmp/catalyst/tmp/stage1-amd64-2006.0
# Destination chroot directory, where files are pushed to before creating the squashfs image
# destination_chroot: /var/tmp/catalyst/tmp/stage1-amd64-2006.0/default/livecd-stage2-amd64-2006.0
# Merge directory with destination chroot
# merge_destination_chroot: /path/to/your/chroot/overlay
# Outer chroot script command, to be executed outside destination chroot before packing it
# outer_chroot_script: /path/to/script/to/be/executed/outside
# Inner chroot script command, to be executed inside destination chroot before packing it
# inner_chroot_script: /path/to/script/to/be/executed/inside
# Destination LiveCD root directory, where files are placed before getting mkisofs'ed
# destination_livecd_root: /path/to/dest/livecd
# Merge directory with destination LiveCD root
# merge_livecd_root: /path/to/your/configured/bootloader dir
# Extra mksquashfs parameters
# extra_mksquashfs_parameters:
# Extra mkisofs parameters, perhaps something to include/use your bootloader
# extra_mkisofs_parameters:
# Destination directory for the ISO image path
# destination_iso_directory:
# Destination ISO image name, call whatever you want.iso, not mandatory
# destination_iso_image_name:
# Directories to remove completely (comma separated)
# directories_to_remove: /path/to/abc, /path/to/xyz,
# Directories to empty (comma separated)
# directories_to_empty: /path/to/abc, /path/to/xyz,
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
import sys
sys.path.insert(0,'molecule/')
import molecule.settings
import molecule.cmdline
molecule_data = molecule.cmdline.parse()
if not molecule_data:
molecule.cmdline.print_help()
raise SystemExit(1)
print "valid",molecule_data
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
import molecule.settings
Config = molecule.settings.Configuration()
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
import os
import sys
import molecule.utils
import molecule.output
from molecule.i18n import _
from molecule import Config
from molecule.settings import SpecParser
def parse():
args_to_remove = ["--nocolor"]
data = {}
myargs = sys.argv[1:]
if "--help" in myargs:
return data
if "--nocolor" in myargs:
molecule.output.nocolor()
for arg in args_to_remove:
if arg in myargs: myargs.remove(arg)
for el in myargs:
if os.path.isfile(el) and os.access(el,os.R_OK):
obj = SpecParser(el)
el_data = obj.parse()
del obj
if el_data: data[el] = el_data
return data
def print_help():
help_data = [
None,
(0," ~ Molecule %s ~ " % (Config.get('version'),) ,1,'Disc Image builder for Sabayon Linux - (C) %s' % (molecule.utils.get_year(),) ),
None,
(0,_('Basic Options'),0,None),
None,
(1,'--help',2,_('this output')),
(1,'--nocolor',1,_('disable colorized output')),
None,
(0,_('Application Options'),0,None),
(1,'<spec file path 1> <spec file path 2> ...',1,_('execute against specified specification files')),
None,
]
molecule.output.print_menu(help_data)
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
class MoleculeException(Exception):
"""General superclass for Entropy exceptions"""
def __init__(self,value):
self.value = value[:]
def __str__(self):
if isinstance(self.value, basestring):
return self.value
else:
return repr(self.value)
class EnvironmentError(MoleculeException):
"""Environment error, self explanatory"""
class SpecFileError(MoleculeException):
"""Error inside spec file"""
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/python
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
License: GPL
Author: Fabio Erculiani <lxnay@sabayonlinux.org>
"""
_LOCALE = None
try:
import gettext
import os
gettext.bindtextdomain('molecule', '/usr/share/locale')
gettext.textdomain('molecule')
gettext.install('molecule', unicode = True)
_ = _
_LOCALE_FULL = os.getenv('LC_ALL')
if _LOCALE_FULL == None:
_LOCALE_FULL = os.getenv('LANG')
if _LOCALE_FULL == None:
_LOCALE_FULL = os.getenv('LANGUAGE')
if _LOCALE_FULL:
_LOCALE = _LOCALE_FULL.split('.')[0]
_LOCALE = _LOCALE.split('_')[0]
_LOCALE = _LOCALE.lower()
except:
def _(s):
return s
+402
View File
@@ -0,0 +1,402 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# Copyright 1998-2004 Gentoo Foundation
# # $Id: output.py 4906 2006-11-01 23:55:29Z zmedico $
# Copyright (C) 2007-2008 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
from molecule.i18n import _
import sys, os
import curses
stuff = {}
stuff['cols'] = 30
try:
curses.setupterm()
stuff['cols'] = curses.tigetnum('cols')
except:
pass
stuff['cleanline'] = ""
def setcols():
stuff['cleanline'] = ""
count = stuff['cols']
while count:
stuff['cleanline'] += ' '
count -= 1
setcols()
stuff['cursor'] = False
stuff['ESC'] = chr(27)
havecolor=1
global dotitles
dotitles=1
esc_seq = "\x1b["
g_attr = {}
g_attr["normal"] = 0
g_attr["bold"] = 1
g_attr["faint"] = 2
g_attr["standout"] = 3
g_attr["underline"] = 4
g_attr["blink"] = 5
g_attr["overline"] = 6 # Why is overline actually useful?
g_attr["reverse"] = 7
g_attr["invisible"] = 8
g_attr["no-attr"] = 22
g_attr["no-standout"] = 23
g_attr["no-underline"] = 24
g_attr["no-blink"] = 25
g_attr["no-overline"] = 26
g_attr["no-reverse"] = 27
# 28 isn't defined?
# 29 isn't defined?
g_attr["black"] = 30
g_attr["red"] = 31
g_attr["green"] = 32
g_attr["yellow"] = 33
g_attr["blue"] = 34
g_attr["magenta"] = 35
g_attr["cyan"] = 36
g_attr["white"] = 37
# 38 isn't defined?
g_attr["default"] = 39
g_attr["bg_black"] = 40
g_attr["bg_red"] = 41
g_attr["bg_green"] = 42
g_attr["bg_yellow"] = 43
g_attr["bg_blue"] = 44
g_attr["bg_magenta"] = 45
g_attr["bg_cyan"] = 46
g_attr["bg_white"] = 47
g_attr["bg_default"] = 49
def color(fg, bg="default", attr=["normal"]):
mystr = esc_seq[:] + "%02d" % g_attr[fg]
for x in [bg]+attr:
mystr += ";%02d" % g_attr[x]
return mystr+"m"
codes={}
codes["reset"] = esc_seq + "39;49;00m"
codes["bold"] = esc_seq + "01m"
codes["faint"] = esc_seq + "02m"
codes["standout"] = esc_seq + "03m"
codes["underline"] = esc_seq + "04m"
codes["blink"] = esc_seq + "05m"
codes["overline"] = esc_seq + "06m" # Who made this up? Seriously.
ansi_color_codes = []
for x in xrange(30, 38):
ansi_color_codes.append("%im" % x)
ansi_color_codes.append("%i;01m" % x)
rgb_ansi_colors = ['0x000000', '0x555555', '0xAA0000', '0xFF5555', '0x00AA00',
'0x55FF55', '0xAA5500', '0xFFFF55', '0x0000AA', '0x5555FF', '0xAA00AA',
'0xFF55FF', '0x00AAAA', '0x55FFFF', '0xAAAAAA', '0xFFFFFF']
for x in xrange(len(rgb_ansi_colors)):
codes[rgb_ansi_colors[x]] = esc_seq + ansi_color_codes[x]
del x
codes["black"] = codes["0x000000"]
codes["darkgray"] = codes["0x555555"]
codes["red"] = codes["0xFF5555"]
codes["darkred"] = codes["0xAA0000"]
codes["green"] = codes["0x55FF55"]
codes["darkgreen"] = codes["0x00AA00"]
codes["yellow"] = codes["0xFFFF55"]
codes["brown"] = codes["0xAA5500"]
codes["blue"] = codes["0x5555FF"]
codes["darkblue"] = codes["0x0000AA"]
codes["fuchsia"] = codes["0xFF55FF"]
codes["purple"] = codes["0xAA00AA"]
codes["turquoise"] = codes["0x55FFFF"]
codes["teal"] = codes["0x00AAAA"]
codes["white"] = codes["0xFFFFFF"]
codes["lightgray"] = codes["0xAAAAAA"]
codes["darkteal"] = codes["turquoise"]
codes["darkyellow"] = codes["brown"]
codes["fuscia"] = codes["fuchsia"]
codes["white"] = codes["bold"]
# Colors from /sbin/functions.sh
codes["GOOD"] = codes["green"]
codes["WARN"] = codes["yellow"]
codes["BAD"] = codes["red"]
codes["HILITE"] = codes["teal"]
codes["BRACKET"] = codes["blue"]
# Portage functions
codes["INFORM"] = codes["darkgreen"]
codes["UNMERGE_WARN"] = codes["red"]
codes["MERGE_LIST_PROGRESS"] = codes["yellow"]
def xtermTitle(mystr, raw=False):
if dotitles and "TERM" in os.environ and sys.stderr.isatty():
myt=os.environ["TERM"]
legal_terms = ["xterm","Eterm","aterm","rxvt","screen","kterm","rxvt-unicode","gnome"]
if myt in legal_terms:
if not raw:
mystr = "\x1b]0;%s\x07" % mystr
try:
sys.stderr.write(mystr)
except UnicodeEncodeError:
sys.stderr.write(mystr.encode('utf-8'))
sys.stderr.flush()
default_xterm_title = None
def xtermTitleReset():
global default_xterm_title
if default_xterm_title is None:
prompt_command = os.getenv('PROMPT_COMMAND')
if prompt_command == "":
default_xterm_title = ""
elif prompt_command is not None:
import commands
default_xterm_title = commands.getoutput(prompt_command)
else:
pwd = os.getenv('PWD','')
home = os.getenv('HOME', '')
if home != '' and pwd.startswith(home):
pwd = '~' + pwd[len(home):]
default_xterm_title = '\x1b]0;%s@%s:%s\x07' % (
os.getenv('LOGNAME', ''), os.getenv('HOSTNAME', '').split('.', 1)[0], pwd)
xtermTitle(default_xterm_title, raw=True)
def notitles():
"turn off title setting"
global dotitles
dotitles=0
def nocolor():
"turn off colorization"
os.environ['MOL_NO_COLOR'] = "1"
global havecolor
havecolor=0
nc = os.getenv("MOL_NO_COLOR")
if nc:
nocolor()
def resetColor():
return codes["reset"]
def colorize(color_key, text):
global havecolor
if havecolor:
return codes[color_key] + text + codes["reset"]
else:
return text
compat_functions_colors = ["bold","white","teal","turquoise","darkteal",
"fuscia","fuchsia","purple","blue","darkblue","green","darkgreen","yellow",
"brown","darkyellow","red","darkred"]
def create_color_func(color_key):
def derived_func(*args):
newargs = list(args)
newargs.insert(0, color_key)
return colorize(*newargs)
return derived_func
for c in compat_functions_colors:
setattr(sys.modules[__name__], c, create_color_func(c))
def print_menu(data):
def orig_myfunc(x):
return x
def orig_myfunc_desc(x):
return x
for item in data:
myfunc = orig_myfunc
myfunc_desc = orig_myfunc_desc
if not item:
writechar("\n")
else:
n_ident = item[0]
name = item[1]
n_d_ident = item[2]
desc = item[3]
if n_ident == 0:
writechar(" ")
# setup identation
while n_ident > 0:
n_ident -= 1
writechar("\t")
n_ident = item[0]
# write name
if n_ident == 0:
myfunc = darkgreen
elif n_ident == 1:
myfunc = blue
myfunc_desc = darkgreen
elif n_ident == 2:
if not name.startswith("--"):
myfunc = red
myfunc_desc = brown
elif n_ident == 3:
myfunc = darkblue
myfunc_desc = purple
try:
print myfunc(name),
except UnicodeEncodeError:
print myfunc(name.encode('utf-8')),
# write desc
if desc:
while n_d_ident > 0:
n_d_ident -= 1
writechar("\t")
try:
print myfunc_desc(desc),
except UnicodeEncodeError:
print myfunc_desc(desc.encode('utf-8')),
writechar("\n")
def reset_cursor():
if havecolor:
sys.stdout.write(stuff['ESC'] + '[2K')
flush_stdouterr()
def flush_stdouterr():
sys.stdout.flush()
sys.stderr.flush()
def print_error(msg, back = False, flush = True):
if not back: setcols()
reset_cursor()
writechar("\r")
if back:
try:
print darkred(">>"),msg,
except UnicodeEncodeError:
print darkred(">>"),msg.encode('utf-8'),
else:
try:
print darkred(">>"),msg
except UnicodeEncodeError:
print darkred(">>"),msg.encode('utf-8')
if flush:
flush_stdouterr()
def print_info(msg, back = False, flush = True):
if not back:
setcols()
reset_cursor()
writechar("\r")
if back:
try:
print darkgreen(">>"),msg,
except UnicodeEncodeError:
print darkgreen(">>"),msg.encode('utf-8'),
else:
try:
print darkgreen(">>"),msg
except UnicodeEncodeError:
print darkgreen(">>"),msg.encode('utf-8')
if flush:
flush_stdouterr()
def print_warning(msg, back = False, flush = True):
if not back: setcols()
reset_cursor()
writechar("\r")
if back:
try:
print red(">>"),msg,
except UnicodeEncodeError:
print red(">>"),msg.encode('utf-8'),
else:
try:
print red(">>"),msg
except UnicodeEncodeError:
print red(">>"),msg.encode('utf-8')
if flush:
flush_stdouterr()
def print_generic(msg): # here we'll wrap any nice formatting
writechar("\r")
try:
print msg
except UnicodeEncodeError:
print msg.encode('utf-8')
flush_stdouterr()
def writechar(char):
try:
sys.stdout.write(char)
sys.stdout.flush()
except IOError, e:
if e.errno == 32:
return
raise
def readtext(request, password = False):
xtermTitle(_("Molecule needs your attention"))
if password:
from getpass import getpass
try:
text = getpass(request+" ")
except UnicodeEncodeError:
text = getpass(request.encode('utf-8')+" ")
else:
try:
print request,"",
except UnicodeEncodeError:
print request.encode('utf-8'),"",
flush_stdouterr()
text = my_raw_input()
return text
def my_raw_input(txt = ''):
if txt:
try:
print darkgreen(txt),
except UnicodeEncodeError:
print darkgreen(txt.encode('utf-8')),
flush_stdouterr()
response = ''
while 1:
y = sys.stdin.read(1)
if y in ('\n','\r',): break
response += y
flush_stdouterr()
return response
+270
View File
@@ -0,0 +1,270 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
from __future__ import with_statement
import os
import threading
from molecule.exception import SpecFileError, EnvironmentError
import molecule.utils
class Dictionary:
def __init__(self):
self._settings = {}
self.L = threading.Lock()
def __setitem__(self, key, value):
with self.L:
self._settings[key] = value
def __getitem__(self, key):
with self.L:
return self._settings[key]
def __contains__(self, key):
with self.L:
return key in self._settings
def __cmp__(self, other):
with self.L:
return cmp(self._settings,other)
def __str__(self):
with self.L:
return str(self._settings)
def get(self, key):
with self.L:
return self._settings.get(key)
def has_key(self, key):
with self.L:
return self._settings.has_key(key)
def clear(self):
with self.L:
self._settings.clear()
def keys(self):
with self.L:
return self._settings.keys()
class Constants(Dictionary):
def __init__(self):
Dictionary.__init__(self)
self.load()
def load(self):
with self.L:
ETC_DIR = '/etc'
CONFIG_FILE_NAME = 'molecule.conf'
mysettings = {
'config_file': os.path.join(ETC_DIR, CONFIG_FILE_NAME),
}
self._settings.clear()
self._settings.update(mysettings)
class Configuration(Dictionary):
def __init__(self):
Dictionary.__init__(self)
self.Constants = Constants()
self.load()
def load(self, mysettings = {}):
with self.L:
settings = {
'version': "0.1",
'chroot_compressor': "mksquashfs",
'iso_builder': "mkisofs",
'iso_builder_builtin_args': ["-J","-R","-l","-no-emul-boot","-boot-load-size","4","-udf","-boot-info-table"],
}
self._settings.clear()
self._settings.update(settings)
self._settings.update(mysettings)
paths_to_check = ["chroot_compressor","iso_builder"]
for key in paths_to_check:
molecule.utils.valid_exec_check(self.get(key))
class SpecParser:
def __init__(self, filepath):
def ne_string(x):
return x
def always_valid(*args):
return True
def valid_path(x):
return os.path.lexists(x)
def valid_file(x):
return os.path.isfile(x)
def valid_dir(x):
return os.path.isdir(x)
def ve_string_stripper(x):
return x.strip()
def ve_string_splitter(x):
return x.strip().split()
def valid_exec(x):
molecule.utils.is_exec_available(x)
return True
def valid_ascii(x):
try:
x = str(x)
return x
except (UnicodeDecodeError,UnicodeEncodeError,):
return ''
def valid_path_string(x):
try:
os.path.split(x)
except OSError:
return False
return True
def valid_path_list(x):
return [x for x in x.split(",") if valid_path_string(x)]
self.vital_parameters = [
"release_string",
"source_chroot",
"destination_iso_directory",
]
self.parser_data_path = {
'prechroot': {
'cb': valid_exec,
've': ve_string_stripper,
},
'release_string': {
'cb': ne_string, # validation callback
've': ve_string_stripper, # value extractor
},
'release_version': {
'cb': ne_string,
've': ve_string_stripper,
},
'release_desc': {
'cb': ne_string,
've': ve_string_stripper,
},
'release_file': {
'cb': ne_string,
've': ve_string_stripper,
},
'source_chroot': {
'cb': valid_dir,
've': ve_string_stripper,
},
'destination_chroot': {
'cb': valid_path_string,
've': ve_string_stripper,
},
'merge_destination_chroot': {
'cb': valid_dir,
've': ve_string_stripper,
},
'outer_chroot_script': {
'cb': valid_exec,
've': ve_string_stripper,
},
'inner_chroot_script': {
'cb': valid_path_string,
've': ve_string_stripper,
},
'destination_livecd_root': {
'cb': valid_path_string,
've': ve_string_stripper,
},
'merge_livecd_root': {
'cb': valid_dir,
've': ve_string_stripper,
},
'extra_mksquashfs_parameters': {
'cb': always_valid,
've': ve_string_splitter,
},
'extra_mkisofs_parameters': {
'cb': always_valid,
've': ve_string_splitter,
},
'destination_iso_directory': {
'cb': valid_dir,
've': ve_string_stripper,
},
'destination_iso_image_name': {
'cb': valid_ascii,
've': ve_string_stripper,
},
'directories_to_remove': {
'cb': valid_path_list,
've': ve_string_stripper,
},
'directories_to_empty': {
'cb': valid_path_list,
've': ve_string_stripper,
},
}
self.filepath = filepath[:]
def parse(self):
mydict = {}
data = self.__generic_parser(self.filepath)
for line in data:
try:
key, value = line.split(":",1)
except (ValueError, IndexError,):
continue
key = key.strip()
check_dict = self.parser_data_path.get(key)
if not isinstance(check_dict,dict): continue
value = check_dict['ve'](value)
if not check_dict['cb'](value): continue
mydict[key] = value
self.validate_parse(mydict)
return mydict.copy()
def validate_parse(self, mydata):
for param in self.vital_parameters:
if param not in mydata:
raise SpecFileError("SpecFileError: '%s' missing or invalid '%s' parameter, it's vital. Your specification file is incomplete!" % (self.filepath,param,))
def __generic_parser(self, filepath):
with open(filepath,"r") as f:
data = []
content = f.readlines()
f.close()
# filter comments and white lines
content = [x.strip().rsplit("#",1)[0].strip() for x in content if not x.startswith("#") and x.strip()]
for line in content:
if line in data: continue
data.append(line)
return data
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/python -O
# -*- coding: iso-8859-1 -*-
# Molecule Disc Image builder for Sabayon Linux
# Copyright (C) 2009 Fabio Erculiani
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
from __future__ import with_statement
import os
import time
import subprocess
from molecule.exception import EnvironmentError
def get_year():
return time.strftime("%Y")
def valid_exec_check(path):
with open("/dev/null","w") as f:
p = subprocess.Popen([path], stdout = f, stderr = f)
rc = p.wait()
if rc == 127:
raise EnvironmentError("EnvironmentError: %s not found" % (path,))
def is_exec_available(exec_name):
paths = os.getenv("PATH")
if not paths: return False
paths = paths.split(":")
for path in paths:
path = os.path.join(path,exec_name)
if os.path.isfile(path) and os.access(path,os.X_OK):
return True
return False