diff options
-rw-r--r-- | .gitignore | 31 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README (renamed from README.md) | 28 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | demo/configurations.yaml | 28 | ||||
-rw-r--r-- | demo/netbook/meego-netbook.yaml | 17 | ||||
-rw-r--r-- | kickstarter.spec | 34 | ||||
-rw-r--r-- | kswriter/KSWriter.py | 172 | ||||
-rw-r--r-- | kswriter/__init__.py | 1 | ||||
-rw-r--r-- | packaging/kickstarter.changes | 42 | ||||
-rw-r--r-- | packaging/kickstarter.manifest | 5 | ||||
-rw-r--r-- | packaging/kickstarter.spec | 19 | ||||
-rw-r--r-- | setup.py | 24 | ||||
-rwxr-xr-x | tools/kickstarter | 149 |
14 files changed, 265 insertions, 294 deletions
diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c54e5cf..0000000 --- a/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -kickstart/__init__.py -kickstart/kickstart.py -*~ - -*.py[co] - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox - -#Translations -*.mo - -#Mr Developer -.mr.developer.cfg @@ -22,10 +22,6 @@ all: tmpls tmpls: cd kickstart; make -install: tmpls - python setup.py build - python setup.py install - %.py: %.tmpl $(CHEETAH) compile --settings='useStackFrames=False' $< @@ -50,4 +46,3 @@ clean: rm -f $(addsuffix .bak,$(TEMPLATE_MODS)) rm -f *.pyc *.pyo rm -rf dist/ build/ kickstart/kickstart.py kickstart/__init__.py *~ */*~ - rm -rf *.egg-info/ @@ -1,36 +1,20 @@ -kickstarter -=========== - -Kickstart file generator based on YAML formated meta data - -Installation ------------- - Install cheetah (http://www.cheetahtemplate.org/) templating system, PyYAML. run make sudo python setup.py install - -Usage ------ - +then run: kickstarter -c <images.yaml> -r <repos.yaml> Example: + kickstarter --configs configurations.yaml --repos repos.yaml - kickstarter --configs configurations.yaml --repos repos.yaml - -This configuration.yaml file is an example only, for meego kickstart files, -consult the image-configurations package - -Repo file ---------- + This configuration.yaml file is an example only, for meego kickstart files, + consult the image-configurations package +Repo file: This file contains a list of repositories to be used in the kickstart files -Configurations file -------------------- - +Configurations file: This file has the definition of configurations. The Configurations inherit from platforms first then from the DEFAULT section. The image configurations override the all other settings (in DEFAULT and platform sections). @@ -1,4 +1,8 @@ + List of things to do: + + - Add support for build IDs (partially done) + - Multi arch repos (partially done) - Support kickstart magic Add addition options per image to describe how it should be created, i.e. image type and other options The generated kickstart files should then have the line on top that can be evaluated by mic diff --git a/demo/configurations.yaml b/demo/configurations.yaml index b7d91ed..52049f4 100644 --- a/demo/configurations.yaml +++ b/demo/configurations.yaml @@ -1,9 +1,7 @@ ExternalConfigs: - - netbook - + - ex Default: Active: True - Baseline: tizen-0.99 Language: en_US.UTF-8 Keyboard: us PackageArgs: @@ -118,6 +116,7 @@ NETBOOK: Configurations: - Name: MeeGo IVI Development Active: True + Baseline: "1.1.80" Platform: IVI Desktop: X-IVI FileName: ivi-ia32 @@ -134,6 +133,7 @@ Configurations: - mesa-libEGL - Name: MeeGo IVI Active: True + Baseline: "1.1.80" Platform: IVI Desktop: X-IVI FileName: ivi-ia32 @@ -147,9 +147,27 @@ Configurations: - ivi ExtraPackages: - mesa-libEGL + - Name: MeeGo Netbook/Nettop + PartSize: 3000 + Active: True + Baseline: "1.1.80" + Platform: NETBOOK + Desktop: meego + FileName: netbook-ia32 + Mic2Options: -f livecd + Groups: + - MeeGo Netbook Desktop + - Base Double Byte IME Support + - MeeGo Base Development + Repos: + - core + - netbook + ExtraPackages: + - chromium - Name: MeeGo Handset N900 Development Part: n900-devel Active: True + Baseline: "1.1.80" Platform: N900 FileName: handset-armv7l-n900-devel Mic2Options: -f raw --save-kernel --arch=armv7l @@ -169,6 +187,7 @@ Configurations: - u-boot - Name: MeeGo Handset N900 Active: True + Baseline: "1.1.80" Platform: N900 FileName: handset-armv7l-n900 Mic2Options: -f raw --save-kernel --arch=armv7l @@ -189,6 +208,7 @@ Configurations: - Name: MeeGo Handset MTF Development PartSize: 2200 Active: True + Baseline: "1.1.80" Platform: MFLD FileName: handset-ia32-mtf-devel Mic2Options: -f nand @@ -205,6 +225,7 @@ Configurations: - serial-mfld - Name: MeeGo Handset MTF Pinetrail Active: True + Baseline: "1.1.80" Platform: MFLD FileName: handset-ia32-pinetrail-mtf Mic2Options: -f livecd @@ -215,6 +236,7 @@ Configurations: - Name: MeeGo Handset MTF Schedule: "* * * * 3" Active: True + Baseline: "1.1.80" Platform: MFLD FileName: handset-ia32-mtf Mic2Options: -f nand diff --git a/demo/netbook/meego-netbook.yaml b/demo/netbook/meego-netbook.yaml deleted file mode 100644 index 2c1e16a..0000000 --- a/demo/netbook/meego-netbook.yaml +++ /dev/null @@ -1,17 +0,0 @@ -Name: MeeGo Netbook/Nettop -PartSize: 2580 -Active: True -Baseline: "1.1.80" -Platform: NETBOOK -Desktop: meego -FileName: netbook-ia32 -Mic2Options: -f livecd -Groups: - - MeeGo Netbook Desktop - - Base Double Byte IME Support - - MeeGo Base Development -Repos: - - core - - netbook -ExtraPackages: - - chromium diff --git a/kickstarter.spec b/kickstarter.spec new file mode 100644 index 0000000..fc24889 --- /dev/null +++ b/kickstarter.spec @@ -0,0 +1,34 @@ +Summary: Create kickstart files for meego images +Name: kickstarter +Version: 0.15 +Release: 1 +License: GPLv2 +Group: System/Base +URL: http://www.meego.com +Source: %{name}-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildArch: noarch +Requires: PyYAML +Requires: python-urlgrabber +Requires: python-cheetah +BuildRequires: python-devel +BuildRequires: python-cheetah + +%description +Create Configuration files to build meego images + +%prep +%setup -q + +%build + +%install +rm -rf $RPM_BUILD_ROOT + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc GPL + diff --git a/kswriter/KSWriter.py b/kswriter/KSWriter.py deleted file mode 100644 index 5e840ac..0000000 --- a/kswriter/KSWriter.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/python -import copy -import time -import yaml -import os, re -import sys -import errno -from urlparse import urlparse - -from kickstart import kickstart - -def mkdir_p(path): - try: - os.makedirs(path) - except OSError as exc: # Python >2.5 - if exc.errno == errno.EEXIST: - pass - else: raise - -class KSWriter(): - def __init__(self, configs=None, repos=None, outdir=".", config=None, packages=False): - self.dist = None - self.arch = None - self.image_filename = os.path.abspath(os.path.expanduser(configs)) - self.repo_filename = repos - self.outdir = outdir - self.packages = packages - self.config = config - self.image_stream = file(self.image_filename, 'r') - self.repo_stream = file(self.repo_filename, 'r') - self.extra = {} - self.repo_meta = yaml.load(self.repo_stream) - self.image_meta = yaml.load(self.image_stream) - - def merge(*input): - return list(reduce(set.union, input, set())) - - def dump(self): - print yaml.dump(yaml.load(self.stream)) - - def parse(self, img): - conf = copy.copy(self.image_meta['Default']) - plat = copy.copy(self.image_meta[img['Platform']]) - conf.update(plat) - conf.update(img) - lval = ['Repos', 'Groups', 'PostScripts', 'NoChrootScripts', 'RemovePackages', 'ExtraPackages'] - lvald = {} - for l in lval: - full = [] - if self.image_meta['Default'].has_key(l) and self.image_meta['Default'][l]: - full = full + self.image_meta['Default'][l] - if plat.has_key(l) and plat[l]: - full = full + plat[l] - if img.has_key(l) and img[l]: - full = full + img[l] - lvald[l] = sorted(set(full), key=full.index) - conf.update(lvald) - postscript = "" - meta_root = os.path.dirname(self.image_filename) - for scr in conf['PostScripts']: - if os.path.exists('%s/custom/scripts/%s.post' %(meta_root, scr)): - f = open('%s/custom/scripts/%s.post' %(meta_root, scr), 'r') - postscript += f.read() - postscript += "\n" - f.close() - else: - print '%s/custom/scripts/%s.post not found, skipping.' %(meta_root,scr ) - - nochrootscript = "" - for scr in conf['NoChrootScripts']: - if os.path.exists('%s/custom/scripts/%s.nochroot' %(meta_root,scr)): - f = open('%s/custom/scripts/%s.nochroot' %(meta_root, scr ), 'r') - nochrootscript += f.read() - nochrootscript += "\n" - f.close() - else: - print '%s/custom/scripts/%s.nochroot not found, skipping.' %(meta_root, scr ) - - ptab = "" - for g in [ plat, img ]: - if g.has_key("Part"): - f = open("%s/custom/part/%s" %(meta_root, g['Part']) ) - ptab = f.read() - f.close() - - conf['Part'] = ptab - conf['Post'] = postscript - conf['NoChroot'] = nochrootscript - return conf - - def process_files(self, meta, repos): - new_repos = [] - if ( meta.has_key("Architecture") and meta['Architecture'] ) or ( meta.has_key("Distribution") and meta['Distribution']): - for repo in repos: - r = {} - r['Name'] = repo['Name'] - repourl = repo['Url'] - if repo.has_key('Options'): - r['Options'] = repo['Options'] - if meta.has_key("Architecture") or self.arch: - repourl = repourl.replace("@ARCH@", self.arch or meta['Architecture']) - if meta.has_key("Distribution") or self.dist: - repourl = repourl.replace("@DIST@", self.dist or meta['Distribution']) - - url = repourl.replace("@RELEASE@", meta['Baseline']) - o = urlparse(url) - new_url = "%s://" % o[0] - if repo.has_key('Username') and repo['Username']: - new_url = "%s%s" % (new_url, repo['Username'] ) - if repo.has_key('Password') and repo['Password']: - new_url = "%s:%s@" % (new_url, repo['Password'] ) - r['Url'] = "%s%s%s" % (new_url, o[1], o[2] ) - new_repos.append(r) - else: - new_repos = repos - - nameSpace = {'metadata': meta, 'repos': new_repos} - t = kickstart(searchList=[nameSpace]) - a = str(t) - if meta.has_key('FileName') and meta['FileName']: - f = None - if meta.has_key("Baseline"): - mkdir_p("%s/%s" %(self.outdir, meta['Baseline'])) - f = open("%s/%s/%s.ks" %( self.outdir, meta['Baseline'], meta['FileName'] ), 'w') - else: - f = open("%s/%s.ks" %( self.outdir, meta['FileName'] ), 'w') - f.write(a) - f.close() - - def generate(self): - out = {} - repos = self.repo_meta['Repositories'] - if self.image_meta.has_key('Configurations'): - for img in self.image_meta['Configurations']: - conf = self.parse(img) - if self.config: - if img.has_key('FileName') and self.config == img['FileName']: - print "Creating %s (%s.ks)" %(img['Name'], img['FileName'] ) - self.process_files(conf, repos) - break - else: - if conf.has_key('Active') and conf['Active'] : - print "Creating %s (%s.ks)" %(img['Name'], img['FileName'] ) - self.process_files(conf, repos) - else: - print "%s is inactive, not generating %s at this time" %(img['Name'], img['FileName'] ) - for path in self.image_meta['ExternalConfigs']: - external_config_dir = os.path.join(os.path.dirname(self.image_filename), path) - for f in os.listdir(external_config_dir): - if f.endswith('.yaml'): - fp = file('%s/%s' %(external_config_dir, f), 'r') - local = yaml.load(fp) - conf = self.parse(local) - if self.config: - if self.config == conf['FileName']: - if self.packages: - out['baseline'] = conf['Baseline'] - out['groups'] = conf['Groups'] - out['packages'] = conf['ExtraPackages'] - else: - print "Creating %s (%s.ks)" %(conf['Name'], conf['FileName'] ) - self.process_files(conf, repos) - break - else: - if conf.has_key('Active') and conf['Active']: - print "Creating %s (%s.ks)" %(conf['Name'], conf['FileName'] ) - self.process_files(conf, repos) - else: - print "%s is inactive, not generate %s this time" %(conf['Name'], conf['FileName'] ) - else: - print "WARNING: File '%s' ignored." % (f) - return out diff --git a/kswriter/__init__.py b/kswriter/__init__.py deleted file mode 100644 index 82212cb..0000000 --- a/kswriter/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from KSWriter import KSWriter diff --git a/packaging/kickstarter.changes b/packaging/kickstarter.changes new file mode 100644 index 0000000..a23d97d --- /dev/null +++ b/packaging/kickstarter.changes @@ -0,0 +1,42 @@ +* Fri May 18 2012 Jian-feng Ding <jian-feng.ding@intel.com> - 0.15 +- update to latest + +* Mon Jul 04 2011 Li Yi <yix.li@intel.com> - 0.12 +- make Active keyword works + +* Fri May 27 2011 Anas Nashif <anas.nashif@intel.com> - 0.11 +- enhance bootloader option support + +* Wed May 18 2011 Anas Nashif <anas.nashif@intel.com> - 0.10 +- Support bootloader options (bmc #16408) + +* Fri May 06 2011 Anas Nashif <anas.nashif@intel.com> - 0.9 +- Now require python-yaml + +* Mon May 02 2011 Anas Nashif <anas.nashif@intel.com> - 0.9 +- Fixed bmc #16397 - temporary .yaml~ files are read + +* Sat Apr 02 2011 Anas Nashif <anas.nashif@intel.com> - 0.8 +- Support external configurations +- Support additional keywords to keep up with static ks files +- 0.8 + +* Fri Mar 18 2011 Anas Nashif <anas.nashif@intel.com> - 0.7 +- Fix schedule handling. + +* Thu Mar 17 2011 Anas Nashif <anas.nashif@intel.com> - 0.6 +- Use cron style syntax for schedule +- Fixed path where files are stored on repo + +* Wed Mar 16 2011 Anas Nashif <anas.nashif@intel.com> - 0.5 +- Add python-lxml as a runtime dependency + +* Wed Mar 16 2011 Anas Nashif <anas.nashif@intel.com> - 0.5 +- Create index file with all kickstart files + +* Sun Feb 06 2011 Anas Nashif <anas.nashif@intel.com> - 0.4 +- Make it build on other distros + +* Wed Jan 26 2011 Anas Nashif <anas.nashif@intel.com> - 0.2 +- Initial Release + diff --git a/packaging/kickstarter.manifest b/packaging/kickstarter.manifest deleted file mode 100644 index 017d22d..0000000 --- a/packaging/kickstarter.manifest +++ /dev/null @@ -1,5 +0,0 @@ -<manifest> - <request> - <domain name="_"/> - </request> -</manifest> diff --git a/packaging/kickstarter.spec b/packaging/kickstarter.spec index 765501f..edb7728 100644 --- a/packaging/kickstarter.spec +++ b/packaging/kickstarter.spec @@ -1,15 +1,15 @@ %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} Name: kickstarter -Summary: Create kickstart files for image creation +Summary: Create kickstart files for meego images Version: 0.15 Release: 1 Group: System/Base License: GPLv2 BuildArch: noarch -URL: http://www.tizen.org +URL: http://www.meego.com Source0: %{name}-%{version}.tar.bz2 -Source1001: packaging/kickstarter.manifest Requires: python-yaml +#Requires: python-urlgrabber Requires: python-cheetah Requires: python-lxml BuildRequires: python-devel @@ -17,7 +17,8 @@ BuildRequires: python-cheetah %description -Create Configuration files(kickstart) to build images +Create Configuration files to build meego images + %prep @@ -25,12 +26,10 @@ Create Configuration files(kickstart) to build images %build -cp %{SOURCE1001} . make tmpls CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build - %install rm -rf $RPM_BUILD_ROOT %if 0%{?suse_version} @@ -40,8 +39,14 @@ rm -rf $RPM_BUILD_ROOT %endif + + + + + %files -%manifest kickstarter.manifest %defattr(-,root,root,-) %{_bindir}/* %{python_sitelib}/* + + @@ -8,33 +8,13 @@ try: except ImportError: pass -MOD_NAME = 'kickstart' - -version_path = 'VERSION' -if not os.path.isfile(version_path): - print 'No VERSION file in topdir, abort' - sys.exit(1) - -try: - # first line should be the version number - version = open(version_path).readline().strip() - if not version: - print 'VERSION file is invalid, abort' - sys.exit(1) - - ver_file = open('%s/__version__.py' % MOD_NAME, 'w') - ver_file.write("VERSION = \"%s\"\n" % version) - ver_file.close() -except IOError: - print 'WARNING: Cannot write version number file' - setup(name='kickstarter', - version = version, + version = "0.1", description='Kickstarter', author='Anas Nashif', author_email='anas.nashif@intel.com', url='http://meego.com/', scripts=['tools/kickstarter'], - packages=['kickstart', 'kswriter'] + packages=['kickstart'] ) diff --git a/tools/kickstarter b/tools/kickstarter index 861bdd4..dd71b70 100755 --- a/tools/kickstarter +++ b/tools/kickstarter @@ -2,12 +2,13 @@ # Anas Nashif <anas.nashif@intel.com> import yaml, sys import re, os -from kswriter import KSWriter +from kickstart import kickstart import copy import time import optparse from time import gmtime, strftime +import errno try: from lxml import etree except ImportError: @@ -29,6 +30,110 @@ except ImportError: except ImportError: print("Failed to import ElementTree from any known place") +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST: + pass + else: raise + + +class KSWriter(): + def __init__(self, im, rep, out): + self.image_filename = im + self.repo_filename = rep + self.outdir = out + self.image_stream = file(self.image_filename, 'r') + self.repo_stream = file(self.repo_filename, 'r') + self.extra = {} + pass + def merge(*input): + return list(reduce(set.union, input, set())) + + def dump(self): + print yaml.dump(yaml.load(self.stream)) + + def parse(self, img): + conf = copy.copy(image_meta['Default']) + plat = copy.copy(image_meta[img['Platform']]) + conf.update(plat) + conf.update(img) + lval = ['Repos', 'Groups', 'PostScripts', 'NoChrootScripts', 'RemovePackages', 'ExtraPackages'] + lvald = {} + for l in lval: + full = [] + if image_meta['Default'].has_key(l) and image_meta['Default'][l]: + full = full + image_meta['Default'][l] + if plat.has_key(l) and plat[l]: + full = full + plat[l] + if img.has_key(l) and img[l]: + full = full + img[l] + lvald[l] = sorted(set(full), key=full.index) + #print full + conf.update(lvald) + #print conf + postscript = "" + for scr in conf['PostScripts']: + if os.path.exists('./custom/scripts/%s.post' %scr): + f = open('./custom/scripts/%s.post' %scr, 'r') + postscript += f.read() + postscript += "\n" + f.close() + else: + print './custom/scripts/%s.post not found, skipping.' %scr + + nochrootscript = "" + for scr in conf['NoChrootScripts']: + if os.path.exists('./custom/scripts/%s.nochroot' %scr): + f = open('./custom/scripts/%s.nochroot' %scr, 'r') + nochrootscript += f.read() + nochrootscript += "\n" + f.close() + else: + print './custom/scripts/%s.nochroot not found, skipping.' %scr + + ptab = "" + for g in [ plat, img ]: + if g.has_key("Part"): + f = open("./custom/part/%s" %g['Part'] ) + ptab = f.read() + f.close() + + conf['Part'] = ptab + conf['Post'] = postscript + conf['NoChroot'] = nochrootscript + return conf + + def process_files(self, meta, repos): + new_repos = [] + #print repos + #print meta + if meta.has_key("Architecture") and meta['Architecture']: + for repo in repos: + r = {} + r['Name'] = repo['Name'] + if repo.has_key('Options'): + r['Options'] = repo['Options'] + r['Url'] = repo['Url'].replace("@ARCH@", meta['Architecture']) + r['Url'] = r['Url'].replace("@RELEASE@", meta['Baseline']) + new_repos.append(r) + else: + new_repos = repos + + nameSpace = {'metadata': meta, 'repos': new_repos} + t = kickstart(searchList=[nameSpace]) + a = str(t) + if meta.has_key('FileName') and meta['FileName']: + f = None + if meta.has_key("Baseline"): + mkdir_p(meta['Baseline']) + f = open("%s/%s/%s.ks" %( self.outdir, meta['Baseline'], meta['FileName'] ), 'w') + else: + f = open("%s/%s.ks" %( self.outdir, meta['FileName'] ), 'w') + f.write(a) + f.close() + def image_xml(root, img): s = etree.Element("config") @@ -79,16 +184,12 @@ if __name__ == '__main__': parser.add_option("-c", "--configs", type="string", dest="configsfile", help="configuration meta file") - parser.add_option("-o", "--outdir", type="string", dest="outdir", default=".", + parser.add_option("-o", "--outdir", type="string", dest="outdir", help="outdir") parser.add_option("-r", "--repos", type="string", dest="repofile", help="repo meta file") parser.add_option("-i", "--index", type="string", dest="indexfile", help="generate index file") - parser.add_option("-C", "--config", type="string", dest="config", default=None, - help="Limit to this configuration file") - parser.add_option("-p", "--packages", action="store_true", dest="packages", default=False, - help="return list of packages to be installed for this configuration") (options, args) = parser.parse_args() @@ -96,11 +197,41 @@ if __name__ == '__main__': print "you need to provide meta files with --configs and --repos" sys.exit(1) - ks = KSWriter(options.configsfile, options.repofile, options.outdir, options.config, options.packages) - ks.generate() + outdir = "" + if options.outdir is None: + outdir = "." + else: + outdir = options.outdir + + ks = KSWriter(options.configsfile, options.repofile, outdir) + repo_meta = yaml.load(ks.repo_stream) + image_meta = yaml.load(ks.image_stream) + + r = repo_meta['Repositories'] + if image_meta.has_key('Configurations'): + for img in image_meta['Configurations']: + conf = ks.parse(img) + if conf.has_key('Active') and conf['Active']: + print "Creating %s (%s.ks)" %(img['Name'], img['FileName'] ) + ks.process_files(conf, r) + else: + print "%s is inactive, not generate %s this time" %(img['Name'], img['FileName'] ) + for path in image_meta['ExternalConfigs']: + for f in os.listdir(path): + if f.endswith('.yaml'): + fp = file('%s/%s' %(path, f), 'r') + local = yaml.load(fp) + conf = ks.parse(local) + if conf.has_key('Active') and conf['Active']: + print "Creating %s (%s.ks)" %(conf['Name'], conf['FileName'] ) + ks.process_files(conf, r) + else: + print "%s is inactive, not generate %s this time" %(conf['Name'], conf['FileName'] ) + else: + print "WARNING: File '%s' ignored." % (f) if options.indexfile: - str = create_xml(ks.image_meta) + str = create_xml(image_meta) f = open(options.indexfile, 'w') f.write(str) f.close() |