+++ /dev/null
-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
tmpls:
cd kickstart; make
-install: tmpls
- python setup.py build
- python setup.py install
-
%.py: %.tmpl
$(CHEETAH) compile --settings='useStackFrames=False' $<
rm -f $(addsuffix .bak,$(TEMPLATE_MODS))
rm -f *.pyc *.pyo
rm -rf dist/ build/ kickstart/kickstart.py kickstart/__init__.py *~ */*~
- rm -rf *.egg-info/
-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).
+
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
ExternalConfigs:
- - netbook
-
+ - ex
Default:
Active: True
- Baseline: tizen-0.99
Language: en_US.UTF-8
Keyboard: us
PackageArgs:
Configurations:
- Name: MeeGo IVI Development
Active: True
+ Baseline: "1.1.80"
Platform: IVI
Desktop: X-IVI
FileName: ivi-ia32
- mesa-libEGL
- Name: MeeGo IVI
Active: True
+ Baseline: "1.1.80"
Platform: IVI
Desktop: X-IVI
FileName: ivi-ia32
- 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
- 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
- Name: MeeGo Handset MTF Development
PartSize: 2200
Active: True
+ Baseline: "1.1.80"
Platform: MFLD
FileName: handset-ia32-mtf-devel
Mic2Options: -f nand
- serial-mfld
- Name: MeeGo Handset MTF Pinetrail
Active: True
+ Baseline: "1.1.80"
Platform: MFLD
FileName: handset-ia32-pinetrail-mtf
Mic2Options: -f livecd
- Name: MeeGo Handset MTF
Schedule: "* * * * 3"
Active: True
+ Baseline: "1.1.80"
Platform: MFLD
FileName: handset-ia32-mtf
Mic2Options: -f nand
+++ /dev/null
-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
--- /dev/null
+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
+
+++ /dev/null
-#!/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
+++ /dev/null
-from KSWriter import KSWriter
--- /dev/null
+* 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
+
+++ /dev/null
-<manifest>
- <request>
- <domain name="_"/>
- </request>
-</manifest>
%{!?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
%description
-Create Configuration files(kickstart) to build images
+Create Configuration files to build meego images
+
%prep
%build
-cp %{SOURCE1001} .
make tmpls
CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build
-
%install
rm -rf $RPM_BUILD_ROOT
%if 0%{?suse_version}
%endif
+
+
+
+
+
%files
-%manifest kickstarter.manifest
%defattr(-,root,root,-)
%{_bindir}/*
%{python_sitelib}/*
+
+
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']
)
# 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:
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")
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()
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()