Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 17:22:02 +0000 (02:22 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 17:22:02 +0000 (02:22 +0900)
31 files changed:
Makefile
README.md [new file with mode: 0644]
TODO
VERSION [new file with mode: 0644]
demo/configurations.yaml [new file with mode: 0644]
demo/custom/part/custom [new file with mode: 0644]
demo/custom/part/n900 [new file with mode: 0644]
demo/custom/part/n900-devel [new file with mode: 0644]
demo/custom/scripts/buildname.nochroot [new file with mode: 0644]
demo/custom/scripts/cleanup.post [new file with mode: 0644]
demo/custom/scripts/flash.post [new file with mode: 0644]
demo/custom/scripts/fstab-n900.post [new file with mode: 0644]
demo/custom/scripts/inittab-n900.post [new file with mode: 0644]
demo/custom/scripts/kboot.post [new file with mode: 0644]
demo/custom/scripts/kernel-handset.post [new file with mode: 0644]
demo/custom/scripts/prelink.post [new file with mode: 0644]
demo/custom/scripts/rpm.post [new file with mode: 0644]
demo/custom/scripts/serial-mfld.post [new file with mode: 0644]
demo/custom/scripts/serial.post [new file with mode: 0644]
demo/custom/scripts/u-boot.post [new file with mode: 0644]
demo/netbook/meego-netbook.yaml [new file with mode: 0644]
demo/repos.yaml [new file with mode: 0644]
kickstart/Makefile [new file with mode: 0644]
kickstart/kickstart.tmpl [new file with mode: 0644]
kswriter/KSWriter.py [new file with mode: 0644]
kswriter/__init__.py [new file with mode: 0644]
packaging/kickstarter.manifest [new file with mode: 0644]
packaging/kickstarter.spec [new file with mode: 0644]
setup.py [new file with mode: 0644]
tools/fetch-configs.py [new file with mode: 0755]
tools/kickstarter [new file with mode: 0755]

index 404738b..a4da77f 100644 (file)
--- 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 (file)
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 (file)
--- 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 (file)
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 (file)
index 0000000..b7d91ed
--- /dev/null
@@ -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 (file)
index 0000000..d6c8b6b
--- /dev/null
@@ -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 (file)
index 0000000..bd7ac77
--- /dev/null
@@ -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 (file)
index 0000000..e239fa8
--- /dev/null
@@ -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 (file)
index 0000000..edd20a7
--- /dev/null
@@ -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 (file)
index 0000000..c36c2e4
--- /dev/null
@@ -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 (file)
index 0000000..fe062d3
--- /dev/null
@@ -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 (file)
index 0000000..03b6fc1
--- /dev/null
@@ -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 (file)
index 0000000..4650a2f
--- /dev/null
@@ -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 (file)
index 0000000..d5d5183
--- /dev/null
@@ -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 (file)
index 0000000..cb07f6c
--- /dev/null
@@ -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 (file)
index 0000000..527548c
--- /dev/null
@@ -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 (file)
index 0000000..6a07394
--- /dev/null
@@ -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 (file)
index 0000000..c3c62b0
--- /dev/null
@@ -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 (file)
index 0000000..5961379
--- /dev/null
@@ -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 (file)
index 0000000..6377edc
--- /dev/null
@@ -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 (file)
index 0000000..2c1e16a
--- /dev/null
@@ -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 (file)
index 0000000..38928c9
--- /dev/null
@@ -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 (file)
index 0000000..ce2f89e
--- /dev/null
@@ -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 (file)
index 0000000..2cfb83c
--- /dev/null
@@ -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 (file)
index 0000000..5e840ac
--- /dev/null
@@ -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 (file)
index 0000000..82212cb
--- /dev/null
@@ -0,0 +1 @@
+from KSWriter import KSWriter
diff --git a/packaging/kickstarter.manifest b/packaging/kickstarter.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/kickstarter.spec b/packaging/kickstarter.spec
new file mode 100644 (file)
index 0000000..765501f
--- /dev/null
@@ -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 (file)
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 (executable)
index 0000000..653af7f
--- /dev/null
@@ -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 (executable)
index 0000000..861bdd4
--- /dev/null
@@ -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()