summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:52:17 +0900
committerHyungKyu Song <hk76.song@samsung.com>2013-02-16 00:52:17 +0900
commit7d6fcd3ea5e129171d62c8ca02605eb644273624 (patch)
tree041ab76879333398b19461f47832e19d168c710a
parentb3f23061abe8b08e51522ec8e2b5cad0b8571f02 (diff)
downloadkickstarter-7d6fcd3ea5e129171d62c8ca02605eb644273624.tar.gz
kickstarter-7d6fcd3ea5e129171d62c8ca02605eb644273624.tar.bz2
kickstarter-7d6fcd3ea5e129171d62c8ca02605eb644273624.zip
-rw-r--r--Makefile40
-rw-r--r--README.md36
-rw-r--r--TODO10
-rw-r--r--VERSION1
-rw-r--r--demo/configurations.yaml235
-rw-r--r--demo/custom/part/custom2
-rw-r--r--demo/custom/part/n9008
-rw-r--r--demo/custom/part/n900-devel8
-rw-r--r--demo/custom/scripts/buildname.nochroot3
-rw-r--r--demo/custom/scripts/cleanup.post6
-rw-r--r--demo/custom/scripts/flash.post5
-rw-r--r--demo/custom/scripts/fstab-n900.post5
-rw-r--r--demo/custom/scripts/inittab-n900.post3
-rw-r--r--demo/custom/scripts/kboot.post3
-rw-r--r--demo/custom/scripts/kernel-handset.post17
-rw-r--r--demo/custom/scripts/prelink.post4
-rw-r--r--demo/custom/scripts/rpm.post7
-rw-r--r--demo/custom/scripts/serial-mfld.post4
-rw-r--r--demo/custom/scripts/serial.post2
-rw-r--r--demo/custom/scripts/u-boot.post4
-rw-r--r--demo/netbook/meego-netbook.yaml17
-rw-r--r--demo/repos.yaml17
-rw-r--r--kickstart/Makefile20
-rw-r--r--kickstart/kickstart.tmpl116
-rw-r--r--kswriter/KSWriter.py172
-rw-r--r--kswriter/__init__.py1
-rw-r--r--packaging/kickstarter.manifest5
-rw-r--r--packaging/kickstarter.spec47
-rw-r--r--setup.py40
-rwxr-xr-xtools/fetch-configs.py29
-rwxr-xr-xtools/kickstarter106
31 files changed, 964 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 404738b..a4da77f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,14 @@
-# ex: set tabstop=4 noexpandtab:
+VERSION = $(shell cat VERSION)
+NAME=kickstarter
+TAGVER = $(shell cat VERSION | sed -e "s/\([0-9\.]*\).*/\1/")
+
+ifeq ($(VERSION), $(TAGVER))
+ TAG = $(TAGVER)
+else
+ TAG = "HEAD"
+endif
+
+
PYTHON=python
CHEETAH=cheetah
TEMPLATES=$(wildcard *.tmpl)
@@ -6,16 +16,38 @@ TEMPLATE_MODS=$(patsubst %.tmpl,%.py,$(TEMPLATES))
.SECONDARY: $(TEMPLATE_MODS)
KS=$(wildcard *.ks)
-all: $(TEMPLATE_MODS)
+all: tmpls
+ python setup.py build
+
+tmpls:
+ cd kickstart; make
+
+install: tmpls
+ python setup.py build
+ python setup.py install
%.py: %.tmpl
$(CHEETAH) compile --settings='useStackFrames=False' $<
+ks: $(TEMPLATES) configurations.yaml repos.yaml
+ kickstarter -c configurations.yaml -r repos.yaml
+
+tag:
+ git tag $(VERSION)
+
+dist-bz2:
+ git archive --format=tar --prefix=$(NAME)-$(TAGVER)/ $(TAG) | \
+ bzip2 > $(NAME)-$(TAGVER).tar.bz2
+
+dist-gz:
+ git archive --format=tar --prefix=$(NAME)-$(TAGVER)/ $(TAG) | \
+ gzip > $(NAME)-$(TAGVER).tar.gz
-ks: $(TEMPLATES) ../images.yaml
- python kickstarter.py -m ../images.yaml
+dist: dist-bz2
clean:
rm -f $(TEMPLATE_MODS)
rm -f $(addsuffix .bak,$(TEMPLATE_MODS))
rm -f *.pyc *.pyo
+ rm -rf dist/ build/ kickstart/kickstart.py kickstart/__init__.py *~ */*~
+ rm -rf *.egg-info/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ac2f925
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+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
+-----
+
+kickstarter -c <images.yaml> -r <repos.yaml>
+
+Example:
+
+ 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 file contains a list of repositories to be used in the kickstart files
+
+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).
diff --git a/TODO b/TODO
index 031d3ee..124d39f 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
-
List of things to do:
-
- - Add support for build IDs
- - Multi arch repos
- - ..
+ - 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
+ - Make it act as a module, so it can be imported into other scripts and generate kickstart file
+ -
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..50c33df
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.15git
diff --git a/demo/configurations.yaml b/demo/configurations.yaml
new file mode 100644
index 0000000..b7d91ed
--- /dev/null
+++ b/demo/configurations.yaml
@@ -0,0 +1,235 @@
+ExternalConfigs:
+ - netbook
+
+Default:
+ Active: True
+ Baseline: tizen-0.99
+ Language: en_US.UTF-8
+ Keyboard: us
+ PackageArgs:
+ SaveRepos: True
+ Timezone: America/Los_Angeles
+ RootPass: meego
+ DefaultUser: meego
+ DefaultUserPass: meego
+ PartSize: 1900
+ FileSystem: ext3
+ PostScripts:
+ - rpm
+ Groups:
+ - MeeGo Core
+ - MeeGo Compliance
+
+CORE:
+ PartSize: 1000
+ BootloaderAppend: "quiet"
+ BootloaderTimeout: 0
+ PostScripts:
+ - cleanup
+ Groups:
+ - MeeGo X Window System
+ NoChrootScripts:
+ - buildname
+N900:
+ Part: n900
+ BootloaderTimeout:
+ BootloaderAppend:
+ StartX: True
+ Groups:
+ - MeeGo Core
+ - Minimal MeeGo X Window System
+ - X for Handsets
+ - MeeGo Compliance
+ - MeeGo Handset Desktop
+ - MeeGo Handset Applications
+ - MeeGo Base Development
+ Kernel: kernel-adaptation-n900
+ PostScripts:
+ - cleanup
+ NoChrootScripts:
+ - buildname
+ Architecture: armv7l
+ Repos:
+ - core
+ - handset
+ - non-oss
+MFLD:
+ PartSize: 1700
+ BootloaderAppend: "ro pci=noearly console=tty1 console=ttyS0 console=ttyMFD2 earlyprintk=mrst loglevel=8 s0ix_latency=160"
+ BootloaderTimeout: 2
+ Bootloader: True
+ StartX: True
+ Groups:
+ - MeeGo Core
+ - Minimal MeeGo X Window System
+ - X for Handsets
+ - MeeGo Compliance
+ - MeeGo Handset Desktop
+ - MeeGo Handset Applications
+ - MeeGo Base Development
+ Kernel: kernel
+ PostScripts:
+ - prelink
+ - cleanup
+ NoChrootScripts:
+ - buildname
+ Architecture: ia32
+ Repos:
+ - core
+ - handset
+ - non-oss
+IVI:
+ PartSize: 2200
+ Bootloader: True
+ BootloaderAppend: "quiet"
+ BootloaderTimeout: 0
+ BootloaderOptions: --test
+ Session: "/usr/bin/startivi"
+ StartX: True
+ Groups:
+ - X for IVI
+ Kernel: kernel-adaptation-intel-automotive
+ PostScripts:
+ - prelink
+ - cleanup
+ NoChrootScripts:
+ - buildname
+ Architecture: ia32
+NETBOOK:
+ PartSize: 3000
+ Bootloader: True
+ BootloaderAppend: "quiet"
+ BootloaderTimeout: 0
+ StartX: True
+ Groups:
+ - X for Netbooks
+ - Virtual Machine Support
+ - Printing
+ - Games
+ - MeeGo Netbook Desktop
+ Kernel: kernel
+ PostScripts:
+ - prelink
+ - cleanup
+ NoChrootScripts:
+ - buildname
+ Architecture: ia32
+
+Configurations:
+ - Name: MeeGo IVI Development
+ Active: True
+ Platform: IVI
+ Desktop: X-IVI
+ FileName: ivi-ia32
+ Mic2Options: -f livecd
+ Groups:
+ - MeeGo IVI Desktop
+ - MeeGo Base Development
+ - MeeGo IVI Applications
+ - Development Tools
+ Repos:
+ - core
+ - ivi
+ ExtraPackages:
+ - mesa-libEGL
+ - Name: MeeGo IVI
+ Active: True
+ Platform: IVI
+ Desktop: X-IVI
+ FileName: ivi-ia32
+ Mic2Options: -f livecd
+ Groups:
+ - MeeGo IVI Desktop
+ - MeeGo Base Development
+ - MeeGo IVI Applications
+ Repos:
+ - core
+ - ivi
+ ExtraPackages:
+ - mesa-libEGL
+ - Name: MeeGo Handset N900 Development
+ Part: n900-devel
+ Active: True
+ Platform: N900
+ FileName: handset-armv7l-n900-devel
+ Mic2Options: -f raw --save-kernel --arch=armv7l
+ Architecture: armv7l
+ Desktop: DUI
+ Session: "/usr/bin/mcompositor"
+ Groups:
+ - Nokia N900 Support
+ - Nokia N900 Proprietary Support
+ - Development Tools
+ ExtraPackages:
+ - xorg-x11-utils-xev
+ - u-boot-tools
+ PostScripts:
+ - inittab-n900
+ - fstab-n900
+ - u-boot
+ - Name: MeeGo Handset N900
+ Active: True
+ Platform: N900
+ FileName: handset-armv7l-n900
+ Mic2Options: -f raw --save-kernel --arch=armv7l
+ Architecture: armv7l
+ Desktop: DUI
+ Session: "/usr/bin/mcompositor"
+ Groups:
+ - Nokia N900 Support
+ - Nokia N900 Proprietary Support
+ ExtraPackages:
+ - xorg-x11-utils-xev
+ - u-boot-tools
+ PostScripts:
+ - inittab-n900
+ - fstab-n900
+ - u-boot
+
+ - Name: MeeGo Handset MTF Development
+ PartSize: 2200
+ Active: True
+ Platform: MFLD
+ FileName: handset-ia32-mtf-devel
+ Mic2Options: -f nand
+ Kernel: kernel-adaptation-medfield
+ Architecture: ia32
+ Desktop: DUI
+ Session: "/usr/bin/mcompositor"
+ Groups:
+ - Moorestown Support
+ - Development Tools
+ PostScripts:
+ - kernel-handset
+ - kboot
+ - serial-mfld
+ - Name: MeeGo Handset MTF Pinetrail
+ Active: True
+ Platform: MFLD
+ FileName: handset-ia32-pinetrail-mtf
+ Mic2Options: -f livecd
+ Kernel: kernel
+ Architecture: ia32
+ Desktop: DUI
+ Session: "/usr/bin/mcompositor"
+ - Name: MeeGo Handset MTF
+ Schedule: "* * * * 3"
+ Active: True
+ Platform: MFLD
+ FileName: handset-ia32-mtf
+ Mic2Options: -f nand
+ Kernel: kernel-adaptation-medfield
+ Architecture: ia32
+ Desktop: DUI
+ Session: "/usr/bin/mcompositor"
+ Groups:
+ - Moorestown Support
+ PostScripts:
+ - kernel-handset
+ - kboot
+ - serial-mfld
+ PrePackages:
+ - Answer2theUltimateQuestionOfEverything
+ Attachment:
+ - ifwi
+ - /boot/vmlinuz-*
diff --git a/demo/custom/part/custom b/demo/custom/part/custom
new file mode 100644
index 0000000..d6c8b6b
--- /dev/null
+++ b/demo/custom/part/custom
@@ -0,0 +1,2 @@
+part / --size 1300 --ondisk sda --grow --maxsize=1450 --fstype=ext3
+#part /home --size 1000 --grow --maxsize=1450 --ondisk sdb --fstype=ext3
diff --git a/demo/custom/part/n900 b/demo/custom/part/n900
new file mode 100644
index 0000000..bd7ac77
--- /dev/null
+++ b/demo/custom/part/n900
@@ -0,0 +1,8 @@
+part / --size=1800 --ondisk mmcblk0p --fstype=btrfs
+
+# This is not used currently. It is here because the /boot partition
+# needs to be the partition number 3 for the u-boot usage.
+part swap --size=192 --ondisk mmcblk0p --fstype=swap
+
+# This partition is made so that u-boot can find the kernel
+part /boot --size=64 --ondisk mmcblk0p --fstype=vfat
diff --git a/demo/custom/part/n900-devel b/demo/custom/part/n900-devel
new file mode 100644
index 0000000..e239fa8
--- /dev/null
+++ b/demo/custom/part/n900-devel
@@ -0,0 +1,8 @@
+part / --size=3400 --ondisk mmcblk0p --fstype=btrfs
+
+# This is not used currently. It is here because the /boot partition
+# needs to be the partition number 3 for the u-boot usage.
+part swap --size=256 --ondisk mmcblk0p --fstype=swap
+
+# This partition is made so that u-boot can find the kernel
+part /boot --size=64 --ondisk mmcblk0p --fstype=vfat
diff --git a/demo/custom/scripts/buildname.nochroot b/demo/custom/scripts/buildname.nochroot
new file mode 100644
index 0000000..edd20a7
--- /dev/null
+++ b/demo/custom/scripts/buildname.nochroot
@@ -0,0 +1,3 @@
+if [ -n "$IMG_NAME" ]; then
+ echo "BUILD: $IMG_NAME" >> $INSTALL_ROOT/etc/meego-release
+fi
diff --git a/demo/custom/scripts/cleanup.post b/demo/custom/scripts/cleanup.post
new file mode 100644
index 0000000..c36c2e4
--- /dev/null
+++ b/demo/custom/scripts/cleanup.post
@@ -0,0 +1,6 @@
+
+# save a little bit of space at least...
+rm -f /boot/initrd*
+
+# make sure there aren't core files lying around
+rm -f /core*
diff --git a/demo/custom/scripts/flash.post b/demo/custom/scripts/flash.post
new file mode 100644
index 0000000..fe062d3
--- /dev/null
+++ b/demo/custom/scripts/flash.post
@@ -0,0 +1,5 @@
+# verify link of flash plugin
+if [ -f /usr/lib/flash-plugin/setup ]; then
+ sh /usr/lib/flash-plugin/setup install
+ rm -f /root/oldflashplugins.tar.gz
+fi
diff --git a/demo/custom/scripts/fstab-n900.post b/demo/custom/scripts/fstab-n900.post
new file mode 100644
index 0000000..03b6fc1
--- /dev/null
+++ b/demo/custom/scripts/fstab-n900.post
@@ -0,0 +1,5 @@
+
+# Use eMMC swap partition as MeeGo swap as well.
+# Because of the 2nd partition is swap for the partition numbering
+# we can just change the current fstab entry to match the eMMC partition.
+sed -i 's/mmcblk0p2/mmcblk1p3/g' /etc/fstab
diff --git a/demo/custom/scripts/inittab-n900.post b/demo/custom/scripts/inittab-n900.post
new file mode 100644
index 0000000..4650a2f
--- /dev/null
+++ b/demo/custom/scripts/inittab-n900.post
@@ -0,0 +1,3 @@
+
+# open serial line console for embedded system
+echo "s0:235:respawn:/sbin/agetty -L 115200 ttyS2 vt100" >> /etc/inittab
diff --git a/demo/custom/scripts/kboot.post b/demo/custom/scripts/kboot.post
new file mode 100644
index 0000000..d5d5183
--- /dev/null
+++ b/demo/custom/scripts/kboot.post
@@ -0,0 +1,3 @@
+#Create Initrd if it does not exist and create symlinks for bzImage and initrd for kboot autoboot
+echo "ro pci=noearly console=tty1 console=ttyS0 console=ttyMFD2 earlyprintk=mrst loglevel=8 s0ix_latency=160" > /boot/kboot.cmdline
+
diff --git a/demo/custom/scripts/kernel-handset.post b/demo/custom/scripts/kernel-handset.post
new file mode 100644
index 0000000..cb07f6c
--- /dev/null
+++ b/demo/custom/scripts/kernel-handset.post
@@ -0,0 +1,17 @@
+echo "Checking for kernel......."
+Kernel_Name=`ls /boot | grep vmlinuz`
+if [ -f /boot/$Kernel_Name ]; then
+ Kernel_Ver=`echo $Kernel_Name | sed s/vmlinuz-//`
+ if [ -f /boot/initrd* ]; then
+ echo "Initrd exists" > /dev/null
+ else
+ /usr/libexec/mkmrstinitrd /boot/initrd-$Kernel_Ver.img $Kernel_Ver
+ fi
+ #Create Symlinks
+ cd /boot
+ ln -s $Kernel_Name bzImage
+ ln -s initrd-$Kernel_Ver.img initrd
+ ln -s kboot.cmdline cmdline
+else
+ echo "No Kernels were found"
+fi
diff --git a/demo/custom/scripts/prelink.post b/demo/custom/scripts/prelink.post
new file mode 100644
index 0000000..527548c
--- /dev/null
+++ b/demo/custom/scripts/prelink.post
@@ -0,0 +1,4 @@
+# Prelink can reduce boot time
+if [ -x /usr/sbin/prelink ]; then
+ /usr/sbin/prelink -aRqm
+fi
diff --git a/demo/custom/scripts/rpm.post b/demo/custom/scripts/rpm.post
new file mode 100644
index 0000000..6a07394
--- /dev/null
+++ b/demo/custom/scripts/rpm.post
@@ -0,0 +1,7 @@
+# work around for poor key import UI in PackageKit
+rm -f /var/lib/rpm/__db*
+rpm --rebuilddb
+
+if [ -f /etc/pki/rpm-gpg/RPM-GPG-KEY-meego ]; then
+ rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-meego
+fi
diff --git a/demo/custom/scripts/serial-mfld.post b/demo/custom/scripts/serial-mfld.post
new file mode 100644
index 0000000..c3c62b0
--- /dev/null
+++ b/demo/custom/scripts/serial-mfld.post
@@ -0,0 +1,4 @@
+# open serial line console for embedded system
+echo "s0:235:respawn:/sbin/agetty -L 115200 ttyS0 vt100" >> /etc/inittab
+echo "s1:235:respawn:/sbin/agetty -L 115200 ttyMFD2 vt100" >> /etc/inittab
+echo "ttyMFD2" >> /etc/securetty
diff --git a/demo/custom/scripts/serial.post b/demo/custom/scripts/serial.post
new file mode 100644
index 0000000..5961379
--- /dev/null
+++ b/demo/custom/scripts/serial.post
@@ -0,0 +1,2 @@
+# open serial line console for embedded system
+echo "s0:235:respawn:/sbin/agetty -L 115200 ttyS0 vt100" >> /etc/inittab
diff --git a/demo/custom/scripts/u-boot.post b/demo/custom/scripts/u-boot.post
new file mode 100644
index 0000000..6377edc
--- /dev/null
+++ b/demo/custom/scripts/u-boot.post
@@ -0,0 +1,4 @@
+
+
+# Create the /boot/uImage for u-boot support.
+mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n vmlinuz -d /boot/vmlinuz* /boot/uImage
diff --git a/demo/netbook/meego-netbook.yaml b/demo/netbook/meego-netbook.yaml
new file mode 100644
index 0000000..2c1e16a
--- /dev/null
+++ b/demo/netbook/meego-netbook.yaml
@@ -0,0 +1,17 @@
+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/demo/repos.yaml b/demo/repos.yaml
new file mode 100644
index 0000000..38928c9
--- /dev/null
+++ b/demo/repos.yaml
@@ -0,0 +1,17 @@
+Repositories:
+ - Name: core-testing
+ Url: http://download.meego.com/testing/core/repos/@ARCH@/packages
+ - Name: netbook-testing
+ Url: http://download.meego.com/testing/netbook/repos/@ARCH@/packages
+ - Name: handset-testing
+ Url: http://download.meego.com/testing/handset/repos/@ARCH@/packages
+ - Name: core
+ Url: http://repo.meego.com/MeeGo/builds/@RELEASE@/@BUILD_ID@/core/repos/@ARCH@/packages
+ - Name: netbook
+ Url: http://repo.meego.com/MeeGo/builds/@RELEASE@/@BUILD_ID@/netbook/repos/@ARCH@/packages
+ - Name: handset
+ Url: http://repo.meego.com/MeeGo/builds/@RELEASE@/@BUILD_ID@/handset/repos/@ARCH@/packages
+ - Name: ivi
+ Url: http://repo.meego.com/MeeGo/builds/@RELEASE@/@BUILD_ID@/ivi/repos/@ARCH@/packages
+ - Name: non-oss
+ Url: http://repo.meego.com/MeeGo/builds/@RELEASE@/@BUILD_ID@/non-oss/repos/@ARCH@/packages
diff --git a/kickstart/Makefile b/kickstart/Makefile
new file mode 100644
index 0000000..ce2f89e
--- /dev/null
+++ b/kickstart/Makefile
@@ -0,0 +1,20 @@
+# ex: set tabstop=4 noexpandtab:
+PYTHON=python
+CHEETAH=cheetah
+TEMPLATES=$(wildcard *.tmpl)
+TEMPLATE_MODS=$(patsubst %.tmpl,%.py,$(TEMPLATES))
+.SECONDARY: $(TEMPLATE_MODS)
+
+all: $(TEMPLATE_MODS)
+
+%.py: %.tmpl
+ $(CHEETAH) compile --settings='useStackFrames=False' $<
+ cp $@ __init__.py
+
+clean:
+ rm -f $(TEMPLATE_MODS)
+ rm -f $(addsuffix .bak,$(TEMPLATE_MODS))
+ rm -f *.xsd *.wsdl
+ rm -f *.pyc *.pyo
+ rm -f *.py
+ rm -f *.bak
diff --git a/kickstart/kickstart.tmpl b/kickstart/kickstart.tmpl
new file mode 100644
index 0000000..2cfb83c
--- /dev/null
+++ b/kickstart/kickstart.tmpl
@@ -0,0 +1,116 @@
+#if $metadata.has_key("Mic2Options")
+# -*-mic2-options-*- ${metadata.Mic2Options} -*-mic2-options-*-
+
+#end if
+# ##############################################
+# Do not Edit! Generated by:
+# kickstarter.py
+# ###############################################
+
+lang ${metadata.Language}
+keyboard ${metadata.Keyboard}
+timezone --utc ${metadata.Timezone}
+#if $metadata.Part == ""
+part / --size ${metadata.PartSize} --ondisk sda --fstype=${metadata.FileSystem}
+#else
+${metadata.Part}
+#end if
+rootpw ${metadata.RootPass}
+#if $metadata.has_key("StartX")
+xconfig --startxonboot
+#end if
+#if $metadata.has_key("BootloaderTimeout") or $metadata.has_key("BootloaderAppend") or $metadata.has_key("BootloaderOptions")
+bootloader #slurp
+#end if
+#if $metadata.has_key("BootloaderTimeout")
+ --timeout=${metadata.BootloaderTimeout} #slurp
+#end if
+#if $metadata.has_key("BootloaderAppend")
+ --append="${metadata.BootloaderAppend}" #slurp
+#end if
+#if $metadata.has_key("BootloaderOptions")
+ ${metadata.BootloaderOptions}
+#end if
+
+#if $metadata.has_key("Desktop")
+desktop --autologinuser=${metadata.DefaultUser} #slurp
+#if $metadata.Desktop != "None"
+--defaultdesktop=${metadata.Desktop} #slurp
+#end if
+#if $metadata.has_key("Session")
+--session="${metadata.Session}"
+#else
+
+#end if
+#end if
+user --name ${metadata.DefaultUser} --groups audio,video --password '${metadata.DefaultUserPass}'
+
+#set $options_global = ""
+#if $metadata.SaveRepos
+#set $options_global = "--save --debuginfo --source --gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-meego"
+#end if
+#for $r in $metadata.Repos
+#for $rr in $repos
+#if $rr.Name == $r
+#set $options_repo = $options_global
+#if $rr.has_key("Options")
+#set $options_repo = $rr.Options
+#end if
+#if $rr.Name == "adobe"
+#if $rr.has_key("Options")
+repo --name=${r} --baseurl=${rr.Url} ${rr.Options}
+#else
+repo --name=${r} --baseurl=${rr.Url}
+#end if
+#else
+repo --name=${r} --baseurl=${rr.Url} ${options_repo}
+#end if
+#end if
+#end for
+#end for
+
+#if $metadata.has_key("PackageArgs")
+%packages --${metadata.PackageArgs}
+#else
+%packages
+#end if
+
+#for $g in $metadata.Groups
+@${g}
+#end for
+
+#if $metadata.has_key("Kernel")
+$metadata.Kernel
+#end if
+
+#for $e in $metadata.ExtraPackages
+${e}
+#end for
+#for $e in $metadata.RemovePackages
+-${e}
+#end for
+%end
+
+#if $metadata.has_key("PrePackages")
+%prepackages
+#for $e in $metadata.PrePackages
+${e}
+#end for
+%end
+#end if
+
+#if $metadata.has_key("Attachment")
+%attachment
+#for $e in $metadata.Attachment
+${e}
+#end for
+%end
+#end if
+
+%post
+${metadata.Post}
+%end
+
+%post --nochroot
+${metadata.NoChroot}
+%end
diff --git a/kswriter/KSWriter.py b/kswriter/KSWriter.py
new file mode 100644
index 0000000..5e840ac
--- /dev/null
+++ b/kswriter/KSWriter.py
@@ -0,0 +1,172 @@
+#!/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
new file mode 100644
index 0000000..82212cb
--- /dev/null
+++ b/kswriter/__init__.py
@@ -0,0 +1 @@
+from KSWriter import KSWriter
diff --git a/packaging/kickstarter.manifest b/packaging/kickstarter.manifest
new file mode 100644
index 0000000..017d22d
--- /dev/null
+++ b/packaging/kickstarter.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/kickstarter.spec b/packaging/kickstarter.spec
new file mode 100644
index 0000000..765501f
--- /dev/null
+++ b/packaging/kickstarter.spec
@@ -0,0 +1,47 @@
+%{!?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
+Version: 0.15
+Release: 1
+Group: System/Base
+License: GPLv2
+BuildArch: noarch
+URL: http://www.tizen.org
+Source0: %{name}-%{version}.tar.bz2
+Source1001: packaging/kickstarter.manifest
+Requires: python-yaml
+Requires: python-cheetah
+Requires: python-lxml
+BuildRequires: python-devel
+BuildRequires: python-cheetah
+
+
+%description
+Create Configuration files(kickstart) to build images
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+cp %{SOURCE1001} .
+make tmpls
+
+CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build
+
+
+%install
+rm -rf $RPM_BUILD_ROOT
+%if 0%{?suse_version}
+%{__python} setup.py install --root=$RPM_BUILD_ROOT --prefix=%{_prefix}
+%else
+%{__python} setup.py install --root=$RPM_BUILD_ROOT -O1 --prefix=%{_prefix}
+%endif
+
+
+%files
+%manifest kickstarter.manifest
+%defattr(-,root,root,-)
+%{_bindir}/*
+%{python_sitelib}/*
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..735a510
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+import os, sys
+from distutils.core import setup
+try:
+ import setuptools
+ # enable "setup.py develop", optional
+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,
+ description='Kickstarter',
+ author='Anas Nashif',
+ author_email='anas.nashif@intel.com',
+ url='http://meego.com/',
+ scripts=['tools/kickstarter'],
+ packages=['kickstart', 'kswriter']
+ )
+
diff --git a/tools/fetch-configs.py b/tools/fetch-configs.py
new file mode 100755
index 0000000..653af7f
--- /dev/null
+++ b/tools/fetch-configs.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+
+import urllib2
+from datetime import date
+from xml.etree.ElementTree import ElementTree
+
+url = "http://download.meego.com/snapshots/1.1.90.8.20110317.88/builddata/image-configs.xml"
+f = urllib2.urlopen(url)
+tree = ElementTree()
+tree.parse(f)
+configs = tree.findall('config')
+for c in configs:
+ planned = False
+ name = c.find('name').text
+ dow = date.today().weekday()
+ if c.find('schedule').text != '':
+ schedule = c.find('schedule').text
+ if schedule == '*':
+ planned = True
+ elif schedule in ["0","1","2","3","4","5","6"] and int(schedule) == dow:
+ planned = True
+ else:
+ planned = False
+
+ if planned:
+ print "%s is scheduled to be created today" %name
+ else:
+ print "%s is not scheduled to be created today" %name
+
diff --git a/tools/kickstarter b/tools/kickstarter
new file mode 100755
index 0000000..861bdd4
--- /dev/null
+++ b/tools/kickstarter
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+# Anas Nashif <anas.nashif@intel.com>
+import yaml, sys
+import re, os
+from kswriter import KSWriter
+
+import copy
+import time
+import optparse
+from time import gmtime, strftime
+try:
+ from lxml import etree
+except ImportError:
+ try:
+ # Python 2.5
+ import xml.etree.cElementTree as etree
+ except ImportError:
+ try:
+ # Python 2.5
+ import xml.etree.ElementTree as etree
+ except ImportError:
+ try:
+ # normal cElementTree install
+ import cElementTree as etree
+ except ImportError:
+ try:
+ # normal ElementTree install
+ import elementtree.ElementTree as etree
+ except ImportError:
+ print("Failed to import ElementTree from any known place")
+
+
+def image_xml(root, img):
+ s = etree.Element("config")
+ c = etree.Element('name')
+ c.text = "%s.ks" %img['FileName']
+ s.append(c)
+ cc = etree.Element('path')
+ cc.text = "image-configs/%s.ks" %img['FileName']
+ s.append(cc)
+ cc = etree.Element('description')
+ cc.text = "%s" %img['Name']
+ s.append(cc)
+
+ if img.has_key('Architecture'):
+ cc = etree.Element('arch')
+ cc.text = "%s" %img['Architecture']
+ s.append(cc)
+
+ cc = etree.Element('md5')
+ cc.text = ""
+ s.append(cc)
+
+ cc = etree.Element('schedule')
+ if img.has_key('Schedule'):
+ cc.text = img['Schedule']
+ s.append(cc)
+ root.append(s)
+
+def create_xml(image_meta):
+ root = etree.Element("image-configs")
+ if image_meta.has_key('Configurations'):
+ for img in image_meta['Configurations']:
+ image_xml(root,img)
+ 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']:
+ image_xml(root,conf)
+
+ str = etree.tostring(root, pretty_print=True)
+ return str
+
+if __name__ == '__main__':
+ parser = optparse.OptionParser()
+
+ parser.add_option("-c", "--configs", type="string", dest="configsfile",
+ help="configuration meta file")
+ parser.add_option("-o", "--outdir", type="string", dest="outdir", default=".",
+ 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()
+
+ if options.configsfile is None or options.repofile is None:
+ 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()
+
+ if options.indexfile:
+ str = create_xml(ks.image_meta)
+ f = open(options.indexfile, 'w')
+ f.write(str)
+ f.close()