summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorTudor Florea <tudor.florea@enea.com>2014-10-16 03:05:19 +0200
committerTudor Florea <tudor.florea@enea.com>2014-10-16 03:05:19 +0200
commitc527fd1f14c27855a37f2e8ac5346ce8d940ced2 (patch)
treebb002c1fdf011c41dbd2f0927bed23ecb5f83c97 /scripts
downloadpoky-daisy-140929.tar.gz
initial commit for Enea Linux 4.0-140929daisy-140929
Migrated from the internal git server on the daisy-enea-point-release branch Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/README1
-rwxr-xr-xscripts/bitbake-prserv-tool103
-rwxr-xr-xscripts/bitbake-whatchanged339
-rwxr-xr-xscripts/buildhistory-collect-srcrevs109
-rwxr-xr-xscripts/buildhistory-diff104
-rwxr-xr-xscripts/cleanup-workdir194
-rwxr-xr-xscripts/combo-layer600
-rwxr-xr-xscripts/combo-layer-hook-default.sh13
-rw-r--r--scripts/combo-layer.conf.example56
-rwxr-xr-xscripts/contrib/bb-perf/bb-matrix-plot.sh137
-rwxr-xr-xscripts/contrib/bb-perf/bb-matrix.sh79
-rwxr-xr-xscripts/contrib/bbvars.py186
-rwxr-xr-xscripts/contrib/build-perf-test.sh369
-rwxr-xr-xscripts/contrib/ddimage89
-rwxr-xr-xscripts/contrib/documentation-audit.sh94
-rwxr-xr-xscripts/contrib/graph-tool92
-rwxr-xr-xscripts/contrib/list-packageconfig-flags.py209
-rwxr-xr-xscripts/contrib/mkefidisk.sh286
-rwxr-xr-xscripts/contrib/python/generate-manifest-2.7.py388
-rwxr-xr-xscripts/contrib/python/generate-manifest-3.3.py380
-rwxr-xr-xscripts/contrib/test_build_time.sh237
-rwxr-xr-xscripts/contrib/test_build_time_worker.sh37
-rwxr-xr-xscripts/cp-noerror52
-rwxr-xr-xscripts/create-pull-request240
-rwxr-xr-xscripts/create-recipe2072
-rwxr-xr-xscripts/crosstap148
-rwxr-xr-xscripts/gen-site-config53
-rwxr-xr-xscripts/help2man3
-rwxr-xr-xscripts/hob6
-rwxr-xr-xscripts/jhbuild/jhbuild2oe.py278
-rw-r--r--scripts/jhbuild/modulesets/bootstrap.modules87
-rw-r--r--scripts/jhbuild/modulesets/freedesktop.modules281
-rw-r--r--scripts/jhbuild/modulesets/gcj.modules135
-rw-r--r--scripts/jhbuild/modulesets/gnome-2.10.modules1621
-rw-r--r--scripts/jhbuild/modulesets/gnome-2.12.modules1747
-rw-r--r--scripts/jhbuild/modulesets/gnome-2.14.modules2013
-rw-r--r--scripts/jhbuild/modulesets/gnome-2.16.modules2087
-rw-r--r--scripts/jhbuild/modulesets/gnutls.modules36
-rw-r--r--scripts/jhbuild/modulesets/gtk.modules72
-rw-r--r--scripts/jhbuild/modulesets/gtk28.modules72
-rw-r--r--scripts/jhbuild/modulesets/moduleset.dtd115
-rw-r--r--scripts/jhbuild/modulesets/moduleset.rnc131
-rw-r--r--scripts/jhbuild/modulesets/moduleset.xsl283
-rw-r--r--scripts/jhbuild/modulesets/schemas.xml4
-rw-r--r--scripts/jhbuild/modulesets/xorg-7.0.modules4847
-rw-r--r--scripts/jhbuild/modulesets/xorg.modules2201
-rw-r--r--scripts/lib/bsp/__init__.py22
-rw-r--r--scripts/lib/bsp/engine.py1780
-rw-r--r--scripts/lib/bsp/help.py1043
-rw-r--r--scripts/lib/bsp/kernel.py1071
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/conf/machine/{{=machine}}.conf105
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf33
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-non_hardware.cfg30
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc13
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc13
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg320
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc7
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend25
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT17
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/README118
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/README.sources17
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf10
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/{{=machine}}/machconfig5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend2
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall26
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom.bb57
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/defconfig5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-config.cfg8
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-patches.scc8
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.cfg3
-rw-r--r--scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.scc17
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/conf/machine/{{=machine}}.conf68
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc15
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc15
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg54
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc20
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend25
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT17
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/README64
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf10
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall14
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}-{{=example_bbappend_version}}/example.patch12
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}_{{=example_bbappend_version}}.bbappend8
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/example.patch12
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/helloworld.c8
-rw-r--r--scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}_0.1.bb23
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/conf/machine/{{=machine}}.conf38
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc7
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend25
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/{{=machine}}.conf74
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg163
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend25
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/{{=machine}}.conf68
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/{{=machine}}/interfaces5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/xorg.conf77
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc16
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc4
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend49
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend55
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend55
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.4.bbappend55
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend55
-rw-r--r--scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend55
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/conf/machine/{{=machine}}.conf58
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend1
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/kernel-list.noinstall5
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc15
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc15
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc9
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc0
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg47
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc13
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend25
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend32
-rw-r--r--scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend32
-rw-r--r--scripts/lib/bsp/tags.py47
-rw-r--r--scripts/lib/image/__init__.py22
-rw-r--r--scripts/lib/image/canned-wks/directdisk.wks10
-rw-r--r--scripts/lib/image/canned-wks/mkefidisk.wks11
-rw-r--r--scripts/lib/image/canned-wks/uboot.wks17
-rw-r--r--scripts/lib/image/config/wic.conf11
-rw-r--r--scripts/lib/image/engine.py287
-rw-r--r--scripts/lib/image/help.py311
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/__init__.py0
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/base.py466
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py26
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/authconfig.py40
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/autopart.py119
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/autostep.py55
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py265
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/clearpart.py86
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/device.py125
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/deviceprobe.py40
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/displaymode.py68
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/dmraid.py91
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/driverdisk.py184
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/fcoe.py114
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/firewall.py193
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/firstboot.py62
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/group.py88
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/ignoredisk.py139
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/interactive.py58
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/iscsi.py133
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/iscsiname.py54
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/key.py64
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/keyboard.py55
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/lang.py60
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/langsupport.py58
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/lilocheck.py54
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/logging.py66
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/logvol.py304
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/mediacheck.py53
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/method.py186
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/monitor.py106
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/mouse.py70
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/multipath.py111
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/network.py363
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/partition.py353
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/raid.py365
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/reboot.py79
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/repo.py249
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/rescue.py68
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/rootpw.py93
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/selinux.py64
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/services.py71
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/skipx.py54
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/sshpw.py105
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/timezone.py86
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/updates.py60
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/upgrade.py106
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/user.py173
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/vnc.py114
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/volgroup.py102
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/xconfig.py184
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/zerombr.py69
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/commands/zfcp.py134
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/constants.py57
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/errors.py103
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py0
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/control.py1307
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f10.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f11.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f12.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f13.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f14.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f15.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f7.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f8.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/f9.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/fc3.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/fc4.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/fc5.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/fc6.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/rhel3.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/rhel4.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/rhel5.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/handlers/rhel6.py24
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/ko.py37
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/options.py204
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/parser.py702
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/sections.py244
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/__init__.py53
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/byterange.py463
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/grabber.py1477
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/keepalive.py617
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/mirror.py458
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/progress.py530
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/urlgrabber/sslfactory.py90
-rw-r--r--scripts/lib/mic/3rdparty/pykickstart/version.py197
-rw-r--r--scripts/lib/mic/__init__.py4
-rw-r--r--scripts/lib/mic/__version__.py1
-rw-r--r--scripts/lib/mic/bootstrap.py279
-rw-r--r--scripts/lib/mic/chroot.py343
-rw-r--r--scripts/lib/mic/conf.py197
-rw-r--r--scripts/lib/mic/creator.py351
-rw-r--r--scripts/lib/mic/imager/__init__.py0
-rw-r--r--scripts/lib/mic/imager/baseimager.py1263
-rw-r--r--scripts/lib/mic/imager/direct.py384
-rw-r--r--scripts/lib/mic/imager/fs.py99
-rw-r--r--scripts/lib/mic/imager/livecd.py750
-rw-r--r--scripts/lib/mic/imager/liveusb.py308
-rw-r--r--scripts/lib/mic/imager/loop.py418
-rw-r--r--scripts/lib/mic/imager/raw.py501
-rw-r--r--scripts/lib/mic/kickstart/__init__.py892
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/__init__.py17
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/desktop.py95
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/installerfw.py63
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/micboot.py49
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/micpartition.py57
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/micrepo.py127
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/partition.py482
-rw-r--r--scripts/lib/mic/kickstart/custom_commands/wicboot.py57
-rw-r--r--scripts/lib/mic/msger.py309
-rw-r--r--scripts/lib/mic/plugin.py121
-rw-r--r--scripts/lib/mic/pluginbase.py158
-rw-r--r--scripts/lib/mic/plugins/backend/yumpkgmgr.py490
-rwxr-xr-xscripts/lib/mic/plugins/backend/zypppkgmgr.py973
-rw-r--r--scripts/lib/mic/plugins/hook/.py0
-rw-r--r--scripts/lib/mic/plugins/hook/empty_hook.py3
-rw-r--r--scripts/lib/mic/plugins/imager/direct_plugin.py107
-rw-r--r--scripts/lib/mic/plugins/imager/fs_plugin.py143
-rw-r--r--scripts/lib/mic/plugins/imager/livecd_plugin.py255
-rw-r--r--scripts/lib/mic/plugins/imager/liveusb_plugin.py260
-rw-r--r--scripts/lib/mic/plugins/imager/loop_plugin.py255
-rw-r--r--scripts/lib/mic/plugins/imager/raw_plugin.py275
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-efi.py169
-rw-r--r--scripts/lib/mic/plugins/source/bootimg-pcbios.py195
-rw-r--r--scripts/lib/mic/plugins/source/rootfs.py71
-rw-r--r--scripts/lib/mic/plugins/source/uboot.py173
-rw-r--r--scripts/lib/mic/rt_util.py223
-rw-r--r--scripts/lib/mic/test1
-rw-r--r--scripts/lib/mic/utils/BmapCreate.py298
-rw-r--r--scripts/lib/mic/utils/Fiemap.py252
-rw-r--r--scripts/lib/mic/utils/__init__.py0
-rw-r--r--scripts/lib/mic/utils/cmdln.py1586
-rw-r--r--scripts/lib/mic/utils/errors.py71
-rw-r--r--scripts/lib/mic/utils/fs_related.py1060
-rw-r--r--scripts/lib/mic/utils/gpt_parser.py331
-rw-r--r--scripts/lib/mic/utils/grabber.py97
-rw-r--r--scripts/lib/mic/utils/misc.py1065
-rw-r--r--scripts/lib/mic/utils/oe/__init__.py22
-rw-r--r--scripts/lib/mic/utils/oe/misc.py144
-rw-r--r--scripts/lib/mic/utils/oe/package_manager.py810
-rw-r--r--scripts/lib/mic/utils/partitionedfs.py782
-rw-r--r--scripts/lib/mic/utils/proxy.py183
-rw-r--r--scripts/lib/mic/utils/rpmmisc.py600
-rw-r--r--scripts/lib/mic/utils/runner.py109
-rwxr-xr-xscripts/lnr21
-rw-r--r--scripts/multilib_header_wrapper.h55
-rwxr-xr-xscripts/native-intercept/chown2
-rwxr-xr-xscripts/oe-buildenv-internal109
-rwxr-xr-xscripts/oe-find-native-sysroot81
-rwxr-xr-xscripts/oe-git-proxy133
-rwxr-xr-xscripts/oe-pkgdata-util332
-rwxr-xr-xscripts/oe-selftest162
-rwxr-xr-xscripts/oe-setup-builddir134
-rwxr-xr-xscripts/oe-setup-rpmrepo97
-rwxr-xr-xscripts/oe-trim-schemas49
-rwxr-xr-xscripts/opkg-query-helper.py85
-rwxr-xr-xscripts/postinst-intercepts/postinst_intercept56
-rw-r--r--scripts/postinst-intercepts/update_font_cache6
-rw-r--r--scripts/postinst-intercepts/update_icon_cache12
-rw-r--r--scripts/postinst-intercepts/update_pixbuf_cache11
-rw-r--r--scripts/pybootchartgui/AUTHORS11
-rw-r--r--scripts/pybootchartgui/COPYING340
-rw-r--r--scripts/pybootchartgui/MAINTAINERS3
-rw-r--r--scripts/pybootchartgui/NEWS204
-rw-r--r--scripts/pybootchartgui/README.pybootchart37
-rwxr-xr-xscripts/pybootchartgui/pybootchartgui.py23
-rw-r--r--scripts/pybootchartgui/pybootchartgui/__init__.py0
-rw-r--r--scripts/pybootchartgui/pybootchartgui/batch.py46
-rw-r--r--scripts/pybootchartgui/pybootchartgui/draw.py894
-rw-r--r--scripts/pybootchartgui/pybootchartgui/gui.py350
l---------scripts/pybootchartgui/pybootchartgui/main.py1
-rw-r--r--scripts/pybootchartgui/pybootchartgui/main.py.in187
-rw-r--r--scripts/pybootchartgui/pybootchartgui/parsing.py740
-rw-r--r--scripts/pybootchartgui/pybootchartgui/process_tree.py292
-rw-r--r--scripts/pybootchartgui/pybootchartgui/samples.py151
-rw-r--r--scripts/pybootchartgui/pybootchartgui/tests/parser_test.py105
-rw-r--r--scripts/pybootchartgui/pybootchartgui/tests/process_tree_test.py92
-rwxr-xr-xscripts/relocate_sdk.py243
-rw-r--r--scripts/rootfs_rpm-extract-postinst.awk11
-rwxr-xr-xscripts/rpm2cpio.sh53
-rwxr-xr-xscripts/runqemu507
-rwxr-xr-xscripts/runqemu-addptable2image51
-rwxr-xr-xscripts/runqemu-export-rootfs163
-rwxr-xr-xscripts/runqemu-extract-sdk103
-rwxr-xr-xscripts/runqemu-gen-tapdevs91
-rwxr-xr-xscripts/runqemu-ifdown66
-rwxr-xr-xscripts/runqemu-ifup106
-rwxr-xr-xscripts/runqemu-internal659
-rw-r--r--scripts/runqemu.README42
-rwxr-xr-xscripts/send-error-report80
-rwxr-xr-xscripts/send-pull-request179
-rwxr-xr-xscripts/sstate-cache-management.sh469
-rwxr-xr-xscripts/sstate-diff-machines.sh107
-rwxr-xr-xscripts/sstate-sysroot-cruft.sh78
-rwxr-xr-xscripts/swabber-strace-attach31
-rwxr-xr-xscripts/sysroot-relativelinks.py31
-rwxr-xr-xscripts/test-dependencies.sh256
-rwxr-xr-xscripts/test-reexec123
-rwxr-xr-xscripts/tiny/dirsize.py93
-rwxr-xr-xscripts/tiny/ksize.py165
-rwxr-xr-xscripts/wic302
-rwxr-xr-xscripts/wipe-sysroot54
-rwxr-xr-xscripts/yocto-bsp156
-rwxr-xr-xscripts/yocto-kernel399
-rwxr-xr-xscripts/yocto-layer147
393 files changed, 71835 insertions, 0 deletions
diff --git a/scripts/README b/scripts/README
new file mode 100644
index 0000000000..1b8d127245
--- /dev/null
+++ b/scripts/README
@@ -0,0 +1 @@
This directory contains Various useful scripts for working with OE builds
diff --git a/scripts/bitbake-prserv-tool b/scripts/bitbake-prserv-tool
new file mode 100755
index 0000000000..28c2416bfe
--- /dev/null
+++ b/scripts/bitbake-prserv-tool
@@ -0,0 +1,103 @@
1#!/usr/bin/env bash
2
3help ()
4{
5 base=`basename $0`
6 echo -e "Usage: $base command"
7 echo "Avaliable commands:"
8 echo -e "\texport <file.conf>: export and lock down the AUTOPR values from the PR service into a file for release."
9 echo -e "\timport <file.conf>: import the AUTOPR values from the exported file into the PR service."
10}
11
12clean_cache()
13{
14 s=`bitbake -e | grep ^CACHE= | cut -f2 -d\"`
15 if [ "x${s}" != "x" ]; then
16 rm -rf ${s}
17 fi
18}
19
20do_export ()
21{
22 file=$1
23 [ "x${file}" == "x" ] && help && exit 1
24 rm -f ${file}
25
26 clean_cache
27 bitbake -R conf/prexport.conf -p
28 s=`bitbake -R conf/prexport.conf -e | grep ^PRSERV_DUMPFILE= | cut -f2 -d\"`
29 if [ "x${s}" != "x" ];
30 then
31 [ -e $s ] && mv -f $s $file && echo "Exporting to file $file succeeded!"
32 return 0
33 fi
34 echo "Exporting to file $file failed!"
35 return 1
36}
37
38do_import ()
39{
40 file=$1
41 [ "x${file}" == "x" ] && help && exit 1
42
43 clean_cache
44 bitbake -R conf/primport.conf -R $file -p
45 ret=$?
46 [ $ret -eq 0 ] && echo "Importing from file $file succeeded!" || echo "Importing from file $file failed!"
47 return $ret
48}
49
50do_migrate_localcount ()
51{
52 df=`bitbake -R conf/migrate_localcount.conf -e | \
53 grep ^LOCALCOUNT_DUMPFILE= | cut -f2 -d\"`
54 if [ "x${df}" == "x" ];
55 then
56 echo "LOCALCOUNT_DUMPFILE is not defined!"
57 return 1
58 fi
59
60 rm -rf $df
61 clean_cache
62 echo "Exporting LOCALCOUNT to AUTOINCs..."
63 bitbake -R conf/migrate_localcount.conf -p
64 [ ! $? -eq 0 ] && echo "Exporting to file $df failed!" && exit 1
65
66 if [ -e $df ];
67 then
68 echo "Exporting to file $df succeeded!"
69 else
70 echo "Exporting to file $df failed!"
71 exit 1
72 fi
73
74 echo "Importing generated AUTOINC entries..."
75 [ -e $df ] && do_import $df
76
77 if [ ! $? -eq 0 ]
78 then
79 echo "Migration from LOCALCOUNT to AUTOINCs failed!"
80 return 1
81 fi
82
83 echo "Migration from LOCALCOUNT to AUTOINCs succeeded!"
84 return 0
85}
86
87[ $# -eq 0 ] && help && exit 1
88
89case $1 in
90export)
91 do_export $2
92 ;;
93import)
94 do_import $2
95 ;;
96migrate_localcount)
97 do_migrate_localcount
98 ;;
99*)
100 help
101 exit 1
102 ;;
103esac
diff --git a/scripts/bitbake-whatchanged b/scripts/bitbake-whatchanged
new file mode 100755
index 0000000000..e4497e03a8
--- /dev/null
+++ b/scripts/bitbake-whatchanged
@@ -0,0 +1,339 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4
5# Copyright (c) 2013 Wind River Systems, Inc.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14# See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20from __future__ import print_function
21import os
22import sys
23import getopt
24import shutil
25import re
26import warnings
27import subprocess
28from optparse import OptionParser
29
30# Figure out where is the bitbake/lib/bb since we need bb.siggen and bb.process
31p = subprocess.Popen("bash -c 'echo $(dirname $(which bitbake-diffsigs | grep -v \'^alias\'))/../lib'",
32 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
33
34err = p.stderr.read()
35if err:
36 print("ERROR: Failed to locate bitbake-diffsigs:", file=sys.stderr)
37 print(err, file=sys.stderr)
38 sys.exit(1)
39
40sys.path.insert(0, p.stdout.read().rstrip('\n'))
41
42import bb.siggen
43import bb.process
44
45# Match the stamp's filename
46# group(1): PE_PV (may no PE)
47# group(2): PR
48# group(3): TASK
49# group(4): HASH
50stamp_re = re.compile("(?P<pv>.*)-(?P<pr>r\d+)\.(?P<task>do_\w+)\.(?P<hash>[^\.]*)")
51sigdata_re = re.compile(".*\.sigdata\..*")
52
53def gen_dict(stamps):
54 """
55 Generate the dict from the stamps dir.
56 The output dict format is:
57 {fake_f: {pn: PN, pv: PV, pr: PR, task: TASK, path: PATH}}
58 Where:
59 fake_f: pv + task + hash
60 path: the path to the stamp file
61 """
62 # The member of the sub dict (A "path" will be appended below)
63 sub_mem = ("pv", "pr", "task")
64 d = {}
65 for dirpath, _, files in os.walk(stamps):
66 for f in files:
67 # The "bitbake -S" would generate ".sigdata", but no "_setscene".
68 fake_f = re.sub('_setscene.', '.', f)
69 fake_f = re.sub('.sigdata', '', fake_f)
70 subdict = {}
71 tmp = stamp_re.match(fake_f)
72 if tmp:
73 for i in sub_mem:
74 subdict[i] = tmp.group(i)
75 if len(subdict) != 0:
76 pn = os.path.basename(dirpath)
77 subdict['pn'] = pn
78 # The path will be used by os.stat() and bb.siggen
79 subdict['path'] = dirpath + "/" + f
80 fake_f = tmp.group('pv') + tmp.group('task') + tmp.group('hash')
81 d[fake_f] = subdict
82 return d
83
84# Re-construct the dict
85def recon_dict(dict_in):
86 """
87 The output dict format is:
88 {pn_task: {pv: PV, pr: PR, path: PATH}}
89 """
90 dict_out = {}
91 for k in dict_in.keys():
92 subdict = {}
93 # The key
94 pn_task = "%s_%s" % (dict_in.get(k).get('pn'), dict_in.get(k).get('task'))
95 # If more than one stamps are found, use the latest one.
96 if pn_task in dict_out:
97 full_path_pre = dict_out.get(pn_task).get('path')
98 full_path_cur = dict_in.get(k).get('path')
99 if os.stat(full_path_pre).st_mtime > os.stat(full_path_cur).st_mtime:
100 continue
101 subdict['pv'] = dict_in.get(k).get('pv')
102 subdict['pr'] = dict_in.get(k).get('pr')
103 subdict['path'] = dict_in.get(k).get('path')
104 dict_out[pn_task] = subdict
105
106 return dict_out
107
108def split_pntask(s):
109 """
110 Split the pn_task in to (pn, task) and return it
111 """
112 tmp = re.match("(.*)_(do_.*)", s)
113 return (tmp.group(1), tmp.group(2))
114
115
116def print_added(d_new = None, d_old = None):
117 """
118 Print the newly added tasks
119 """
120 added = {}
121 for k in d_new.keys():
122 if k not in d_old:
123 # Add the new one to added dict, and remove it from
124 # d_new, so the remaining ones are the changed ones
125 added[k] = d_new.get(k)
126 del(d_new[k])
127
128 if not added:
129 return 0
130
131 # Format the output, the dict format is:
132 # {pn: task1, task2 ...}
133 added_format = {}
134 counter = 0
135 for k in added.keys():
136 pn, task = split_pntask(k)
137 if pn in added_format:
138 # Append the value
139 added_format[pn] = "%s %s" % (added_format.get(pn), task)
140 else:
141 added_format[pn] = task
142 counter += 1
143 print("=== Newly added tasks: (%s tasks)" % counter)
144 for k in added_format.keys():
145 print(" %s: %s" % (k, added_format.get(k)))
146
147 return counter
148
149def print_vrchanged(d_new = None, d_old = None, vr = None):
150 """
151 Print the pv or pr changed tasks.
152 The arg "vr" is "pv" or "pr"
153 """
154 pvchanged = {}
155 counter = 0
156 for k in d_new.keys():
157 if d_new.get(k).get(vr) != d_old.get(k).get(vr):
158 counter += 1
159 pn, task = split_pntask(k)
160 if pn not in pvchanged:
161 # Format the output, we only print pn (no task) since
162 # all the tasks would be changed when pn or pr changed,
163 # the dict format is:
164 # {pn: pv/pr_old -> pv/pr_new}
165 pvchanged[pn] = "%s -> %s" % (d_old.get(k).get(vr), d_new.get(k).get(vr))
166 del(d_new[k])
167
168 if not pvchanged:
169 return 0
170
171 print("\n=== %s changed: (%s tasks)" % (vr.upper(), counter))
172 for k in pvchanged.keys():
173 print(" %s: %s" % (k, pvchanged.get(k)))
174
175 return counter
176
177def print_depchanged(d_new = None, d_old = None, verbose = False):
178 """
179 Print the dependency changes
180 """
181 depchanged = {}
182 counter = 0
183 for k in d_new.keys():
184 counter += 1
185 pn, task = split_pntask(k)
186 if (verbose):
187 full_path_old = d_old.get(k).get("path")
188 full_path_new = d_new.get(k).get("path")
189 # No counter since it is not ready here
190 if sigdata_re.match(full_path_old) and sigdata_re.match(full_path_new):
191 output = bb.siggen.compare_sigfiles(full_path_old, full_path_new)
192 if output:
193 print("\n=== The verbose changes of %s.do_%s:" % (pn, task))
194 print('\n'.join(output))
195 else:
196 # Format the output, the format is:
197 # {pn: task1, task2, ...}
198 if pn in depchanged:
199 depchanged[pn] = "%s %s" % (depchanged.get(pn), task)
200 else:
201 depchanged[pn] = task
202
203 if len(depchanged) > 0:
204 print("\n=== Dependencies changed: (%s tasks)" % counter)
205 for k in depchanged.keys():
206 print(" %s: %s" % (k, depchanged[k]))
207
208 return counter
209
210
211def main():
212 """
213 Print what will be done between the current and last builds:
214 1) Run "STAMPS_DIR=<path> bitbake -S recipe" to re-generate the stamps
215 2) Figure out what are newly added and changed, can't figure out
216 what are removed since we can't know the previous stamps
217 clearly, for example, if there are several builds, we can't know
218 which stamps the last build has used exactly.
219 3) Use bb.siggen.compare_sigfiles to diff the old and new stamps
220 """
221
222 parser = OptionParser(
223 version = "1.0",
224 usage = """%prog [options] [package ...]
225print what will be done between the current and last builds, for example:
226
227 $ bitbake core-image-sato
228 # Edit the recipes
229 $ bitbake-whatchanged core-image-sato
230
231The changes will be printed"
232
233Note:
234 The amount of tasks is not accurate when the task is "do_build" since
235 it usually depends on other tasks.
236 The "nostamp" task is not included.
237"""
238)
239 parser.add_option("-v", "--verbose", help = "print the verbose changes",
240 action = "store_true", dest = "verbose")
241
242 options, args = parser.parse_args(sys.argv)
243
244 verbose = options.verbose
245
246 if len(args) != 2:
247 parser.error("Incorrect number of arguments")
248 else:
249 recipe = args[1]
250
251 # Get the STAMPS_DIR
252 print("Figuring out the STAMPS_DIR ...")
253 cmdline = "bitbake -e | sed -ne 's/^STAMPS_DIR=\"\(.*\)\"/\\1/p'"
254 try:
255 stampsdir, err = bb.process.run(cmdline)
256 except:
257 raise
258 if not stampsdir:
259 print("ERROR: No STAMPS_DIR found for '%s'" % recipe, file=sys.stderr)
260 return 2
261 stampsdir = stampsdir.rstrip("\n")
262 if not os.path.isdir(stampsdir):
263 print("ERROR: stamps directory \"%s\" not found!" % stampsdir, file=sys.stderr)
264 return 2
265
266 # The new stamps dir
267 new_stampsdir = stampsdir + ".bbs"
268 if os.path.exists(new_stampsdir):
269 print("ERROR: %s already exists!" % new_stampsdir, file=sys.stderr)
270 return 2
271
272 try:
273 # Generate the new stamps dir
274 print("Generating the new stamps ... (need several minutes)")
275 cmdline = "STAMPS_DIR=%s bitbake -S none %s" % (new_stampsdir, recipe)
276 # FIXME
277 # The "bitbake -S" may fail, not fatal error, the stamps will still
278 # be generated, this might be a bug of "bitbake -S".
279 try:
280 bb.process.run(cmdline)
281 except Exception as exc:
282 print(exc)
283
284 # The dict for the new and old stamps.
285 old_dict = gen_dict(stampsdir)
286 new_dict = gen_dict(new_stampsdir)
287
288 # Remove the same one from both stamps.
289 cnt_unchanged = 0
290 for k in new_dict.keys():
291 if k in old_dict:
292 cnt_unchanged += 1
293 del(new_dict[k])
294 del(old_dict[k])
295
296 # Re-construct the dict to easily find out what is added or changed.
297 # The dict format is:
298 # {pn_task: {pv: PV, pr: PR, path: PATH}}
299 new_recon = recon_dict(new_dict)
300 old_recon = recon_dict(old_dict)
301
302 del new_dict
303 del old_dict
304
305 # Figure out what are changed, the new_recon would be changed
306 # by the print_xxx function.
307 # Newly added
308 cnt_added = print_added(new_recon, old_recon)
309
310 # PV (including PE) and PR changed
311 # Let the bb.siggen handle them if verbose
312 cnt_rv = {}
313 if not verbose:
314 for i in ('pv', 'pr'):
315 cnt_rv[i] = print_vrchanged(new_recon, old_recon, i)
316
317 # Dependencies changed (use bitbake-diffsigs)
318 cnt_dep = print_depchanged(new_recon, old_recon, verbose)
319
320 total_changed = cnt_added + (cnt_rv.get('pv') or 0) + (cnt_rv.get('pr') or 0) + cnt_dep
321
322 print("\n=== Summary: (%s changed, %s unchanged)" % (total_changed, cnt_unchanged))
323 if verbose:
324 print("Newly added: %s\nDependencies changed: %s\n" % \
325 (cnt_added, cnt_dep))
326 else:
327 print("Newly added: %s\nPV changed: %s\nPR changed: %s\nDependencies changed: %s\n" % \
328 (cnt_added, cnt_rv.get('pv') or 0, cnt_rv.get('pr') or 0, cnt_dep))
329 except:
330 print("ERROR occurred!")
331 raise
332 finally:
333 # Remove the newly generated stamps dir
334 if os.path.exists(new_stampsdir):
335 print("Removing the newly generated stamps dir ...")
336 shutil.rmtree(new_stampsdir)
337
338if __name__ == "__main__":
339 sys.exit(main())
diff --git a/scripts/buildhistory-collect-srcrevs b/scripts/buildhistory-collect-srcrevs
new file mode 100755
index 0000000000..58a2708032
--- /dev/null
+++ b/scripts/buildhistory-collect-srcrevs
@@ -0,0 +1,109 @@
1#!/usr/bin/env python
2#
3# Collects the recorded SRCREV values from buildhistory and reports on them
4#
5# Copyright 2013 Intel Corporation
6# Authored-by: Paul Eggleton <paul.eggleton@intel.com>
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21import os, sys
22import optparse
23import logging
24
25def logger_create():
26 logger = logging.getLogger("buildhistory")
27 loggerhandler = logging.StreamHandler()
28 loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
29 logger.addHandler(loggerhandler)
30 logger.setLevel(logging.INFO)
31 return logger
32
33logger = logger_create()
34
35def main():
36 parser = optparse.OptionParser(
37 description = "Collects the recorded SRCREV values from buildhistory and reports on them.",
38 usage = """
39 %prog [options]""")
40
41 parser.add_option("-a", "--report-all",
42 help = "Report all SRCREV values, not just ones where AUTOREV has been used",
43 action="store_true", dest="reportall")
44 parser.add_option("-f", "--forcevariable",
45 help = "Use forcevariable override for all output lines",
46 action="store_true", dest="forcevariable")
47 parser.add_option("-p", "--buildhistory-dir",
48 help = "Specify path to buildhistory directory (defaults to buildhistory/ under cwd)",
49 action="store", dest="buildhistory_dir", default='buildhistory/')
50
51 options, args = parser.parse_args(sys.argv)
52
53 if len(args) > 1:
54 sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args[1:]))
55 parser.print_help()
56 sys.exit(1)
57
58 if not os.path.exists(options.buildhistory_dir):
59 sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % options.buildhistory_dir)
60 parser.print_help()
61 sys.exit(1)
62
63 if options.forcevariable:
64 forcevariable = '_forcevariable'
65 else:
66 forcevariable = ''
67
68 lastdir = ''
69 for root, dirs, files in os.walk(options.buildhistory_dir):
70 if '.git' in dirs:
71 dirs.remove('.git')
72 for fn in files:
73 if fn == 'latest_srcrev':
74 curdir = os.path.basename(os.path.dirname(root))
75 if lastdir != curdir:
76 print('# %s' % curdir)
77 lastdir = curdir
78 fullpath = os.path.join(root, fn)
79 pn = os.path.basename(root)
80 srcrev = None
81 orig_srcrev = None
82 orig_srcrevs = {}
83 srcrevs = {}
84 with open(fullpath) as f:
85 for line in f:
86 if '=' in line:
87 splitval = line.split('=')
88 value = splitval[1].strip('" \t\n\r')
89 if line.startswith('# SRCREV = '):
90 orig_srcrev = value
91 elif line.startswith('# SRCREV_'):
92 splitval = line.split('=')
93 name = splitval[0].split('_')[1].strip()
94 orig_srcrevs[name] = value
95 elif line.startswith('SRCREV ='):
96 srcrev = value
97 elif line.startswith('SRCREV_'):
98 name = splitval[0].split('_')[1].strip()
99 srcrevs[name] = value
100 if srcrev and (options.reportall or srcrev != orig_srcrev):
101 print('SRCREV_pn-%s%s = "%s"' % (pn, forcevariable, srcrev))
102 for name, value in srcrevs.items():
103 orig = orig_srcrevs.get(name, orig_srcrev)
104 if options.reportall or value != orig:
105 print('SRCREV_%s_pn-%s%s = "%s"' % (name, pn, forcevariable, value))
106
107
108if __name__ == "__main__":
109 main()
diff --git a/scripts/buildhistory-diff b/scripts/buildhistory-diff
new file mode 100755
index 0000000000..ad50414bce
--- /dev/null
+++ b/scripts/buildhistory-diff
@@ -0,0 +1,104 @@
1#!/usr/bin/env python
2
3# Report significant differences in the buildhistory repository since a specific revision
4#
5# Copyright (C) 2013 Intel Corporation
6# Author: Paul Eggleton <paul.eggleton@linux.intel.com>
7
8import sys
9import os
10import optparse
11from distutils.version import LooseVersion
12
13# Ensure PythonGit is installed (buildhistory_analysis needs it)
14try:
15 import git
16except ImportError:
17 print("Please install GitPython (python-git) 0.3.1 or later in order to use this script")
18 sys.exit(1)
19
20def main():
21 parser = optparse.OptionParser(
22 description = "Reports significant differences in the buildhistory repository.",
23 usage = """
24 %prog [options] [from-revision [to-revision]]
25(if not specified, from-revision defaults to build-minus-1, and to-revision defaults to HEAD)""")
26
27 parser.add_option("-p", "--buildhistory-dir",
28 help = "Specify path to buildhistory directory (defaults to buildhistory/ under cwd)",
29 action="store", dest="buildhistory_dir", default='buildhistory/')
30 parser.add_option("-v", "--report-version",
31 help = "Report changes in PKGE/PKGV/PKGR even when the values are still the default (PE/PV/PR)",
32 action="store_true", dest="report_ver", default=False)
33 parser.add_option("-a", "--report-all",
34 help = "Report all changes, not just the default significant ones",
35 action="store_true", dest="report_all", default=False)
36
37 options, args = parser.parse_args(sys.argv)
38
39 if len(args) > 3:
40 sys.stderr.write('Invalid argument(s) specified: %s\n\n' % ' '.join(args[3:]))
41 parser.print_help()
42 sys.exit(1)
43
44 if LooseVersion(git.__version__) < '0.3.1':
45 sys.stderr.write("Version of GitPython is too old, please install GitPython (python-git) 0.3.1 or later in order to use this script\n")
46 sys.exit(1)
47
48 if not os.path.exists(options.buildhistory_dir):
49 sys.stderr.write('Buildhistory directory "%s" does not exist\n\n' % options.buildhistory_dir)
50 parser.print_help()
51 sys.exit(1)
52
53 # Set path to OE lib dir so we can import the buildhistory_analysis module
54 basepath = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])) + '/..')
55 newpath = basepath + '/meta/lib'
56 # Set path to bitbake lib dir so the buildhistory_analysis module can load bb.utils
57 if os.path.exists(basepath + '/bitbake/lib/bb'):
58 bitbakepath = basepath + '/bitbake'
59 else:
60 # look for bitbake/bin dir in PATH
61 bitbakepath = None
62 for pth in os.environ['PATH'].split(':'):
63 if os.path.exists(os.path.join(pth, '../lib/bb')):
64 bitbakepath = os.path.abspath(os.path.join(pth, '..'))
65 break
66 if not bitbakepath:
67 sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
68 sys.exit(1)
69
70 sys.path[0:0] = [newpath, bitbakepath + '/lib']
71 import oe.buildhistory_analysis
72
73 fromrev = 'build-minus-1'
74 torev = 'HEAD'
75 if len(args) > 1:
76 if len(args) == 2 and '..' in args[1]:
77 revs = args[1].split('..')
78 fromrev = revs[0]
79 if revs[1]:
80 torev = revs[1]
81 else:
82 fromrev = args[1]
83 if len(args) > 2:
84 torev = args[2]
85
86 import gitdb
87 try:
88 changes = oe.buildhistory_analysis.process_changes(options.buildhistory_dir, fromrev, torev, options.report_all, options.report_ver)
89 except gitdb.exc.BadObject as e:
90 if len(args) == 1:
91 sys.stderr.write("Unable to find previous build revision in buildhistory repository\n\n")
92 parser.print_help()
93 else:
94 sys.stderr.write('Specified git revision "%s" is not valid\n' % e.args[0])
95 sys.exit(1)
96
97 for chg in changes:
98 print('%s' % chg)
99
100 sys.exit(0)
101
102
103if __name__ == "__main__":
104 main()
diff --git a/scripts/cleanup-workdir b/scripts/cleanup-workdir
new file mode 100755
index 0000000000..25fef976b6
--- /dev/null
+++ b/scripts/cleanup-workdir
@@ -0,0 +1,194 @@
1#!/usr/bin/env python
2
3# Copyright (c) 2012 Wind River Systems, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18import os
19import sys
20import optparse
21import re
22import subprocess
23import shutil
24
25pkg_cur_dirs = {}
26obsolete_dirs = []
27parser = None
28
29def err_quit(msg):
30 print msg
31 parser.print_usage()
32 sys.exit(1)
33
34def parse_version(verstr):
35 elems = verstr.split(':')
36 epoch = elems[0]
37 if len(epoch) == 0:
38 return elems[1]
39 else:
40 return epoch + '_' + elems[1]
41
42def run_command(cmd):
43 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
44 output = pipe.communicate()[0]
45 if pipe.returncode != 0:
46 print "Execute command '%s' failed." % cmd
47 sys.exit(1)
48 return output
49
50def get_cur_arch_dirs(workdir, arch_dirs):
51 pattern = workdir + '/(.*?)/'
52
53 # select thest 5 packages to get the dirs of current arch
54 pkgs = ['hicolor-icon-theme', 'base-files', 'acl-native', 'binutils-crosssdk', 'nativesdk-autoconf']
55
56 for pkg in pkgs:
57 cmd = "bitbake -e " + pkg + " | grep ^IMAGE_ROOTFS="
58 output = run_command(cmd)
59 output = output.split('"')[1]
60 m = re.match(pattern, output)
61 arch_dirs.append(m.group(1))
62
63def main():
64 global parser
65 parser = optparse.OptionParser(
66 usage = """%prog
67
68%prog removes the obsolete packages' build directories in WORKDIR.
69This script must be ran under BUILDDIR after source file \"oe-init-build-env\".
70
71Any file or directory under WORKDIR which is not created by Yocto
72will be deleted. Be CAUTIOUS.""")
73
74 options, args = parser.parse_args(sys.argv)
75
76 builddir = run_command('echo $BUILDDIR').strip()
77 if len(builddir) == 0:
78 err_quit("Please source file \"oe-init-build-env\" first.\n")
79
80 if os.getcwd() != builddir:
81 err_quit("Please run %s under: %s\n" % (os.path.basename(args[0]), builddir))
82
83 print 'Updating bitbake caches...'
84 cmd = "bitbake -s"
85 output = run_command(cmd)
86
87 output = output.split('\n')
88 index = 0
89 while len(output[index]) > 0:
90 index += 1
91 alllines = output[index+1:]
92
93 for line in alllines:
94 # empty again means end of the versions output
95 if len(line) == 0:
96 break
97 line = line.strip()
98 line = re.sub('\s+', ' ', line)
99 elems = line.split(' ')
100 if len(elems) == 2:
101 version = parse_version(elems[1])
102 else:
103 version = parse_version(elems[2])
104 pkg_cur_dirs[elems[0]] = version
105
106 cmd = "bitbake -e"
107 output = run_command(cmd)
108
109 tmpdir = None
110 image_rootfs = None
111 output = output.split('\n')
112 for line in output:
113 if tmpdir and image_rootfs:
114 break
115
116 if not tmpdir:
117 m = re.match('TMPDIR="(.*)"', line)
118 if m:
119 tmpdir = m.group(1)
120
121 if not image_rootfs:
122 m = re.match('IMAGE_ROOTFS="(.*)"', line)
123 if m:
124 image_rootfs = m.group(1)
125
126 # won't fail just in case
127 if not tmpdir or not image_rootfs:
128 print "Can't get TMPDIR or IMAGE_ROOTFS."
129 return 1
130
131 pattern = tmpdir + '/(.*?)/(.*?)/'
132 m = re.match(pattern, image_rootfs)
133 if not m:
134 print "Can't get WORKDIR."
135 return 1
136
137 workdir = os.path.join(tmpdir, m.group(1))
138
139 # we only deal the dirs of current arch, total numbers of dirs are 6
140 cur_arch_dirs = [m.group(2)]
141 get_cur_arch_dirs(workdir, cur_arch_dirs)
142
143 for workroot, dirs, files in os.walk(workdir):
144 # For the files, they should NOT exist in WORKDIR. Remove them.
145 for f in files:
146 obsolete_dirs.append(os.path.join(workroot, f))
147
148 for d in dirs:
149 if d not in cur_arch_dirs:
150 continue
151
152 for pkgroot, pkgdirs, filenames in os.walk(os.path.join(workroot, d)):
153 for f in filenames:
154 obsolete_dirs.append(os.path.join(pkgroot, f))
155
156 for pkgdir in sorted(pkgdirs):
157 if pkgdir not in pkg_cur_dirs:
158 obsolete_dirs.append(os.path.join(pkgroot, pkgdir))
159 else:
160 for verroot, verdirs, verfiles in os.walk(os.path.join(pkgroot, pkgdir)):
161 for f in verfiles:
162 obsolete_dirs.append(os.path.join(pkgroot, f))
163 for v in sorted(verdirs):
164 if v not in pkg_cur_dirs[pkgdir]:
165 obsolete_dirs.append(os.path.join(pkgroot, pkgdir, v))
166 break
167
168 # just process the top dir of every package under tmp/work/*/,
169 # then jump out of the above os.walk()
170 break
171
172 # it is convenient to use os.walk() to get dirs and files at same time
173 # both of them have been dealed in the loop, so jump out
174 break
175
176 for d in obsolete_dirs:
177 print "Deleting %s" % d
178 shutil.rmtree(d, True)
179
180 if len(obsolete_dirs):
181 print '\nTotal %d items.' % len(obsolete_dirs)
182 else:
183 print '\nNo obsolete directory found under %s.' % workdir
184
185 return 0
186
187if __name__ == '__main__':
188 try:
189 ret = main()
190 except Exception:
191 ret = 2
192 import traceback
193 traceback.print_exc(3)
194 sys.exit(ret)
diff --git a/scripts/combo-layer b/scripts/combo-layer
new file mode 100755
index 0000000000..9da1d3a89e
--- /dev/null
+++ b/scripts/combo-layer
@@ -0,0 +1,600 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright 2011 Intel Corporation
6# Authored-by: Yu Ke <ke.yu@intel.com>
7# Paul Eggleton <paul.eggleton@intel.com>
8# Richard Purdie <richard.purdie@intel.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23import os, sys
24import optparse
25import logging
26import subprocess
27import ConfigParser
28import re
29
30__version__ = "0.2.1"
31
32def logger_create():
33 logger = logging.getLogger("")
34 loggerhandler = logging.StreamHandler()
35 loggerhandler.setFormatter(logging.Formatter("[%(asctime)s] %(message)s","%H:%M:%S"))
36 logger.addHandler(loggerhandler)
37 logger.setLevel(logging.INFO)
38 return logger
39
40logger = logger_create()
41
42def get_current_branch(repodir=None):
43 try:
44 if not os.path.exists(os.path.join(repodir if repodir else '', ".git")):
45 # Repo not created yet (i.e. during init) so just assume master
46 return "master"
47 branchname = runcmd("git symbolic-ref HEAD 2>/dev/null", repodir).strip()
48 if branchname.startswith("refs/heads/"):
49 branchname = branchname[11:]
50 return branchname
51 except subprocess.CalledProcessError:
52 return ""
53
54class Configuration(object):
55 """
56 Manages the configuration
57
58 For an example config file, see combo-layer.conf.example
59
60 """
61 def __init__(self, options):
62 for key, val in options.__dict__.items():
63 setattr(self, key, val)
64
65 def readsection(parser, section, repo):
66 for (name, value) in parser.items(section):
67 if value.startswith("@"):
68 self.repos[repo][name] = eval(value.strip("@"))
69 else:
70 self.repos[repo][name] = value
71
72 logger.debug("Loading config file %s" % self.conffile)
73 self.parser = ConfigParser.ConfigParser()
74 with open(self.conffile) as f:
75 self.parser.readfp(f)
76
77 self.repos = {}
78 for repo in self.parser.sections():
79 self.repos[repo] = {}
80 readsection(self.parser, repo, repo)
81
82 # Load local configuration, if available
83 self.localconffile = None
84 self.localparser = None
85 self.combobranch = None
86 if self.conffile.endswith('.conf'):
87 lcfile = self.conffile.replace('.conf', '-local.conf')
88 if os.path.exists(lcfile):
89 # Read combo layer branch
90 self.combobranch = get_current_branch()
91 logger.debug("Combo layer branch is %s" % self.combobranch)
92
93 self.localconffile = lcfile
94 logger.debug("Loading local config file %s" % self.localconffile)
95 self.localparser = ConfigParser.ConfigParser()
96 with open(self.localconffile) as f:
97 self.localparser.readfp(f)
98
99 for section in self.localparser.sections():
100 if '|' in section:
101 sectionvals = section.split('|')
102 repo = sectionvals[0]
103 if sectionvals[1] != self.combobranch:
104 continue
105 else:
106 repo = section
107 if repo in self.repos:
108 readsection(self.localparser, section, repo)
109
110 def update(self, repo, option, value, initmode=False):
111 if self.localparser:
112 parser = self.localparser
113 section = "%s|%s" % (repo, self.combobranch)
114 conffile = self.localconffile
115 if initmode and not parser.has_section(section):
116 parser.add_section(section)
117 else:
118 parser = self.parser
119 section = repo
120 conffile = self.conffile
121 parser.set(section, option, value)
122 with open(conffile, "w") as f:
123 parser.write(f)
124
125 def sanity_check(self, initmode=False):
126 required_options=["src_uri", "local_repo_dir", "dest_dir", "last_revision"]
127 if initmode:
128 required_options.remove("last_revision")
129 msg = ""
130 missing_options = []
131 for name in self.repos:
132 for option in required_options:
133 if option not in self.repos[name]:
134 msg = "%s\nOption %s is not defined for component %s" %(msg, option, name)
135 missing_options.append(option)
136 if msg != "":
137 logger.error("configuration file %s has the following error: %s" % (self.conffile,msg))
138 if self.localconffile and 'last_revision' in missing_options:
139 logger.error("local configuration file %s may be missing configuration for combo branch %s" % (self.localconffile, self.combobranch))
140 sys.exit(1)
141
142 # filterdiff is required by action_splitpatch, so check its availability
143 if subprocess.call("which filterdiff > /dev/null 2>&1", shell=True) != 0:
144 logger.error("ERROR: patchutils package is missing, please install it (e.g. # apt-get install patchutils)")
145 sys.exit(1)
146
147def runcmd(cmd,destdir=None,printerr=True):
148 """
149 execute command, raise CalledProcessError if fail
150 return output if succeed
151 """
152 logger.debug("run cmd '%s' in %s" % (cmd, os.getcwd() if destdir is None else destdir))
153 out = os.tmpfile()
154 try:
155 subprocess.check_call(cmd, stdout=out, stderr=out, cwd=destdir, shell=True)
156 except subprocess.CalledProcessError,e:
157 out.seek(0)
158 if printerr:
159 logger.error("%s" % out.read())
160 raise e
161
162 out.seek(0)
163 output = out.read()
164 logger.debug("output: %s" % output )
165 return output
166
167def action_init(conf, args):
168 """
169 Clone component repositories
170 Check git is initialised; if not, copy initial data from component repos
171 """
172 for name in conf.repos:
173 ldir = conf.repos[name]['local_repo_dir']
174 if not os.path.exists(ldir):
175 logger.info("cloning %s to %s" %(conf.repos[name]['src_uri'], ldir))
176 subprocess.check_call("git clone %s %s" % (conf.repos[name]['src_uri'], ldir), shell=True)
177 if not os.path.exists(".git"):
178 runcmd("git init")
179 for name in conf.repos:
180 repo = conf.repos[name]
181 ldir = repo['local_repo_dir']
182 branch = repo.get('branch', "master")
183 lastrev = repo.get('last_revision', None)
184 if lastrev and lastrev != "HEAD":
185 initialrev = lastrev
186 if branch:
187 if not check_rev_branch(name, ldir, lastrev, branch):
188 sys.exit(1)
189 logger.info("Copying data from %s at specified revision %s..." % (name, lastrev))
190 else:
191 lastrev = None
192 initialrev = branch
193 logger.info("Copying data from %s..." % name)
194 dest_dir = repo['dest_dir']
195 if dest_dir and dest_dir != ".":
196 extract_dir = os.path.join(os.getcwd(), dest_dir)
197 if not os.path.exists(extract_dir):
198 os.makedirs(extract_dir)
199 else:
200 extract_dir = os.getcwd()
201 file_filter = repo.get('file_filter', "")
202 runcmd("git archive %s | tar -x -C %s %s" % (initialrev, extract_dir, file_filter), ldir)
203 if not lastrev:
204 lastrev = runcmd("git rev-parse %s" % initialrev, ldir).strip()
205 conf.update(name, "last_revision", lastrev, initmode=True)
206 runcmd("git add .")
207 if conf.localconffile:
208 localadded = True
209 try:
210 runcmd("git rm --cached %s" % conf.localconffile, printerr=False)
211 except subprocess.CalledProcessError:
212 localadded = False
213 if localadded:
214 localrelpath = os.path.relpath(conf.localconffile)
215 runcmd("grep -q %s .gitignore || echo %s >> .gitignore" % (localrelpath, localrelpath))
216 runcmd("git add .gitignore")
217 logger.info("Added local configuration file %s to .gitignore", localrelpath)
218 logger.info("Initial combo layer repository data has been created; please make any changes if desired and then use 'git commit' to make the initial commit.")
219 else:
220 logger.info("Repository already initialised, nothing to do.")
221
222
223def check_repo_clean(repodir):
224 """
225 check if the repo is clean
226 exit if repo is dirty
227 """
228 output=runcmd("git status --porcelain", repodir)
229 r = re.compile('\?\? patch-.*/')
230 dirtyout = [item for item in output.splitlines() if not r.match(item)]
231 if dirtyout:
232 logger.error("git repo %s is dirty, please fix it first", repodir)
233 sys.exit(1)
234
235def check_patch(patchfile):
236 f = open(patchfile)
237 ln = f.readline()
238 of = None
239 in_patch = False
240 beyond_msg = False
241 pre_buf = ''
242 while ln:
243 if not beyond_msg:
244 if ln == '---\n':
245 if not of:
246 break
247 in_patch = False
248 beyond_msg = True
249 elif ln.startswith('--- '):
250 # We have a diff in the commit message
251 in_patch = True
252 if not of:
253 print('WARNING: %s contains a diff in its commit message, indenting to avoid failure during apply' % patchfile)
254 of = open(patchfile + '.tmp', 'w')
255 of.write(pre_buf)
256 pre_buf = ''
257 elif in_patch and not ln[0] in '+-@ \n\r':
258 in_patch = False
259 if of:
260 if in_patch:
261 of.write(' ' + ln)
262 else:
263 of.write(ln)
264 else:
265 pre_buf += ln
266 ln = f.readline()
267 f.close()
268 if of:
269 of.close()
270 os.rename(patchfile + '.tmp', patchfile)
271
272def drop_to_shell(workdir=None):
273 shell = os.environ.get('SHELL', 'bash')
274 print('Dropping to shell "%s"\n' \
275 'When you are finished, run the following to continue:\n' \
276 ' exit -- continue to apply the patches\n' \
277 ' exit 1 -- abort\n' % shell);
278 ret = subprocess.call([shell], cwd=workdir)
279 if ret != 0:
280 print "Aborting"
281 return False
282 else:
283 return True
284
285def check_rev_branch(component, repodir, rev, branch):
286 try:
287 actualbranch = runcmd("git branch --contains %s" % rev, repodir, printerr=False)
288 except subprocess.CalledProcessError as e:
289 if e.returncode == 129:
290 actualbranch = ""
291 else:
292 raise
293
294 if not actualbranch:
295 logger.error("%s: specified revision %s is invalid!" % (component, rev))
296 return False
297
298 branches = []
299 branchlist = actualbranch.split("\n")
300 for b in branchlist:
301 branches.append(b.strip().split(' ')[-1])
302
303 if branch not in branches:
304 logger.error("%s: specified revision %s is not on specified branch %s!" % (component, rev, branch))
305 return False
306 return True
307
308def get_repos(conf, args):
309 repos = []
310 if len(args) > 1:
311 for arg in args[1:]:
312 if arg.startswith('-'):
313 break
314 else:
315 repos.append(arg)
316 for repo in repos:
317 if not repo in conf.repos:
318 logger.error("Specified component '%s' not found in configuration" % repo)
319 sys.exit(0)
320
321 if not repos:
322 repos = conf.repos
323
324 return repos
325
326def action_pull(conf, args):
327 """
328 update the component repos only
329 """
330 repos = get_repos(conf, args)
331
332 # make sure all repos are clean
333 for name in repos:
334 check_repo_clean(conf.repos[name]['local_repo_dir'])
335
336 for name in repos:
337 repo = conf.repos[name]
338 ldir = repo['local_repo_dir']
339 branch = repo.get('branch', "master")
340 runcmd("git checkout %s" % branch, ldir)
341 logger.info("git pull for component repo %s in %s ..." % (name, ldir))
342 output=runcmd("git pull", ldir)
343 logger.info(output)
344
345def action_update(conf, args):
346 """
347 update the component repos
348 generate the patch list
349 apply the generated patches
350 """
351 repos = get_repos(conf, args)
352
353 # make sure combo repo is clean
354 check_repo_clean(os.getcwd())
355
356 import uuid
357 patch_dir = "patch-%s" % uuid.uuid4()
358 if not os.path.exists(patch_dir):
359 os.mkdir(patch_dir)
360
361 # Step 1: update the component repos
362 if conf.nopull:
363 logger.info("Skipping pull (-n)")
364 else:
365 action_pull(conf, args)
366
367 for name in repos:
368 repo = conf.repos[name]
369 ldir = repo['local_repo_dir']
370 dest_dir = repo['dest_dir']
371 branch = repo.get('branch', "master")
372 repo_patch_dir = os.path.join(os.getcwd(), patch_dir, name)
373
374 # Step 2: generate the patch list and store to patch dir
375 logger.info("Generating patches from %s..." % name)
376 if dest_dir != ".":
377 prefix = "--src-prefix=a/%s/ --dst-prefix=b/%s/" % (dest_dir, dest_dir)
378 else:
379 prefix = ""
380 if repo['last_revision'] == "":
381 logger.info("Warning: last_revision of component %s is not set, starting from the first commit" % name)
382 patch_cmd_range = "--root %s" % branch
383 rev_cmd_range = branch
384 else:
385 if not check_rev_branch(name, ldir, repo['last_revision'], branch):
386 sys.exit(1)
387 patch_cmd_range = "%s..%s" % (repo['last_revision'], branch)
388 rev_cmd_range = patch_cmd_range
389
390 file_filter = repo.get('file_filter',"")
391
392 patch_cmd = "git format-patch -N %s --output-directory %s %s -- %s" % \
393 (prefix,repo_patch_dir, patch_cmd_range, file_filter)
394 output = runcmd(patch_cmd, ldir)
395 logger.debug("generated patch set:\n%s" % output)
396 patchlist = output.splitlines()
397
398 rev_cmd = 'git rev-list --no-merges ' + rev_cmd_range
399 revlist = runcmd(rev_cmd, ldir).splitlines()
400
401 # Step 3: Call repo specific hook to adjust patch
402 if 'hook' in repo:
403 # hook parameter is: ./hook patchpath revision reponame
404 count=len(revlist)-1
405 for patch in patchlist:
406 runcmd("%s %s %s %s" % (repo['hook'], patch, revlist[count], name))
407 count=count-1
408
409 # Step 4: write patch list and revision list to file, for user to edit later
410 patchlist_file = os.path.join(os.getcwd(), patch_dir, "patchlist-%s" % name)
411 repo['patchlist'] = patchlist_file
412 f = open(patchlist_file, 'w')
413 count=len(revlist)-1
414 for patch in patchlist:
415 f.write("%s %s\n" % (patch, revlist[count]))
416 check_patch(os.path.join(patch_dir, patch))
417 count=count-1
418 f.close()
419
420 # Step 5: invoke bash for user to edit patch and patch list
421 if conf.interactive:
422 print('You may now edit the patch and patch list in %s\n' \
423 'For example, you can remove unwanted patch entries from patchlist-*, so that they will be not applied later' % patch_dir);
424 if not drop_to_shell(patch_dir):
425 sys.exit(0)
426
427 # Step 6: apply the generated and revised patch
428 apply_patchlist(conf, repos)
429 runcmd("rm -rf %s" % patch_dir)
430
431 # Step 7: commit the updated config file if it's being tracked
432 relpath = os.path.relpath(conf.conffile)
433 try:
434 output = runcmd("git status --porcelain %s" % relpath, printerr=False)
435 except:
436 # Outside the repository
437 output = None
438 if output:
439 logger.info("Committing updated configuration file")
440 if output.lstrip().startswith("M"):
441 runcmd('git commit -m "Automatic commit to update last_revision" %s' % relpath)
442
443def apply_patchlist(conf, repos):
444 """
445 apply the generated patch list to combo repo
446 """
447 for name in repos:
448 repo = conf.repos[name]
449 lastrev = repo["last_revision"]
450 prevrev = lastrev
451
452 # Get non-blank lines from patch list file
453 patchlist = []
454 if os.path.exists(repo['patchlist']) or not conf.interactive:
455 # Note: we want this to fail here if the file doesn't exist and we're not in
456 # interactive mode since the file should exist in this case
457 with open(repo['patchlist']) as f:
458 for line in f:
459 line = line.rstrip()
460 if line:
461 patchlist.append(line)
462
463 if patchlist:
464 logger.info("Applying patches from %s..." % name)
465 linecount = len(patchlist)
466 i = 1
467 for line in patchlist:
468 patchfile = line.split()[0]
469 lastrev = line.split()[1]
470 patchdisp = os.path.relpath(patchfile)
471 if os.path.getsize(patchfile) == 0:
472 logger.info("(skipping %d/%d %s - no changes)" % (i, linecount, patchdisp))
473 else:
474 cmd = "git am --keep-cr -s -p1 %s" % patchfile
475 logger.info("Applying %d/%d: %s" % (i, linecount, patchdisp))
476 try:
477 runcmd(cmd)
478 except subprocess.CalledProcessError:
479 logger.info('Running "git am --abort" to cleanup repo')
480 runcmd("git am --abort")
481 logger.error('"%s" failed' % cmd)
482 logger.info("Please manually apply patch %s" % patchdisp)
483 logger.info("Note: if you exit and continue applying without manually applying the patch, it will be skipped")
484 if not drop_to_shell():
485 if prevrev != repo['last_revision']:
486 conf.update(name, "last_revision", prevrev)
487 sys.exit(0)
488 prevrev = lastrev
489 i += 1
490 else:
491 logger.info("No patches to apply from %s" % name)
492 ldir = conf.repos[name]['local_repo_dir']
493 branch = conf.repos[name].get('branch', "master")
494 lastrev = runcmd("git rev-parse %s" % branch, ldir).strip()
495
496 if lastrev != repo['last_revision']:
497 conf.update(name, "last_revision", lastrev)
498
499def action_splitpatch(conf, args):
500 """
501 generate the commit patch and
502 split the patch per repo
503 """
504 logger.debug("action_splitpatch")
505 if len(args) > 1:
506 commit = args[1]
507 else:
508 commit = "HEAD"
509 patchdir = "splitpatch-%s" % commit
510 if not os.path.exists(patchdir):
511 os.mkdir(patchdir)
512
513 # filerange_root is for the repo whose dest_dir is root "."
514 # and it should be specified by excluding all other repo dest dir
515 # like "-x repo1 -x repo2 -x repo3 ..."
516 filerange_root = ""
517 for name in conf.repos:
518 dest_dir = conf.repos[name]['dest_dir']
519 if dest_dir != ".":
520 filerange_root = '%s -x "%s/*"' % (filerange_root, dest_dir)
521
522 for name in conf.repos:
523 dest_dir = conf.repos[name]['dest_dir']
524 patch_filename = "%s/%s.patch" % (patchdir, name)
525 if dest_dir == ".":
526 cmd = "git format-patch -n1 --stdout %s^..%s | filterdiff -p1 %s > %s" % (commit, commit, filerange_root, patch_filename)
527 else:
528 cmd = "git format-patch --no-prefix -n1 --stdout %s^..%s -- %s > %s" % (commit, commit, dest_dir, patch_filename)
529 runcmd(cmd)
530 # Detect empty patches (including those produced by filterdiff above
531 # that contain only preamble text)
532 if os.path.getsize(patch_filename) == 0 or runcmd("filterdiff %s" % patch_filename) == "":
533 os.remove(patch_filename)
534 logger.info("(skipping %s - no changes)", name)
535 else:
536 logger.info(patch_filename)
537
538def action_error(conf, args):
539 logger.info("invalid action %s" % args[0])
540
541actions = {
542 "init": action_init,
543 "update": action_update,
544 "pull": action_pull,
545 "splitpatch": action_splitpatch,
546}
547
548def main():
549 parser = optparse.OptionParser(
550 version = "Combo Layer Repo Tool version %s" % __version__,
551 usage = """%prog [options] action
552
553Create and update a combination layer repository from multiple component repositories.
554
555Action:
556 init initialise the combo layer repo
557 update [components] get patches from component repos and apply them to the combo repo
558 pull [components] just pull component repos only
559 splitpatch [commit] generate commit patch and split per component, default commit is HEAD""")
560
561 parser.add_option("-c", "--conf", help = "specify the config file (conf/combo-layer.conf is the default).",
562 action = "store", dest = "conffile", default = "conf/combo-layer.conf")
563
564 parser.add_option("-i", "--interactive", help = "interactive mode, user can edit the patch list and patches",
565 action = "store_true", dest = "interactive", default = False)
566
567 parser.add_option("-D", "--debug", help = "output debug information",
568 action = "store_true", dest = "debug", default = False)
569
570 parser.add_option("-n", "--no-pull", help = "skip pulling component repos during update",
571 action = "store_true", dest = "nopull", default = False)
572
573 options, args = parser.parse_args(sys.argv)
574
575 # Dispatch to action handler
576 if len(args) == 1:
577 logger.error("No action specified, exiting")
578 parser.print_help()
579 elif args[1] not in actions:
580 logger.error("Unsupported action %s, exiting\n" % (args[1]))
581 parser.print_help()
582 elif not os.path.exists(options.conffile):
583 logger.error("No valid config file, exiting\n")
584 parser.print_help()
585 else:
586 if options.debug:
587 logger.setLevel(logging.DEBUG)
588 confdata = Configuration(options)
589 initmode = (args[1] == 'init')
590 confdata.sanity_check(initmode)
591 actions.get(args[1], action_error)(confdata, args[1:])
592
593if __name__ == "__main__":
594 try:
595 ret = main()
596 except Exception:
597 ret = 1
598 import traceback
599 traceback.print_exc(5)
600 sys.exit(ret)
diff --git a/scripts/combo-layer-hook-default.sh b/scripts/combo-layer-hook-default.sh
new file mode 100755
index 0000000000..8b148aca07
--- /dev/null
+++ b/scripts/combo-layer-hook-default.sh
@@ -0,0 +1,13 @@
1#!/bin/sh
2# Hook to add source component/revision info to commit message
3# Parameter:
4# $1 patch-file
5# $2 revision
6# $3 reponame
7
8patchfile=$1
9rev=$2
10reponame=$3
11
12sed -i -e "s#^Subject: \[PATCH\] \(.*\)#Subject: \[PATCH\] $reponame: \1#" $patchfile
13sed -i -e "0,/^Signed-off-by:/s#\(^Signed-off-by:.*\)#\($reponame rev: $rev\)\n\n\1#" $patchfile
diff --git a/scripts/combo-layer.conf.example b/scripts/combo-layer.conf.example
new file mode 100644
index 0000000000..010a692350
--- /dev/null
+++ b/scripts/combo-layer.conf.example
@@ -0,0 +1,56 @@
1# combo-layer example configuration file
2
3# component name
4[bitbake]
5# mandatory options
6# git upstream uri
7src_uri = git://git.openembedded.org/bitbake
8
9# the directory to clone the component repo
10local_repo_dir = /home/kyu3/src/test/bitbake
11
12# the relative dir within the combo repo to put the component files
13# use "." if the files should be in the root dir
14dest_dir = bitbake
15
16# the last update revision.
17# "init" will set this to the latest revision automatically, however if it
18# is empty when "update" is run, the tool will start from the first commit.
19# Note that this value will get updated by "update" if the component repo's
20# latest revision changed and the operation completes successfully.
21last_revision =
22
23# optional options:
24
25# branch: specify the branch in the component repo to pull from
26# (master if not specified)
27
28# file_filter: only include the specified file(s)
29# file_filter = [path] [path] ...
30# example:
31# file_filter = src/ : only include the subdir src
32# file_filter = src/*.c : only include the src *.c file
33# file_filter = src/main.c src/Makefile.am : only include these two files
34
35# hook: if provided, the tool will call the hook to process the generated
36# patch from upstream, and then apply the modified patch to the combo
37# repo.
38# the hook script is called as follows: ./hook patchpath revision reponame
39# example:
40# hook = combo-layer-hook-default.sh
41
42[oe-core]
43src_uri = git://git.openembedded.org/openembedded-core
44local_repo_dir = /home/kyu3/src/test/oecore
45dest_dir = .
46last_revision =
47
48# It is also possible to embed python code in the config values. Similar
49# to bitbake it considers every value starting with @ to be a python
50# script.
51# e.g. local_repo_dir could easily be configured using an environment
52# variable:
53#
54# [bitbake]
55# local_repo_dir = @os.getenv("LOCAL_REPO_DIR") + "/bitbake"
56#
diff --git a/scripts/contrib/bb-perf/bb-matrix-plot.sh b/scripts/contrib/bb-perf/bb-matrix-plot.sh
new file mode 100755
index 0000000000..136a25570d
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix-plot.sh
@@ -0,0 +1,137 @@
1#!/bin/bash
2#
3# Copyright (c) 2011, Intel Corporation.
4# All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20# DESCRIPTION
21# This script operates on the .dat file generated by bb-matrix.sh. It tolerates
22# the header by skipping the first line, but error messages and bad data records
23# need to be removed first. It will generate three views of the plot, and leave
24# an interactive view open for further analysis.
25#
26# AUTHORS
27# Darren Hart <dvhart@linux.intel.com>
28#
29
30# Setup the defaults
31DATFILE="bb-matrix.dat"
32XLABEL="BB_NUMBER_THREADS"
33YLABEL="PARALLEL_MAKE"
34FIELD=3
35DEF_TITLE="Elapsed Time (seconds)"
36PM3D_FRAGMENT="unset surface; set pm3d at s hidden3d 100"
37SIZE="640,480"
38
39function usage {
40CMD=$(basename $0)
41cat <<EOM
42Usage: $CMD [-d datfile] [-f field] [-h] [-t title] [-w]
43 -d datfile The data file generated by bb-matrix.sh (default: $DATFILE)
44 -f field The field index to plot as the Z axis from the data file
45 (default: $FIELD, "$DEF_TITLE")
46 -h Display this help message
47 -s W,H PNG and window size in pixels (default: $SIZE)
48 -t title The title to display, should describe the field (-f) and units
49 (default: "$DEF_TITLE")
50 -w Render the plot as wireframe with a 2D colormap projected on the
51 XY plane rather than as the texture for the surface
52EOM
53}
54
55# Parse and validate arguments
56while getopts "d:f:hs:t:w" OPT; do
57 case $OPT in
58 d)
59 DATFILE="$OPTARG"
60 ;;
61 f)
62 FIELD="$OPTARG"
63 ;;
64 h)
65 usage
66 exit 0
67 ;;
68 s)
69 SIZE="$OPTARG"
70 ;;
71 t)
72 TITLE="$OPTARG"
73 ;;
74 w)
75 PM3D_FRAGMENT="set pm3d at b"
76 W="-w"
77 ;;
78 *)
79 usage
80 exit 1
81 ;;
82 esac
83done
84
85# Ensure the data file exists
86if [ ! -f "$DATFILE" ]; then
87 echo "ERROR: $DATFILE does not exist"
88 usage
89 exit 1
90fi
91PLOT_BASENAME=${DATFILE%.*}-f$FIELD$W
92
93# Set a sane title
94# TODO: parse the header and define titles for each format parameter for TIME(1)
95if [ -z "$TITLE" ]; then
96 if [ ! "$FIELD" == "3" ]; then
97 TITLE="Field $FIELD"
98 else
99 TITLE="$DEF_TITLE"
100 fi
101fi
102
103# Determine the dgrid3d mesh dimensions size
104MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | head -n1)
105MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 1 | sed 's/^0*//' | sort -n | uniq | tail -n1)
106BB_CNT=$[${MAX} - $MIN + 1]
107MIN=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | head -n1)
108MAX=$(tail -n +2 "$DATFILE" | cut -d ' ' -f 2 | sed 's/^0*//' | sort -n | uniq | tail -n1)
109PM_CNT=$[${MAX} - $MIN + 1]
110
111
112(cat <<EOF
113set title "$TITLE"
114set xlabel "$XLABEL"
115set ylabel "$YLABEL"
116set style line 100 lt 5 lw 1.5
117$PM3D_FRAGMENT
118set dgrid3d $PM_CNT,$BB_CNT splines
119set ticslevel 0.2
120
121set term png size $SIZE
122set output "$PLOT_BASENAME.png"
123splot "$DATFILE" every ::1 using 1:2:$FIELD with lines ls 100
124
125set view 90,0
126set output "$PLOT_BASENAME-bb.png"
127replot
128
129set view 90,90
130set output "$PLOT_BASENAME-pm.png"
131replot
132
133set view 60,30
134set term wxt size $SIZE
135replot
136EOF
137) | gnuplot --persist
diff --git a/scripts/contrib/bb-perf/bb-matrix.sh b/scripts/contrib/bb-perf/bb-matrix.sh
new file mode 100755
index 0000000000..106456584d
--- /dev/null
+++ b/scripts/contrib/bb-perf/bb-matrix.sh
@@ -0,0 +1,79 @@
1#!/bin/bash
2#
3# Copyright (c) 2011, Intel Corporation.
4# All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20# DESCRIPTION
21# This script runs BB_CMD (typically building core-image-sato) for all
22# combincations of BB_RANGE and PM_RANGE values. It saves off all the console
23# logs, the buildstats directories, and creates a bb-pm-runtime.dat file which
24# can be used to postprocess the results with a plotting tool, spreadsheet, etc.
25# Before running this script, it is recommended that you pre-download all the
26# necessary sources by performing the BB_CMD once manually. It is also a good
27# idea to disable cron to avoid runtime variations caused by things like the
28# locate process. Be sure to sanitize the dat file prior to post-processing as
29# it may contain error messages or bad runs that should be removed.
30#
31# AUTHORS
32# Darren Hart <dvhart@linux.intel.com>
33#
34
35# The following ranges are appropriate for a 4 core system with 8 logical units
36# Use leading 0s to ensure all digits are the same string length, this results
37# in nice log file names and columnar dat files.
38BB_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
39PM_RANGE="04 05 06 07 08 09 10 11 12 13 14 15 16"
40
41DATADIR="bb-matrix-$$"
42BB_CMD="bitbake core-image-minimal"
43RUNTIME_LOG="$DATADIR/bb-matrix.dat"
44
45# See TIME(1) for a description of the time format parameters
46# The following all report 0: W K r s t w
47TIME_STR="%e %S %U %P %c %w %R %F %M %x"
48
49# Prepare the DATADIR
50mkdir $DATADIR
51if [ $? -ne 0 ]; then
52 echo "Failed to create $DATADIR."
53 exit 1
54fi
55
56# Add a simple header
57echo "BB PM $TIME_STR" > $RUNTIME_LOG
58for BB in $BB_RANGE; do
59 for PM in $PM_RANGE; do
60 RUNDIR="$DATADIR/$BB-$PM-build"
61 mkdir $RUNDIR
62 BB_LOG=$RUNDIR/$BB-$PM-bitbake.log
63 date
64 echo "BB=$BB PM=$PM Logging to $BB_LOG"
65
66 echo -n " Preparing the work directory... "
67 rm -rf pseudodone tmp sstate-cache tmp-eglibc &> /dev/null
68 echo "done"
69
70 # Export the variables under test and run the bitbake command
71 # Strip any leading zeroes before passing to bitbake
72 export BB_NUMBER_THREADS=$(echo $BB | sed 's/^0*//')
73 export PARALLEL_MAKE="-j $(echo $PM | sed 's/^0*//')"
74 /usr/bin/time -f "$BB $PM $TIME_STR" -a -o $RUNTIME_LOG $BB_CMD &> $BB_LOG
75
76 echo " $(tail -n1 $RUNTIME_LOG)"
77 cp -a tmp/buildstats $RUNDIR/$BB-$PM-buildstats
78 done
79done
diff --git a/scripts/contrib/bbvars.py b/scripts/contrib/bbvars.py
new file mode 100755
index 0000000000..0896d64445
--- /dev/null
+++ b/scripts/contrib/bbvars.py
@@ -0,0 +1,186 @@
1#!/usr/bin/env python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16#
17# Copyright (C) Darren Hart <dvhart@linux.intel.com>, 2010
18
19
20import sys
21import getopt
22import os
23import os.path
24import re
25
26def usage():
27 print 'Usage: %s -d FILENAME [-d FILENAME]* -m METADIR [-m MATADIR]*' % os.path.basename(sys.argv[0])
28 print ' -d FILENAME documentation file to search'
29 print ' -h, --help display this help and exit'
30 print ' -m METADIR meta directory to search for recipes'
31 print ' -t FILENAME documentation config file (for doc tags)'
32 print ' -T Only display variables with doc tags (requires -t)'
33
34def recipe_bbvars(recipe):
35 ''' Return a unique set of every bbvar encountered in the recipe '''
36 prog = re.compile("[A-Z_]+")
37 vset = set()
38 try:
39 r = open(recipe)
40 except IOError as (errno, strerror):
41 print 'WARNING: Failed to open recipe ', recipe
42 print strerror
43
44 for line in r:
45 # Strip any comments from the line
46 line = line.rsplit('#')[0]
47 vset = vset.union(set(prog.findall(line)))
48 r.close()
49
50 bbvars = {}
51 for v in vset:
52 bbvars[v] = 1
53
54 return bbvars
55
56def collect_bbvars(metadir):
57 ''' Walk the metadir and collect the bbvars from each recipe found '''
58 bbvars = {}
59 for root,dirs,files in os.walk(metadir):
60 for name in files:
61 if name.find(".bb") >= 0:
62 for key in recipe_bbvars(os.path.join(root,name)).iterkeys():
63 if bbvars.has_key(key):
64 bbvars[key] = bbvars[key] + 1
65 else:
66 bbvars[key] = 1
67 return bbvars
68
69def bbvar_is_documented(var, docfiles):
70 prog = re.compile(".*($|[^A-Z_])%s([^A-Z_]|$)" % (var))
71 for doc in docfiles:
72 try:
73 f = open(doc)
74 except IOError as (errno, strerror):
75 print 'WARNING: Failed to open doc ', doc
76 print strerror
77 for line in f:
78 if prog.match(line):
79 return True
80 f.close()
81 return False
82
83def bbvar_doctag(var, docconf):
84 prog = re.compile('^%s\[doc\] *= *"(.*)"' % (var))
85 if docconf == "":
86 return "?"
87
88 try:
89 f = open(docconf)
90 except IOError as (errno, strerror):
91 return strerror
92
93 for line in f:
94 m = prog.search(line)
95 if m:
96 return m.group(1)
97
98 f.close()
99 return ""
100
101def main():
102 docfiles = []
103 metadirs = []
104 bbvars = {}
105 undocumented = []
106 docconf = ""
107 onlydoctags = False
108
109 # Collect and validate input
110 try:
111 opts, args = getopt.getopt(sys.argv[1:], "d:hm:t:T", ["help"])
112 except getopt.GetoptError, err:
113 print '%s' % str(err)
114 usage()
115 sys.exit(2)
116
117 for o, a in opts:
118 if o in ('-h', '--help'):
119 usage()
120 sys.exit(0)
121 elif o == '-d':
122 if os.path.isfile(a):
123 docfiles.append(a)
124 else:
125 print 'ERROR: documentation file %s is not a regular file' % (a)
126 sys.exit(3)
127 elif o == '-m':
128 if os.path.isdir(a):
129 metadirs.append(a)
130 else:
131 print 'ERROR: meta directory %s is not a directory' % (a)
132 sys.exit(4)
133 elif o == "-t":
134 if os.path.isfile(a):
135 docconf = a
136 elif o == "-T":
137 onlydoctags = True
138 else:
139 assert False, "unhandled option"
140
141 if len(docfiles) == 0:
142 print 'ERROR: no docfile specified'
143 usage()
144 sys.exit(5)
145
146 if len(metadirs) == 0:
147 print 'ERROR: no metadir specified'
148 usage()
149 sys.exit(6)
150
151 if onlydoctags and docconf == "":
152 print 'ERROR: no docconf specified'
153 usage()
154 sys.exit(7)
155
156 # Collect all the variable names from the recipes in the metadirs
157 for m in metadirs:
158 for key,cnt in collect_bbvars(m).iteritems():
159 if bbvars.has_key(key):
160 bbvars[key] = bbvars[key] + cnt
161 else:
162 bbvars[key] = cnt
163
164 # Check each var for documentation
165 varlen = 0
166 for v in bbvars.iterkeys():
167 if len(v) > varlen:
168 varlen = len(v)
169 if not bbvar_is_documented(v, docfiles):
170 undocumented.append(v)
171 undocumented.sort()
172 varlen = varlen + 1
173
174 # Report all undocumented variables
175 print 'Found %d undocumented bb variables (out of %d):' % (len(undocumented), len(bbvars))
176 header = '%s%s%s' % (str("VARIABLE").ljust(varlen), str("COUNT").ljust(6), str("DOCTAG").ljust(7))
177 print header
178 print str("").ljust(len(header), '=')
179 for v in undocumented:
180 doctag = bbvar_doctag(v, docconf)
181 if not onlydoctags or not doctag == "":
182 print '%s%s%s' % (v.ljust(varlen), str(bbvars[v]).ljust(6), doctag)
183
184
185if __name__ == "__main__":
186 main()
diff --git a/scripts/contrib/build-perf-test.sh b/scripts/contrib/build-perf-test.sh
new file mode 100755
index 0000000000..be3b648046
--- /dev/null
+++ b/scripts/contrib/build-perf-test.sh
@@ -0,0 +1,369 @@
1#!/bin/bash
2#
3# This script runs a series of tests (with and without sstate) and reports build time (and tmp/ size)
4#
5# Build performance test script
6#
7# Copyright 2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22#
23#
24# AUTHORS:
25# Stefan Stanacar <stefanx.stanacar@intel.com>
26
27
28ME=$(basename $0)
29
30#
31# usage and setup
32#
33
34usage () {
35cat << EOT
36Usage: $ME [-h]
37 $ME [-c <commit>] [-v] [-m <val>] [-j <val>] [-t <val>] [-i <image-name>] [-d <path>]
38Options:
39 -h
40 Display this help and exit.
41 -c <commit>
42 git checkout <commit> before anything else
43 -v
44 Show bitbake output, don't redirect it to a log.
45 -m <machine>
46 Value for MACHINE. Default is qemux86.
47 -j <val>
48 Value for PARALLEL_MAKE. Default is 8.
49 -t <val>
50 Value for BB_NUMBER_THREADS. Default is 8.
51 -i <image-name>
52 Instead of timing against core-image-sato, use <image-name>
53 -d <path>
54 Use <path> as DL_DIR
55 -p <githash>
56 Cherry pick githash onto the commit
57
58Note: current working directory must be inside a poky git clone.
59
60EOT
61}
62
63
64if clonedir=$(git rev-parse --show-toplevel); then
65 cd $clonedir
66else
67 echo "The current working dir doesn't seem to be a poky git clone. Please cd there before running $ME"
68 exit 1
69fi
70
71IMAGE="core-image-sato"
72verbose=0
73dldir=
74commit=
75pmake=
76cherrypicks=
77while getopts "hvc:m:j:t:i:d:p:" opt; do
78 case $opt in
79 h) usage
80 exit 0
81 ;;
82 v) verbose=1
83 ;;
84 c) commit=$OPTARG
85 ;;
86 m) export MACHINE=$OPTARG
87 ;;
88 j) pmake=$OPTARG
89 ;;
90 t) export BB_NUMBER_THREADS=$OPTARG
91 ;;
92 i) IMAGE=$OPTARG
93 ;;
94 d) dldir=$OPTARG
95 ;;
96 p) cherrypicks="$cherrypicks $OPTARG"
97 ;;
98 *) usage
99 exit 1
100 ;;
101 esac
102done
103
104
105#drop cached credentials and test for sudo access without a password
106sudo -k -n ls > /dev/null 2>&1
107reqpass=$?
108if [ $reqpass -ne 0 ]; then
109 echo "The script requires sudo access to drop caches between builds (echo 3 > /proc/sys/vm/drop_caches)"
110 read -s -p "Please enter your sudo password: " pass
111 echo
112fi
113
114if [ -n "$commit" ]; then
115 echo "git checkout -f $commit"
116 git pull > /dev/null 2>&1
117 git checkout -f $commit || exit 1
118 git pull > /dev/null 2>&1
119fi
120
121if [ -n "$cherrypicks" ]; then
122 for c in $cherrypicks; do
123 git cherry-pick $c
124 done
125fi
126
127rev=$(git rev-parse --short HEAD) || exit 1
128OUTDIR="$clonedir/build-perf-test/results-$rev-`date "+%Y%m%d%H%M%S"`"
129BUILDDIR="$OUTDIR/build"
130resultsfile="$OUTDIR/results.log"
131bboutput="$OUTDIR/bitbake.log"
132myoutput="$OUTDIR/output.log"
133globalres="$clonedir/build-perf-test/globalres.log"
134
135mkdir -p $OUTDIR || exit 1
136
137log () {
138 local msg="$1"
139 echo "`date`: $msg" | tee -a $myoutput
140}
141
142
143#
144# Config stuff
145#
146
147branch=`git branch 2>&1 | grep "^* " | tr -d "* "`
148gitcommit=$(git rev-parse HEAD) || exit 1
149log "Running on $branch:$gitcommit"
150
151source ./oe-init-build-env $OUTDIR/build >/dev/null || exit 1
152cd $OUTDIR/build
153
154[ -n "$MACHINE" ] || export MACHINE="qemux86"
155[ -n "$BB_NUMBER_THREADS" ] || export BB_NUMBER_THREADS="8"
156
157if [ -n "$pmake" ]; then
158 export PARALLEL_MAKE="-j $pmake"
159else
160 export PARALLEL_MAKE="-j 8"
161fi
162
163if [ -n "$dldir" ]; then
164 echo "DL_DIR = \"$dldir\"" >> conf/local.conf
165else
166 echo "DL_DIR = \"$clonedir/build-perf-test/downloads\"" >> conf/local.conf
167fi
168
169# Sometimes I've noticed big differences in timings for the same commit, on the same machine
170# Disabling the network sanity check helps a bit (because of my crappy network connection and/or proxy)
171echo "CONNECTIVITY_CHECK_URIS =\"\"" >> conf/local.conf
172
173
174#
175# Functions
176#
177
178declare -a TIMES
179time_count=0
180declare -a SIZES
181size_count=0
182
183bbtime () {
184 local arg="$@"
185 log " Timing: bitbake ${arg}"
186
187 if [ $verbose -eq 0 ]; then
188 /usr/bin/time -v -o $resultsfile bitbake ${arg} >> $bboutput
189 else
190 /usr/bin/time -v -o $resultsfile bitbake ${arg}
191 fi
192 ret=$?
193 if [ $ret -eq 0 ]; then
194 t=`grep wall $resultsfile | sed 's/.*m:ss): //'`
195 log " TIME: $t"
196 TIMES[(( time_count++ ))]="$t"
197 else
198 log "ERROR: exit status was non-zero, will report time as 0."
199 TIMES[(( time_count++ ))]="0"
200 fi
201
202 #time by default overwrites the output file and we want to keep the results
203 #it has an append option but I don't want to clobber the results in the same file
204 i=`ls $OUTDIR/results.log* |wc -l`
205 mv $resultsfile "${resultsfile}.${i}"
206 log "More stats can be found in ${resultsfile}.${i}"
207}
208
209#we don't time bitbake here
210bbnotime () {
211 local arg="$@"
212 log " Running: bitbake ${arg}"
213 if [ $verbose -eq 0 ]; then
214 bitbake ${arg} >> $bboutput
215 else
216 bitbake ${arg}
217 fi
218 ret=$?
219 if [ $ret -eq 0 ]; then
220 log " Finished bitbake ${arg}"
221 else
222 log "ERROR: exit status was non-zero. Exit.."
223 exit $ret
224 fi
225
226}
227
228do_rmtmp() {
229 log " Removing tmp"
230 rm -rf bitbake.lock pseudodone conf/sanity_info cache tmp
231}
232do_rmsstate () {
233 log " Removing sstate-cache"
234 rm -rf sstate-cache
235}
236do_sync () {
237 log " Syncing and dropping caches"
238 sync; sync
239 if [ $reqpass -eq 0 ]; then
240 sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
241 else
242 echo "$pass" | sudo -S sh -c "echo 3 > /proc/sys/vm/drop_caches"
243 echo
244 fi
245 sleep 3
246}
247
248write_results() {
249 echo -n "`uname -n`,$branch:$gitcommit,`git describe`," >> $globalres
250 for i in "${TIMES[@]}"; do
251 echo -n "$i," >> $globalres
252 done
253 for i in "${SIZES[@]}"; do
254 echo -n "$i," >> $globalres
255 done
256 echo >> $globalres
257 sed -i '$ s/,$//' $globalres
258}
259
260####
261
262#
263# Test 1
264# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir (w/o rm_work and w/ rm_work)
265# Pre: Downloaded sources, no sstate
266# Steps:
267# Part1:
268# - fetchall
269# - clean build dir
270# - time bitbake core-image-sato
271# - collect data
272# Part2:
273# - bitbake virtual/kernel -c cleansstate
274# - time bitbake virtual/kernel
275# Part3:
276# - add INHERIT to local.conf
277# - clean build dir
278# - build
279# - report size, remove INHERIT
280
281test1_p1 () {
282 log "Running Test 1, part 1/3: Measure wall clock of bitbake $IMAGE and size of tmp/ dir"
283 bbnotime $IMAGE -c fetchall
284 do_rmtmp
285 do_rmsstate
286 do_sync
287 bbtime $IMAGE
288 s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
289 SIZES[(( size_count++ ))]="$s"
290 log "SIZE of tmp dir is: $s"
291 log "Buildstats are saved in $OUTDIR/buildstats-test1"
292 mv tmp/buildstats $OUTDIR/buildstats-test1
293}
294
295
296test1_p2 () {
297 log "Running Test 1, part 2/3: bitbake virtual/kernel -c cleansstate and time bitbake virtual/kernel"
298 bbnotime virtual/kernel -c cleansstate
299 do_sync
300 bbtime virtual/kernel
301}
302
303test1_p3 () {
304 log "Running Test 1, part 3/3: Build $IMAGE w/o sstate and report size of tmp/dir with rm_work enabled"
305 echo "INHERIT += \"rm_work\"" >> conf/local.conf
306 do_rmtmp
307 do_rmsstate
308 do_sync
309 bbtime $IMAGE
310 sed -i 's/INHERIT += \"rm_work\"//' conf/local.conf
311 s=`du -s tmp | sed 's/tmp//' | sed 's/[ \t]*$//'`
312 SIZES[(( size_count++ ))]="$s"
313 log "SIZE of tmp dir is: $s"
314 log "Buildstats are saved in $OUTDIR/buildstats-test13"
315 mv tmp/buildstats $OUTDIR/buildstats-test13
316}
317
318
319#
320# Test 2
321# Measure: Wall clock of "bitbake core-image-sato" and size of tmp/dir
322# Pre: populated sstate cache
323
324test2 () {
325 # Assuming test 1 has run
326 log "Running Test 2: Measure wall clock of bitbake $IMAGE -c rootfs with sstate"
327 do_rmtmp
328 do_sync
329 bbtime $IMAGE -c rootfs
330}
331
332
333# Test 3
334# parsing time metrics
335#
336# Start with
337# i) "rm -rf tmp/cache; time bitbake -p"
338# ii) "rm -rf tmp/cache/default-eglibc/; time bitbake -p"
339# iii) "time bitbake -p"
340
341
342test3 () {
343 log "Running Test 3: Parsing time metrics (bitbake -p)"
344 log " Removing tmp/cache && cache"
345 rm -rf tmp/cache cache
346 bbtime -p
347 log " Removing tmp/cache/default-eglibc/"
348 rm -rf tmp/cache/default-eglibc/
349 bbtime -p
350 bbtime -p
351}
352
353
354
355# RUN!
356
357test1_p1
358test1_p2
359test1_p3
360test2
361test3
362
363# if we got til here write to global results
364write_results
365
366log "All done, cleaning up..."
367
368do_rmtmp
369do_rmsstate
diff --git a/scripts/contrib/ddimage b/scripts/contrib/ddimage
new file mode 100755
index 0000000000..93ebeafc31
--- /dev/null
+++ b/scripts/contrib/ddimage
@@ -0,0 +1,89 @@
1#!/bin/sh
2
3#BLACKLIST_DEVICES="/dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde"
4BLACKLIST_DEVICES="/dev/sda"
5
6# 1MB blocksize
7BLOCKSIZE=1048576
8
9usage() {
10 echo "Usage: $(basename $0) IMAGE DEVICE"
11}
12
13image_details() {
14 IMG=$1
15 echo "Image details"
16 echo "============="
17 echo " image: $(stat --printf '%N\n' $IMG)"
18 echo " size: $(stat -L --printf '%s bytes\n' $IMG)"
19 echo " modified: $(stat -L --printf '%y\n' $IMG)"
20 echo " type: $(file -L -b $IMG)"
21 echo ""
22}
23
24device_details() {
25 DEV=$1
26 BLOCK_SIZE=512
27
28 echo "Device details"
29 echo "=============="
30 echo " device: $DEVICE"
31 if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
32 echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
33 else
34 echo " vendor: UNKOWN"
35 fi
36 if [ -f "/sys/class/block/$DEV/device/model" ]; then
37 echo " model: $(cat /sys/class/block/$DEV/device/model)"
38 else
39 echo " model: UNKNOWN"
40 fi
41 if [ -f "/sys/class/block/$DEV/size" ]; then
42 echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
43 else
44 echo " size: UNKNOWN"
45 fi
46 echo ""
47}
48
49if [ $# -ne 2 ]; then
50 usage
51 exit 1
52fi
53
54IMAGE=$1
55DEVICE=$2
56
57if [ ! -e "$IMAGE" ]; then
58 echo "ERROR: Image $IMAGE does not exist"
59 usage
60 exit 1
61fi
62
63
64for i in ${BLACKLIST_DEVICES}; do
65 if [ "$i" = "$DEVICE" ]; then
66 echo "ERROR: Device $DEVICE is blacklisted"
67 exit 1
68 fi
69done
70
71if [ ! -w "$DEVICE" ]; then
72 echo "ERROR: Device $DEVICE does not exist or is not writable"
73 usage
74 exit 1
75fi
76
77image_details $IMAGE
78device_details $(basename $DEVICE)
79
80printf "Write $IMAGE to $DEVICE [y/N]? "
81read RESPONSE
82if [ "$RESPONSE" != "y" ]; then
83 echo "Write aborted"
84 exit 0
85fi
86
87echo "Writing image..."
88dd if="$IMAGE" of="$DEVICE" bs="$BLOCKSIZE"
89sync
diff --git a/scripts/contrib/documentation-audit.sh b/scripts/contrib/documentation-audit.sh
new file mode 100755
index 0000000000..2144aac936
--- /dev/null
+++ b/scripts/contrib/documentation-audit.sh
@@ -0,0 +1,94 @@
1#!/bin/bash
2#
3# Perform an audit of which packages provide documentation and which
4# are missing -doc packages.
5#
6# Setup requirements: be sure to be building for MACHINE=qemux86. Run
7# this script after source'ing the build environment script, so you're
8# running it from build/ directory.
9#
10# Maintainer: Scott Garman <scott.a.garman@intel.com>
11
12REPORT_DOC_SIMPLE="documentation_exists.txt"
13REPORT_DOC_DETAIL="documentation_exists_detail.txt"
14REPORT_MISSING_SIMPLE="documentation_missing.txt"
15REPORT_MISSING_DETAIL="documentation_missing_detail.txt"
16REPORT_BUILD_ERRORS="build_errors.txt"
17
18rm -rf $REPORT_DOC_SIMPLE $REPORT_DOC_DETAIL $REPORT_MISSING_SIMPLE $REPORT_MISSING_DETAIL
19
20BITBAKE=`which bitbake`
21if [ -z "$BITBAKE" ]; then
22 echo "Error: bitbake command not found."
23 echo "Did you forget to source the build environment script?"
24 exit 1
25fi
26
27echo "REMINDER: you need to build for MACHINE=qemux86 or you won't get useful results"
28echo "REMINDER: you need to set LICENSE_FLAGS_WHITELIST appropriately in local.conf or "
29echo " you'll get false positives. For example, LICENSE_FLAGS_WHITELIST = \"Commercial\""
30
31for pkg in `bitbake -s | awk '{ print \$1 }'`; do
32 if [[ "$pkg" == "Loading" || "$pkg" == "Loaded" ||
33 "$pkg" == "Recipe" ||
34 "$pkg" == "Parsing" || "$pkg" == "Package" ||
35 "$pkg" == "NOTE:" || "$pkg" == "WARNING:" ||
36 "$pkg" == "done." || "$pkg" == "===========" ]]
37 then
38 # Skip initial bitbake output
39 continue
40 fi
41 if [[ "$pkg" =~ -native$ || "$pkg" =~ -nativesdk$ ||
42 "$pkg" =~ -cross-canadian ]]; then
43 # Skip native/nativesdk/cross-canadian recipes
44 continue
45 fi
46 if [[ "$pkg" =~ ^meta- || "$pkg" =~ ^packagegroup- || "$pkg" =~ -image ]]; then
47 # Skip meta, task and image recipes
48 continue
49 fi
50 if [[ "$pkg" =~ ^glibc- || "$pkg" =~ ^libiconv$ ||
51 "$pkg" =~ -toolchain$ || "$pkg" =~ ^package-index$ ||
52 "$pkg" =~ ^linux- || "$pkg" =~ ^adt-installer$ ||
53 "$pkg" =~ ^eds-tools$ || "$pkg" =~ ^external-python-tarball$ ||
54 "$pkg" =~ ^qt4-embedded$ || "$pkg" =~ ^qt-mobility ]]; then
55 # Skip glibc, libiconv, -toolchain, and other recipes known
56 # to cause build conflicts or trigger false positives.
57 continue
58 fi
59
60 echo "Building package $pkg..."
61 bitbake $pkg > /dev/null
62 if [ $? -ne 0 ]; then
63 echo "There was an error building package $pkg" >> "$REPORT_MISSING_DETAIL"
64 echo "$pkg" >> $REPORT_BUILD_ERRORS
65
66 # Do not skip the remaining tests, as sometimes the
67 # exit status is 1 due to QA errors, and we can still
68 # perform the -doc checks.
69 fi
70
71 echo "$pkg built successfully, checking for a documentation package..."
72 WORKDIR=`bitbake -e $pkg | grep ^WORKDIR | awk -F '=' '{ print \$2 }' | awk -F '"' '{ print \$2 }'`
73 FIND_DOC_PKG=`find $WORKDIR/packages-split/*-doc -maxdepth 0 -type d`
74 if [ -z "$FIND_DOC_PKG" ]; then
75 # No -doc package was generated:
76 echo "No -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
77 echo "$pkg" >> $REPORT_MISSING_SIMPLE
78 continue
79 fi
80
81 FIND_DOC_FILES=`find $FIND_DOC_PKG -type f`
82 if [ -z "$FIND_DOC_FILES" ]; then
83 # No files shipped with the -doc package:
84 echo "No files shipped with the -doc package: $pkg" >> "$REPORT_MISSING_DETAIL"
85 echo "$pkg" >> $REPORT_MISSING_SIMPLE
86 continue
87 fi
88
89 echo "Documentation shipped with $pkg:" >> "$REPORT_DOC_DETAIL"
90 echo "$FIND_DOC_FILES" >> "$REPORT_DOC_DETAIL"
91 echo "" >> "$REPORT_DOC_DETAIL"
92
93 echo "$pkg" >> "$REPORT_DOC_SIMPLE"
94done
diff --git a/scripts/contrib/graph-tool b/scripts/contrib/graph-tool
new file mode 100755
index 0000000000..6dc7d337f8
--- /dev/null
+++ b/scripts/contrib/graph-tool
@@ -0,0 +1,92 @@
1#!/usr/bin/env python
2
3# Simple graph query utility
4# useful for getting answers from .dot files produced by bitbake -g
5#
6# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
7#
8# Copyright 2013 Intel Corporation
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22#
23
24import sys
25
26def get_path_networkx(dotfile, fromnode, tonode):
27 try:
28 import networkx
29 except ImportError:
30 print('ERROR: Please install the networkx python module')
31 sys.exit(1)
32
33 graph = networkx.DiGraph(networkx.read_dot(dotfile))
34
35 def node_missing(node):
36 import difflib
37 close_matches = difflib.get_close_matches(node, graph.nodes(), cutoff=0.7)
38 if close_matches:
39 print('ERROR: no node "%s" in graph. Close matches:\n %s' % (node, '\n '.join(close_matches)))
40 sys.exit(1)
41
42 if not fromnode in graph:
43 node_missing(fromnode)
44 if not tonode in graph:
45 node_missing(tonode)
46 return networkx.all_simple_paths(graph, source=fromnode, target=tonode)
47
48
49def find_paths(args, usage):
50 if len(args) < 3:
51 usage()
52 sys.exit(1)
53
54 fromnode = args[1]
55 tonode = args[2]
56 paths = list(get_path_networkx(args[0], fromnode, tonode))
57 if paths:
58 for path in paths:
59 print ' -> '.join(path)
60 else:
61 print("ERROR: no path from %s to %s in graph" % (fromnode, tonode))
62 sys.exit(1)
63
64def main():
65 import optparse
66 parser = optparse.OptionParser(
67 usage = '''%prog [options] <command> <arguments>
68
69Available commands:
70 find-paths <dotfile> <from> <to>
71 Find all of the paths between two nodes in a dot graph''')
72
73 #parser.add_option("-d", "--debug",
74 # help = "Report all SRCREV values, not just ones where AUTOREV has been used",
75 # action="store_true", dest="debug", default=False)
76
77 options, args = parser.parse_args(sys.argv)
78 args = args[1:]
79
80 if len(args) < 1:
81 parser.print_help()
82 sys.exit(1)
83
84 if args[0] == "find-paths":
85 find_paths(args[1:], parser.print_help)
86 else:
87 parser.print_help()
88 sys.exit(1)
89
90
91if __name__ == "__main__":
92 main()
diff --git a/scripts/contrib/list-packageconfig-flags.py b/scripts/contrib/list-packageconfig-flags.py
new file mode 100755
index 0000000000..371033a3d8
--- /dev/null
+++ b/scripts/contrib/list-packageconfig-flags.py
@@ -0,0 +1,209 @@
1#!/usr/bin/env python
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software Foundation.
15#
16# Copyright (C) 2013 Wind River Systems, Inc.
17#
18# - list available pkgs which have PACKAGECONFIG flags
19# - list available PACKAGECONFIG flags and all affected pkgs
20# - list all pkgs and PACKAGECONFIG information
21
22import sys
23import getopt
24import os
25
26def search_bitbakepath():
27 bitbakepath = ""
28
29 # Search path to bitbake lib dir in order to load bb modules
30 if os.path.exists(os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib/bb')):
31 bitbakepath = os.path.join(os.path.dirname(sys.argv[0]), '../../bitbake/lib')
32 bitbakepath = os.path.abspath(bitbakepath)
33 else:
34 # Look for bitbake/bin dir in PATH
35 for pth in os.environ['PATH'].split(':'):
36 if os.path.exists(os.path.join(pth, '../lib/bb')):
37 bitbakepath = os.path.abspath(os.path.join(pth, '../lib'))
38 break
39 if not bitbakepath:
40 sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n")
41 sys.exit(1)
42 return bitbakepath
43
44# For importing the following modules
45sys.path.insert(0, search_bitbakepath())
46import bb.cache
47import bb.cooker
48import bb.providers
49import bb.tinfoil
50
51usage_body = ''' list available pkgs which have PACKAGECONFIG flags
52
53OPTION:
54 -h, --help display this help and exit
55 -f, --flag list available PACKAGECONFIG flags and all affected pkgs
56 -a, --all list all pkgs and PACKAGECONFIG information
57 -p, --prefer list pkgs with preferred version
58
59EXAMPLE:
60list-packageconfig-flags.py
61list-packageconfig-flags.py -f
62list-packageconfig-flags.py -a
63list-packageconfig-flags.py -p
64list-packageconfig-flags.py -f -p
65list-packageconfig-flags.py -a -p
66'''
67
68def usage():
69 print 'Usage: %s [-f|-a] [-p]' % os.path.basename(sys.argv[0])
70 print usage_body
71
72def get_fnlist(bbhandler, pkg_pn, preferred):
73 ''' Get all recipe file names '''
74 if preferred:
75 (latest_versions, preferred_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecache, pkg_pn)
76
77 fn_list = []
78 for pn in sorted(pkg_pn):
79 if preferred:
80 fn_list.append(preferred_versions[pn][1])
81 else:
82 fn_list.extend(pkg_pn[pn])
83
84 return fn_list
85
86def get_recipesdata(bbhandler, preferred):
87 ''' Get data of all available recipes which have PACKAGECONFIG flags '''
88 pkg_pn = bbhandler.cooker.recipecache.pkg_pn
89
90 data_dict = {}
91 for fn in get_fnlist(bbhandler, pkg_pn, preferred):
92 data = bb.cache.Cache.loadDataFull(fn, bbhandler.cooker.collection.get_file_appends(fn), bbhandler.config_data)
93 if data.getVarFlags("PACKAGECONFIG"):
94 data_dict[fn] = data
95
96 return data_dict
97
98def collect_pkgs(data_dict):
99 ''' Collect available pkgs in which have PACKAGECONFIG flags '''
100 # pkg_dict = {'pkg1': ['flag1', 'flag2',...]}
101 pkg_dict = {}
102 for fn in data_dict:
103 pkgconfigflags = data_dict[fn].getVarFlags("PACKAGECONFIG")
104 pkgname = data_dict[fn].getVar("P", True)
105 pkg_dict[pkgname] = sorted(pkgconfigflags.keys())
106
107 return pkg_dict
108
109def collect_flags(pkg_dict):
110 ''' Collect available PACKAGECONFIG flags and all affected pkgs '''
111 # flag_dict = {'flag': ['pkg1', 'pkg2',...]}
112 flag_dict = {}
113 for pkgname, flaglist in pkg_dict.iteritems():
114 for flag in flaglist:
115 if flag == "defaultval":
116 continue
117
118 if flag in flag_dict:
119 flag_dict[flag].append(pkgname)
120 else:
121 flag_dict[flag] = [pkgname]
122
123 return flag_dict
124
125def display_pkgs(pkg_dict):
126 ''' Display available pkgs which have PACKAGECONFIG flags '''
127 pkgname_len = len("PACKAGE NAME") + 1
128 for pkgname in pkg_dict:
129 if pkgname_len < len(pkgname):
130 pkgname_len = len(pkgname)
131 pkgname_len += 1
132
133 header = '%-*s%s' % (pkgname_len, str("PACKAGE NAME"), str("PACKAGECONFIG FLAGS"))
134 print header
135 print str("").ljust(len(header), '=')
136 for pkgname in sorted(pkg_dict):
137 print('%-*s%s' % (pkgname_len, pkgname, ' '.join(pkg_dict[pkgname])))
138
139
140def display_flags(flag_dict):
141 ''' Display available PACKAGECONFIG flags and all affected pkgs '''
142 flag_len = len("PACKAGECONFIG FLAG") + 5
143
144 header = '%-*s%s' % (flag_len, str("PACKAGECONFIG FLAG"), str("PACKAGE NAMES"))
145 print header
146 print str("").ljust(len(header), '=')
147
148 for flag in sorted(flag_dict):
149 print('%-*s%s' % (flag_len, flag, ' '.join(sorted(flag_dict[flag]))))
150
151def display_all(data_dict):
152 ''' Display all pkgs and PACKAGECONFIG information '''
153 print str("").ljust(50, '=')
154 for fn in data_dict:
155 print('%s' % data_dict[fn].getVar("P", True))
156 print fn
157 packageconfig = data_dict[fn].getVar("PACKAGECONFIG", True) or ''
158 if packageconfig.strip() == '':
159 packageconfig = 'None'
160 print('PACKAGECONFIG %s' % packageconfig)
161
162 for flag,flag_val in data_dict[fn].getVarFlags("PACKAGECONFIG").iteritems():
163 if flag == "defaultval":
164 continue
165 print('PACKAGECONFIG[%s] %s' % (flag, flag_val))
166 print ''
167
168def main():
169 listtype = 'pkgs'
170 preferred = False
171 pkg_dict = {}
172 flag_dict = {}
173
174 # Collect and validate input
175 try:
176 opts, args = getopt.getopt(sys.argv[1:], "hfap", ["help", "flag", "all", "prefer"])
177 except getopt.GetoptError, err:
178 print >> sys.stderr,'%s' % str(err)
179 usage()
180 sys.exit(2)
181 for opt, value in opts:
182 if opt in ('-h', '--help'):
183 usage()
184 sys.exit(0)
185 elif opt in ('-f', '--flag'):
186 listtype = 'flags'
187 elif opt in ('-a', '--all'):
188 listtype = 'all'
189 elif opt in ('-p', '--prefer'):
190 preferred = True
191 else:
192 assert False, "unhandled option"
193
194 bbhandler = bb.tinfoil.Tinfoil()
195 bbhandler.prepare()
196 data_dict = get_recipesdata(bbhandler, preferred)
197
198 if listtype == 'flags':
199 pkg_dict = collect_pkgs(data_dict)
200 flag_dict = collect_flags(pkg_dict)
201 display_flags(flag_dict)
202 elif listtype == 'pkgs':
203 pkg_dict = collect_pkgs(data_dict)
204 display_pkgs(pkg_dict)
205 elif listtype == 'all':
206 display_all(data_dict)
207
208if __name__ == "__main__":
209 main()
diff --git a/scripts/contrib/mkefidisk.sh b/scripts/contrib/mkefidisk.sh
new file mode 100755
index 0000000000..c86849d395
--- /dev/null
+++ b/scripts/contrib/mkefidisk.sh
@@ -0,0 +1,286 @@
1#!/bin/sh
2#
3# Copyright (c) 2012, Intel Corporation.
4# All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14# the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19#
20
21LANG=C
22
23#
24# Defaults
25#
26# 20 Mb for the boot partition
27BOOT_SIZE=20
28# 5% for swap
29SWAP_RATIO=5
30
31usage() {
32 echo "Usage: $(basename $0) DEVICE HDDIMG TARGET_DEVICE"
33 echo " DEVICE: The device to write the image to, e.g. /dev/sdh"
34 echo " HDDIMG: The hddimg file to generate the efi disk from"
35 echo " TARGET_DEVICE: The device the target will boot from, e.g. /dev/mmcblk0"
36}
37
38image_details() {
39 IMG=$1
40 echo "Image details"
41 echo "============="
42 echo " image: $(stat --printf '%N\n' $IMG)"
43 echo " size: $(stat -L --printf '%s bytes\n' $IMG)"
44 echo " modified: $(stat -L --printf '%y\n' $IMG)"
45 echo " type: $(file -L -b $IMG)"
46 echo ""
47}
48
49device_details() {
50 DEV=$1
51 BLOCK_SIZE=512
52
53 echo "Device details"
54 echo "=============="
55 echo " device: $DEVICE"
56 if [ -f "/sys/class/block/$DEV/device/vendor" ]; then
57 echo " vendor: $(cat /sys/class/block/$DEV/device/vendor)"
58 else
59 echo " vendor: UNKOWN"
60 fi
61 if [ -f "/sys/class/block/$DEV/device/model" ]; then
62 echo " model: $(cat /sys/class/block/$DEV/device/model)"
63 else
64 echo " model: UNKNOWN"
65 fi
66 if [ -f "/sys/class/block/$DEV/size" ]; then
67 echo " size: $(($(cat /sys/class/block/$DEV/size) * $BLOCK_SIZE)) bytes"
68 else
69 echo " size: UNKNOWN"
70 fi
71 echo ""
72}
73
74unmount_device() {
75 grep -q $DEVICE /proc/mounts
76 if [ $? -eq 0 ]; then
77 echo -n "$DEVICE listed in /proc/mounts, attempting to unmount..."
78 umount $DEVICE* 2>/dev/null
79 grep -q $DEVICE /proc/mounts
80 if [ $? -eq 0 ]; then
81 echo "FAILED"
82 exit 1
83 fi
84 echo "OK"
85 fi
86}
87
88
89#
90# Parse and validate arguments
91#
92if [ $# -ne 3 ]; then
93 usage
94 exit 1
95fi
96
97DEVICE=$1
98HDDIMG=$2
99TARGET_DEVICE=$3
100
101if [ ! -w "$DEVICE" ]; then
102 echo "ERROR: Device $DEVICE does not exist or is not writable"
103 usage
104 exit 1
105fi
106
107if [ ! -e "$HDDIMG" ]; then
108 echo "ERROR: HDDIMG $HDDIMG does not exist"
109 usage
110 exit 1
111fi
112
113
114#
115# Check if any $DEVICE partitions are mounted
116#
117unmount_device
118
119
120#
121# Confirm device with user
122#
123image_details $HDDIMG
124device_details $(basename $DEVICE)
125echo -n "Prepare EFI image on $DEVICE [y/N]? "
126read RESPONSE
127if [ "$RESPONSE" != "y" ]; then
128 echo "Image creation aborted"
129 exit 0
130fi
131
132
133#
134# Partition $DEVICE
135#
136DEVICE_SIZE=$(parted $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
137# If the device size is not reported there may not be a valid label
138if [ "$DEVICE_SIZE" = "" ] ; then
139 parted $DEVICE mklabel msdos
140 DEVICE_SIZE=$(parted $DEVICE unit mb print | grep ^Disk | cut -d" " -f 3 | sed -e "s/MB//")
141fi
142SWAP_SIZE=$((DEVICE_SIZE*SWAP_RATIO/100))
143ROOTFS_SIZE=$((DEVICE_SIZE-BOOT_SIZE-SWAP_SIZE))
144ROOTFS_START=$((BOOT_SIZE))
145ROOTFS_END=$((ROOTFS_START+ROOTFS_SIZE))
146SWAP_START=$((ROOTFS_END))
147
148# MMC devices use a partition prefix character 'p'
149PART_PREFIX=""
150if [ ! "${DEVICE#/dev/mmcblk}" = "${DEVICE}" ] || [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
151 PART_PREFIX="p"
152fi
153BOOTFS=$DEVICE${PART_PREFIX}1
154ROOTFS=$DEVICE${PART_PREFIX}2
155SWAP=$DEVICE${PART_PREFIX}3
156
157TARGET_PART_PREFIX=""
158if [ ! "${TARGET_DEVICE#/dev/mmcblk}" = "${TARGET_DEVICE}" ]; then
159 TARGET_PART_PREFIX="p"
160fi
161TARGET_ROOTFS=$TARGET_DEVICE${TARGET_PART_PREFIX}2
162TARGET_SWAP=$TARGET_DEVICE${TARGET_PART_PREFIX}3
163
164echo "*****************"
165echo "Boot partition size: $BOOT_SIZE MB ($BOOTFS)"
166echo "ROOTFS partition size: $ROOTFS_SIZE MB ($ROOTFS)"
167echo "Swap partition size: $SWAP_SIZE MB ($SWAP)"
168echo "*****************"
169
170echo "Deleting partition table on $DEVICE ..."
171dd if=/dev/zero of=$DEVICE bs=512 count=2
172
173# Use MSDOS by default as GPT cannot be reliably distributed in disk image form
174# as it requires the backup table to be on the last block of the device, which
175# of course varies from device to device.
176echo "Creating new partition table (MSDOS) on $DEVICE ..."
177parted $DEVICE mklabel msdos
178
179echo "Creating boot partition on $BOOTFS"
180parted $DEVICE mkpart primary 0% $BOOT_SIZE
181
182echo "Enabling boot flag on $BOOTFS"
183parted $DEVICE set 1 boot on
184
185echo "Creating ROOTFS partition on $ROOTFS"
186parted $DEVICE mkpart primary $ROOTFS_START $ROOTFS_END
187
188echo "Creating swap partition on $SWAP"
189parted $DEVICE mkpart primary $SWAP_START 100%
190
191parted $DEVICE print
192
193
194#
195# Check if any $DEVICE partitions are mounted after partitioning
196#
197unmount_device
198
199
200#
201# Format $DEVICE partitions
202#
203echo ""
204echo "Formatting $BOOTFS as vfat..."
205if [ ! "${DEVICE#/dev/loop}" = "${DEVICE}" ]; then
206 mkfs.vfat -I $BOOTFS -n "efi"
207else
208 mkfs.vfat $BOOTFS -n "efi"
209
210fi
211
212echo "Formatting $ROOTFS as ext3..."
213mkfs.ext3 $ROOTFS -L "root"
214
215echo "Formatting swap partition...($SWAP)"
216mkswap $SWAP
217
218
219#
220# Installing to $DEVICE
221#
222echo ""
223echo "Mounting images and device in preparation for installation..."
224TMPDIR=$(mktemp -d mkefidisk-XXX)
225if [ $? -ne 0 ]; then
226 echo "ERROR: Failed to create temporary mounting directory."
227 exit 1
228fi
229HDDIMG_MNT=$TMPDIR/hddimg
230HDDIMG_ROOTFS_MNT=$TMPDIR/hddimg_rootfs
231ROOTFS_MNT=$TMPDIR/rootfs
232BOOTFS_MNT=$TMPDIR/bootfs
233mkdir $HDDIMG_MNT
234mkdir $HDDIMG_ROOTFS_MNT
235mkdir $ROOTFS_MNT
236mkdir $BOOTFS_MNT
237
238mount -o loop $HDDIMG $HDDIMG_MNT
239mount -o loop $HDDIMG_MNT/rootfs.img $HDDIMG_ROOTFS_MNT
240mount $ROOTFS $ROOTFS_MNT
241mount $BOOTFS $BOOTFS_MNT
242
243echo "Copying ROOTFS files..."
244cp -a $HDDIMG_ROOTFS_MNT/* $ROOTFS_MNT
245
246echo "$TARGET_SWAP swap swap defaults 0 0" >> $ROOTFS_MNT/etc/fstab
247
248# We dont want udev to mount our root device while we're booting...
249if [ -d $ROOTFS_MNT/etc/udev/ ] ; then
250 echo "$TARGET_DEVICE" >> $ROOTFS_MNT/etc/udev/mount.blacklist
251fi
252
253umount $ROOTFS_MNT
254umount $HDDIMG_ROOTFS_MNT
255
256echo "Preparing boot partition..."
257EFIDIR="$BOOTFS_MNT/EFI/BOOT"
258mkdir -p $EFIDIR
259GRUBCFG="$EFIDIR/grub.cfg"
260
261cp $HDDIMG_MNT/vmlinuz $BOOTFS_MNT
262# Copy the efi loader and config (booti*.efi and grub.cfg)
263cp $HDDIMG_MNT/EFI/BOOT/* $EFIDIR
264
265# Update grub config for the installed image
266# Delete the install entry
267sed -i "/menuentry 'install'/,/^}/d" $GRUBCFG
268# Delete the initrd lines
269sed -i "/initrd /d" $GRUBCFG
270# Delete any LABEL= strings
271sed -i "s/ LABEL=[^ ]*/ /" $GRUBCFG
272# Remove any existing root= kernel parameters and:
273# o Add a root= parameter with the target rootfs
274# o Specify ro so fsck can be run during boot
275# o Specify rootwait in case the target media is an asyncronous block device
276# such as MMC or USB disks
277# o Specify "quiet" to minimize boot time when using slow serial consoles
278sed -i "s@ root=[^ ]*@ @" $GRUBCFG
279sed -i "s@vmlinuz @vmlinuz root=$TARGET_ROOTFS ro rootwait quiet @" $GRUBCFG
280
281umount $BOOTFS_MNT
282umount $HDDIMG_MNT
283rm -rf $TMPDIR
284sync
285
286echo "Installation complete."
diff --git a/scripts/contrib/python/generate-manifest-2.7.py b/scripts/contrib/python/generate-manifest-2.7.py
new file mode 100755
index 0000000000..4356ad0ddd
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-2.7.py
@@ -0,0 +1,388 @@
1#!/usr/bin/env python
2
3# generate Python Manifest for the OpenEmbedded build system
4# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
5# (C) 2007 Jeremy Laine
6# licensed under MIT, see COPYING.MIT
7#
8# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
9# * Updated to no longer generate special -dbg package, instead use the
10# single system -dbg
11# * Update version with ".1" to indicate this change
12
13import os
14import sys
15import time
16
17VERSION = "2.7.2"
18
19__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
20__version__ = "20110222.2"
21
22class MakefileMaker:
23
24 def __init__( self, outfile ):
25 """initialize"""
26 self.packages = {}
27 self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
28 self.output = outfile
29 self.out( """
30# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
31# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
32# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
33""" % ( sys.argv[0], __version__ ) )
34
35 #
36 # helper functions
37 #
38
39 def out( self, data ):
40 """print a line to the output file"""
41 self.output.write( "%s\n" % data )
42
43 def setPrefix( self, targetPrefix ):
44 """set a file prefix for addPackage files"""
45 self.targetPrefix = targetPrefix
46
47 def doProlog( self ):
48 self.out( """ """ )
49 self.out( "" )
50
51 def addPackage( self, name, description, dependencies, filenames ):
52 """add a package to the Makefile"""
53 if type( filenames ) == type( "" ):
54 filenames = filenames.split()
55 fullFilenames = []
56 for filename in filenames:
57 if filename[0] != "$":
58 fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
59 else:
60 fullFilenames.append( filename )
61 self.packages[name] = description, dependencies, fullFilenames
62
63 def doBody( self ):
64 """generate body of Makefile"""
65
66 global VERSION
67
68 #
69 # generate provides line
70 #
71
72 provideLine = 'PROVIDES+="'
73 for name in sorted(self.packages):
74 provideLine += "%s " % name
75 provideLine += '"'
76
77 self.out( provideLine )
78 self.out( "" )
79
80 #
81 # generate package line
82 #
83
84 packageLine = 'PACKAGES="${PN}-dbg '
85 for name in sorted(self.packages):
86 if name.startswith("${PN}-distutils"):
87 if name == "${PN}-distutils":
88 packageLine += "%s-staticdev %s " % (name, name)
89 elif name != '${PN}-dbg':
90 packageLine += "%s " % name
91 packageLine += '${PN}-modules"'
92
93 self.out( packageLine )
94 self.out( "" )
95
96 #
97 # generate package variables
98 #
99
100 for name, data in sorted(self.packages.iteritems()):
101 desc, deps, files = data
102
103 #
104 # write out the description, revision and dependencies
105 #
106 self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
107 self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
108
109 line = 'FILES_%s="' % name
110
111 #
112 # check which directories to make in the temporary directory
113 #
114
115 dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
116 for target in files:
117 dirset[os.path.dirname( target )] = True
118
119 #
120 # generate which files to copy for the target (-dfR because whole directories are also allowed)
121 #
122
123 for target in files:
124 line += "%s " % target
125
126 line += '"'
127 self.out( line )
128 self.out( "" )
129
130 self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
131 line = 'RDEPENDS_${PN}-modules="'
132
133 for name, data in sorted(self.packages.iteritems()):
134 if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
135 line += "%s " % name
136
137 self.out( "%s \"" % line )
138 self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
139
140 def doEpilog( self ):
141 self.out( """""" )
142 self.out( "" )
143
144 def make( self ):
145 self.doProlog()
146 self.doBody()
147 self.doEpilog()
148
149if __name__ == "__main__":
150
151 if len( sys.argv ) > 1:
152 try:
153 os.unlink(sys.argv[1])
154 except Exception:
155 sys.exc_clear()
156 outfile = file( sys.argv[1], "w" )
157 else:
158 outfile = sys.stdout
159
160 m = MakefileMaker( outfile )
161
162 # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
163 # Parameters: revision, name, description, dependencies, filenames
164 #
165
166 m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re",
167 "__future__.* _abcoll.* abc.* copy.* copy_reg.* ConfigParser.* " +
168 "genericpath.* getopt.* linecache.* new.* " +
169 "os.* posixpath.* struct.* " +
170 "warnings.* site.* stat.* " +
171 "UserDict.* UserList.* UserString.* " +
172 "lib-dynload/binascii.so lib-dynload/_struct.so lib-dynload/time.so " +
173 "lib-dynload/xreadlines.so types.* platform.* ${bindir}/python* " +
174 "_weakrefset.* sysconfig.* config/Makefile " +
175 "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h " +
176 "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
177
178 m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
179 "${includedir} " +
180 "${libdir}/lib*${SOLIBSDEV} " +
181 "${libdir}/*.la " +
182 "${libdir}/*.a " +
183 "${libdir}/*.o " +
184 "${libdir}/pkgconfig " +
185 "${base_libdir}/*.a " +
186 "${base_libdir}/*.o " +
187 "${datadir}/aclocal " +
188 "${datadir}/pkgconfig " )
189
190 m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
191 "${bindir}/2to3 lib2to3" ) # package
192
193 m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
194 "${bindir}/idle idlelib" ) # package
195
196 m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
197 "${bindir}/pydoc pydoc.* pydoc_data" )
198
199 m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
200 "${bindir}/smtpd.* smtpd.*" )
201
202 m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
203 "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.so lib-dynload/audioop.so audiodev.* sunaudio.* sunau.* toaiff.*" )
204
205 m.addPackage( "${PN}-bsddb", "Python bindings for the Berkeley Database", "${PN}-core",
206 "bsddb lib-dynload/_bsddb.so" ) # package
207
208 m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
209 "codecs.* encodings gettext.* locale.* lib-dynload/_locale.so lib-dynload/_codecs* lib-dynload/_multibytecodec.so lib-dynload/unicodedata.so stringprep.* xdrlib.*" )
210
211 m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
212 "py_compile.* compileall.*" )
213
214 m.addPackage( "${PN}-compiler", "Python compiler support", "${PN}-core",
215 "compiler" ) # package
216
217 m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-zlib",
218 "gzip.* zipfile.* tarfile.* lib-dynload/bz2.so" )
219
220 m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
221 "hashlib.* md5.* sha.* lib-dynload/crypt.so lib-dynload/_hashlib.so lib-dynload/_sha256.so lib-dynload/_sha512.so" )
222
223 m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
224 "lib-dynload/_csv.so csv.* optparse.* textwrap.*" )
225
226 m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
227 "curses lib-dynload/_curses.so lib-dynload/_curses_panel.so" ) # directory + low level module
228
229 m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
230 "ctypes lib-dynload/_ctypes.so lib-dynload/_ctypes_test.so" ) # directory + low level module
231
232 m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
233 "_strptime.* calendar.* lib-dynload/datetime.so" )
234
235 m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
236 "anydbm.* dumbdbm.* whichdb.* " )
237
238 m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
239 "bdb.* pdb.*" )
240
241 m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
242 "difflib.*" )
243
244 m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
245 "config/lib*.a" ) # package
246
247 m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core",
248 "config distutils" ) # package
249
250 m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
251 "doctest.*" )
252
253 # FIXME consider adding to some higher level package
254 m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
255 "lib-dynload/_elementtree.so" )
256
257 m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
258 "imaplib.* email" ) # package
259
260 m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
261 "lib-dynload/fcntl.so" )
262
263 m.addPackage( "${PN}-hotshot", "Python hotshot performance profiler", "${PN}-core",
264 "hotshot lib-dynload/_hotshot.so" )
265
266 m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
267 "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
268
269 m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
270 "lib-dynload/gdbm.so" )
271
272 m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
273 "colorsys.* imghdr.* lib-dynload/imageop.so lib-dynload/rgbimg.so" )
274
275 m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math ${PN}-textutils",
276 "lib-dynload/_socket.so lib-dynload/_io.so lib-dynload/_ssl.so lib-dynload/select.so lib-dynload/termios.so lib-dynload/cStringIO.so " +
277 "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
278
279 m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re",
280 "json lib-dynload/_json.so" ) # package
281
282 m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
283 "lib-dynload/_bisect.so lib-dynload/_collections.so lib-dynload/_heapq.so lib-dynload/_weakref.so lib-dynload/_functools.so " +
284 "lib-dynload/array.so lib-dynload/itertools.so lib-dynload/operator.so lib-dynload/parser.so " +
285 "atexit.* bisect.* code.* codeop.* collections.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
286 "tokenize.* traceback.* weakref.*" )
287
288 m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
289 "logging" ) # package
290
291 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
292 "mailbox.*" )
293
294 m.addPackage( "${PN}-math", "Python math support", "${PN}-core ${PN}-crypt",
295 "lib-dynload/cmath.so lib-dynload/math.so lib-dynload/_random.so random.* sets.*" )
296
297 m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
298 "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
299
300 m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
301 "lib-dynload/mmap.so " )
302
303 m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
304 "lib-dynload/_multiprocessing.so multiprocessing" ) # package
305
306 m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
307 "*Cookie*.* " +
308 "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.* uuid.* rfc822.* mimetools.*" )
309
310 m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient",
311 "cgi.* *HTTPServer.* SocketServer.*" )
312
313 m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
314 "decimal.* numbers.*" )
315
316 m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
317 "pickle.* shelve.* lib-dynload/cPickle.so pickletools.*" )
318
319 m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
320 "pkgutil.*")
321
322 m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
323 "pprint.*" )
324
325 m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
326 "profile.* pstats.* cProfile.* lib-dynload/_lsprof.so" )
327
328 m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
329 "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
330
331 m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
332 "lib-dynload/readline.so rlcompleter.*" )
333
334 m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
335 "lib-dynload/resource.so" )
336
337 m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
338 "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
339
340 m.addPackage( "${PN}-robotparser", "Python robots.txt parser", "${PN}-core ${PN}-netclient",
341 "robotparser.*")
342
343 m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
344 "subprocess.*" )
345
346 m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading ${PN}-zlib",
347 "lib-dynload/_sqlite3.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
348
349 m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
350 "sqlite3/test" )
351
352 m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
353 "lib-dynload/strop.so string.* stringold.*" )
354
355 m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
356 "lib-dynload/syslog.so" )
357
358 m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
359 "pty.* tty.*" )
360
361 m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
362 "test" ) # package
363
364 m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
365 "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
366
367 m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
368 "lib-dynload/_tkinter.so lib-tk" ) # package
369
370 m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
371 "unittest/" )
372
373 m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
374 "lib-dynload/nis.so lib-dynload/grp.so lib-dynload/pwd.so getpass.*" )
375
376 m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-elementtree ${PN}-re",
377 "lib-dynload/pyexpat.so xml xmllib.*" ) # package
378
379 m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
380 "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.*" )
381
382 m.addPackage( "${PN}-zlib", "Python zlib compression support", "${PN}-core",
383 "lib-dynload/zlib.so" )
384
385 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
386 "mailbox.*" )
387
388 m.make()
diff --git a/scripts/contrib/python/generate-manifest-3.3.py b/scripts/contrib/python/generate-manifest-3.3.py
new file mode 100755
index 0000000000..1586c46868
--- /dev/null
+++ b/scripts/contrib/python/generate-manifest-3.3.py
@@ -0,0 +1,380 @@
1#!/usr/bin/env python
2
3# generate Python Manifest for the OpenEmbedded build system
4# (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
5# (C) 2007 Jeremy Laine
6# licensed under MIT, see COPYING.MIT
7#
8# June 22, 2011 -- Mark Hatle <mark.hatle@windriver.com>
9# * Updated to no longer generate special -dbg package, instead use the
10# single system -dbg
11# * Update version with ".1" to indicate this change
12#
13# 2014 Khem Raj <raj.khem@gmail.com>
14# Added python3 support
15#
16import os
17import sys
18import time
19
20VERSION = "3.3.3"
21
22__author__ = "Michael 'Mickey' Lauer <mlauer@vanille-media.de>"
23__version__ = "20140131"
24
25class MakefileMaker:
26
27 def __init__( self, outfile ):
28 """initialize"""
29 self.packages = {}
30 self.targetPrefix = "${libdir}/python%s/" % VERSION[:3]
31 self.output = outfile
32 self.out( """
33# WARNING: This file is AUTO GENERATED: Manual edits will be lost next time I regenerate the file.
34# Generator: '%s' Version %s (C) 2002-2010 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
35# Visit the Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
36""" % ( sys.argv[0], __version__ ) )
37
38 #
39 # helper functions
40 #
41
42 def out( self, data ):
43 """print a line to the output file"""
44 self.output.write( "%s\n" % data )
45
46 def setPrefix( self, targetPrefix ):
47 """set a file prefix for addPackage files"""
48 self.targetPrefix = targetPrefix
49
50 def doProlog( self ):
51 self.out( """ """ )
52 self.out( "" )
53
54 def addPackage( self, name, description, dependencies, filenames ):
55 """add a package to the Makefile"""
56 if type( filenames ) == type( "" ):
57 filenames = filenames.split()
58 fullFilenames = []
59 for filename in filenames:
60 if filename[0] != "$":
61 fullFilenames.append( "%s%s" % ( self.targetPrefix, filename ) )
62 else:
63 fullFilenames.append( filename )
64 self.packages[name] = description, dependencies, fullFilenames
65
66 def doBody( self ):
67 """generate body of Makefile"""
68
69 global VERSION
70
71 #
72 # generate provides line
73 #
74
75 provideLine = 'PROVIDES+="'
76 for name in sorted(self.packages):
77 provideLine += "%s " % name
78 provideLine += '"'
79
80 self.out( provideLine )
81 self.out( "" )
82
83 #
84 # generate package line
85 #
86
87 packageLine = 'PACKAGES="${PN}-dbg '
88 for name in sorted(self.packages):
89 if name.startswith("${PN}-distutils"):
90 if name == "${PN}-distutils":
91 packageLine += "%s-staticdev %s " % (name, name)
92 elif name != '${PN}-dbg':
93 packageLine += "%s " % name
94 packageLine += '${PN}-modules"'
95
96 self.out( packageLine )
97 self.out( "" )
98
99 #
100 # generate package variables
101 #
102
103 for name, data in sorted(self.packages.iteritems()):
104 desc, deps, files = data
105
106 #
107 # write out the description, revision and dependencies
108 #
109 self.out( 'SUMMARY_%s="%s"' % ( name, desc ) )
110 self.out( 'RDEPENDS_%s="%s"' % ( name, deps ) )
111
112 line = 'FILES_%s="' % name
113
114 #
115 # check which directories to make in the temporary directory
116 #
117
118 dirset = {} # if python had a set-datatype this would be sufficient. for now, we're using a dict instead.
119 for target in files:
120 dirset[os.path.dirname( target )] = True
121
122 #
123 # generate which files to copy for the target (-dfR because whole directories are also allowed)
124 #
125
126 for target in files:
127 line += "%s " % target
128
129 line += '"'
130 self.out( line )
131 self.out( "" )
132
133 self.out( 'SUMMARY_${PN}-modules="All Python modules"' )
134 line = 'RDEPENDS_${PN}-modules="'
135
136 for name, data in sorted(self.packages.iteritems()):
137 if name not in ['${PN}-dev', '${PN}-distutils-staticdev']:
138 line += "%s " % name
139
140 self.out( "%s \"" % line )
141 self.out( 'ALLOW_EMPTY_${PN}-modules = "1"' )
142
143 def doEpilog( self ):
144 self.out( """""" )
145 self.out( "" )
146
147 def make( self ):
148 self.doProlog()
149 self.doBody()
150 self.doEpilog()
151
152if __name__ == "__main__":
153
154 if len( sys.argv ) > 1:
155 try:
156 os.unlink(sys.argv[1])
157 except Exception:
158 sys.exc_clear()
159 outfile = file( sys.argv[1], "w" )
160 else:
161 outfile = sys.stdout
162
163 m = MakefileMaker( outfile )
164
165 # Add packages here. Only specify dlopen-style library dependencies here, no ldd-style dependencies!
166 # Parameters: revision, name, description, dependencies, filenames
167 #
168
169 m.addPackage( "${PN}-core", "Python interpreter and core modules", "${PN}-lang ${PN}-re",
170 "__future__.* _abcoll.* abc.* copy.* copy_reg.* ConfigParser.* " +
171 "genericpath.* getopt.* linecache.* new.* " +
172 "os.* posixpath.* struct.* " +
173 "warnings.* site.* stat.* " +
174 "UserDict.* UserList.* UserString.* " +
175 "lib-dynload/binascii.*.so lib-dynload/_struct.*.so lib-dynload/time.*.so " +
176 "lib-dynload/xreadlines.*.so types.* platform.* ${bindir}/python* " +
177 "_weakrefset.* sysconfig.* config/Makefile " +
178 "${includedir}/python${PYTHON_MAJMIN}/pyconfig*.h " +
179 "${libdir}/python${PYTHON_MAJMIN}/collections " +
180 "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py ")
181
182 m.addPackage( "${PN}-dev", "Python development package", "${PN}-core",
183 "${includedir} " +
184 "${libdir}/lib*${SOLIBSDEV} " +
185 "${libdir}/*.la " +
186 "${libdir}/*.a " +
187 "${libdir}/*.o " +
188 "${libdir}/pkgconfig " +
189 "${base_libdir}/*.a " +
190 "${base_libdir}/*.o " +
191 "${datadir}/aclocal " +
192 "${datadir}/pkgconfig " )
193
194 m.addPackage( "${PN}-2to3", "Python automated Python 2 to 3 code translator", "${PN}-core",
195 "${bindir}/2to3 lib2to3" ) # package
196
197 m.addPackage( "${PN}-idle", "Python Integrated Development Environment", "${PN}-core ${PN}-tkinter",
198 "${bindir}/idle idlelib" ) # package
199
200 m.addPackage( "${PN}-pydoc", "Python interactive help support", "${PN}-core ${PN}-lang ${PN}-stringold ${PN}-re",
201 "${bindir}/pydoc pydoc.* pydoc_data" )
202
203 m.addPackage( "${PN}-smtpd", "Python Simple Mail Transport Daemon", "${PN}-core ${PN}-netserver ${PN}-email ${PN}-mime",
204 "${bindir}/smtpd.* smtpd.*" )
205
206 m.addPackage( "${PN}-audio", "Python Audio Handling", "${PN}-core",
207 "wave.* chunk.* sndhdr.* lib-dynload/ossaudiodev.*.so lib-dynload/audioop.*.so audiodev.* sunaudio.* sunau.* toaiff.*" )
208
209 m.addPackage( "${PN}-codecs", "Python codecs, encodings & i18n support", "${PN}-core ${PN}-lang",
210 "codecs.* encodings gettext.* locale.* lib-dynload/_locale.*.so lib-dynload/_codecs* lib-dynload/_multibytecodec.*.so lib-dynload/unicodedata.*.so stringprep.* xdrlib.*" )
211
212 m.addPackage( "${PN}-compile", "Python bytecode compilation support", "${PN}-core",
213 "py_compile.* compileall.*" )
214
215 m.addPackage( "${PN}-compression", "Python high-level compression support", "${PN}-core ${PN}-codecs",
216 "gzip.* zipfile.* tarfile.* lib-dynload/bz2.*.so" )
217
218 m.addPackage( "${PN}-crypt", "Python basic cryptographic and hashing support", "${PN}-core",
219 "hashlib.* md5.* sha.* lib-dynload/crypt.*.so lib-dynload/_hashlib.*.so lib-dynload/_sha256.*.so lib-dynload/_sha512.*.so" )
220
221 m.addPackage( "${PN}-textutils", "Python option parsing, text wrapping and CSV support", "${PN}-core ${PN}-io ${PN}-re ${PN}-stringold",
222 "lib-dynload/_csv.*.so csv.* optparse.* textwrap.*" )
223
224 m.addPackage( "${PN}-curses", "Python curses support", "${PN}-core",
225 "curses lib-dynload/_curses.*.so lib-dynload/_curses_panel.*.so" ) # directory + low level module
226
227 m.addPackage( "${PN}-ctypes", "Python C types support", "${PN}-core",
228 "ctypes lib-dynload/_ctypes.*.so lib-dynload/_ctypes_test.*.so" ) # directory + low level module
229
230 m.addPackage( "${PN}-datetime", "Python calendar and time support", "${PN}-core ${PN}-codecs",
231 "_strptime.* calendar.* lib-dynload/datetime.*.so" )
232
233 m.addPackage( "${PN}-db", "Python file-based database support", "${PN}-core",
234 "anydbm.* dumbdbm.* whichdb.* dbm lib-dynload/_dbm.*.so" )
235
236 m.addPackage( "${PN}-debugger", "Python debugger", "${PN}-core ${PN}-io ${PN}-lang ${PN}-re ${PN}-stringold ${PN}-shell ${PN}-pprint",
237 "bdb.* pdb.*" )
238
239 m.addPackage( "${PN}-difflib", "Python helpers for computing deltas between objects", "${PN}-lang ${PN}-re",
240 "difflib.*" )
241
242 m.addPackage( "${PN}-distutils-staticdev", "Python distribution utilities (static libraries)", "${PN}-distutils",
243 "config/lib*.a" ) # package
244
245 m.addPackage( "${PN}-distutils", "Python Distribution Utilities", "${PN}-core",
246 "config distutils" ) # package
247
248 m.addPackage( "${PN}-doctest", "Python framework for running examples in docstrings", "${PN}-core ${PN}-lang ${PN}-io ${PN}-re ${PN}-unittest ${PN}-debugger ${PN}-difflib",
249 "doctest.*" )
250
251 # FIXME consider adding to some higher level package
252 m.addPackage( "${PN}-elementtree", "Python elementree", "${PN}-core",
253 "lib-dynload/_elementtree.*.so" )
254
255 m.addPackage( "${PN}-email", "Python email support", "${PN}-core ${PN}-io ${PN}-re ${PN}-mime ${PN}-audio ${PN}-image ${PN}-netclient",
256 "imaplib.* email" ) # package
257
258 m.addPackage( "${PN}-fcntl", "Python's fcntl interface", "${PN}-core",
259 "lib-dynload/fcntl.*.so" )
260
261 m.addPackage( "${PN}-html", "Python HTML processing support", "${PN}-core",
262 "formatter.* htmlentitydefs.* htmllib.* markupbase.* sgmllib.* HTMLParser.* " )
263
264 m.addPackage( "${PN}-gdbm", "Python GNU database support", "${PN}-core",
265 "lib-dynload/_gdbm.*.so" )
266
267 m.addPackage( "${PN}-image", "Python graphical image handling", "${PN}-core",
268 "colorsys.* imghdr.* lib-dynload/imageop.*.so lib-dynload/rgbimg.*.so" )
269
270 m.addPackage( "${PN}-io", "Python low-level I/O", "${PN}-core ${PN}-math",
271 "lib-dynload/_socket.*.so lib-dynload/_io.*.so lib-dynload/_ssl.*.so lib-dynload/select.*.so lib-dynload/termios.*.so lib-dynload/cStringIO.*.so " +
272 "pipes.* socket.* ssl.* tempfile.* StringIO.* io.* _pyio.*" )
273
274 m.addPackage( "${PN}-json", "Python JSON support", "${PN}-core ${PN}-math ${PN}-re",
275 "json lib-dynload/_json.*.so" ) # package
276
277 m.addPackage( "${PN}-lang", "Python low-level language support", "${PN}-core",
278 "lib-dynload/_bisect.*.so lib-dynload/_collections.*.so lib-dynload/_heapq.*.so lib-dynload/_weakref.*.so lib-dynload/_functools.*.so " +
279 "lib-dynload/array.*.so lib-dynload/itertools.*.so lib-dynload/operator.*.so lib-dynload/parser.*.so " +
280 "atexit.* bisect.* code.* codeop.* collections.* dis.* functools.* heapq.* inspect.* keyword.* opcode.* symbol.* repr.* token.* " +
281 "tokenize.* traceback.* weakref.*" )
282
283 m.addPackage( "${PN}-logging", "Python logging support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-stringold",
284 "logging" ) # package
285
286 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
287 "mailbox.*" )
288
289 m.addPackage( "${PN}-math", "Python math support", "${PN}-core",
290 "lib-dynload/cmath.*.so lib-dynload/math.*.so lib-dynload/_random.*.so random.* sets.*" )
291
292 m.addPackage( "${PN}-mime", "Python MIME handling APIs", "${PN}-core ${PN}-io",
293 "mimetools.* uu.* quopri.* rfc822.* MimeWriter.*" )
294
295 m.addPackage( "${PN}-mmap", "Python memory-mapped file support", "${PN}-core ${PN}-io",
296 "lib-dynload/mmap.*.so " )
297
298 m.addPackage( "${PN}-multiprocessing", "Python multiprocessing support", "${PN}-core ${PN}-io ${PN}-lang ${PN}-pickle ${PN}-threading ${PN}-ctypes ${PN}-mmap",
299 "lib-dynload/_multiprocessing.*.so multiprocessing" ) # package
300
301 m.addPackage( "${PN}-netclient", "Python Internet Protocol clients", "${PN}-core ${PN}-crypt ${PN}-datetime ${PN}-io ${PN}-lang ${PN}-logging ${PN}-mime",
302 "*Cookie*.* " +
303 "base64.* cookielib.* ftplib.* gopherlib.* hmac.* httplib.* mimetypes.* nntplib.* poplib.* smtplib.* telnetlib.* urllib.* urllib2.* urlparse.* uuid.* rfc822.* mimetools.*" )
304
305 m.addPackage( "${PN}-netserver", "Python Internet Protocol servers", "${PN}-core ${PN}-netclient",
306 "cgi.* *HTTPServer.* SocketServer.*" )
307
308 m.addPackage( "${PN}-numbers", "Python number APIs", "${PN}-core ${PN}-lang ${PN}-re",
309 "decimal.* numbers.*" )
310
311 m.addPackage( "${PN}-pickle", "Python serialisation/persistence support", "${PN}-core ${PN}-codecs ${PN}-io ${PN}-re",
312 "pickle.* shelve.* lib-dynload/cPickle.*.so pickletools.*" )
313
314 m.addPackage( "${PN}-pkgutil", "Python package extension utility support", "${PN}-core",
315 "pkgutil.*")
316
317 m.addPackage( "${PN}-pprint", "Python pretty-print support", "${PN}-core ${PN}-io",
318 "pprint.*" )
319
320 m.addPackage( "${PN}-profile", "Python basic performance profiling support", "${PN}-core ${PN}-textutils",
321 "profile.* pstats.* cProfile.* lib-dynload/_lsprof.*.so" )
322
323 m.addPackage( "${PN}-re", "Python Regular Expression APIs", "${PN}-core",
324 "re.* sre.* sre_compile.* sre_constants* sre_parse.*" ) # _sre is builtin
325
326 m.addPackage( "${PN}-readline", "Python readline support", "${PN}-core",
327 "lib-dynload/readline.*.so rlcompleter.*" )
328
329 m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core",
330 "lib-dynload/resource.*.so" )
331
332 m.addPackage( "${PN}-shell", "Python shell-like functionality", "${PN}-core ${PN}-re",
333 "cmd.* commands.* dircache.* fnmatch.* glob.* popen2.* shlex.* shutil.*" )
334
335 m.addPackage( "${PN}-robotparser", "Python robots.txt parser", "${PN}-core ${PN}-netclient",
336 "urllib/robotparser.*")
337
338 m.addPackage( "${PN}-subprocess", "Python subprocess support", "${PN}-core ${PN}-io ${PN}-re ${PN}-fcntl ${PN}-pickle",
339 "subprocess.*" )
340
341 m.addPackage( "${PN}-sqlite3", "Python Sqlite3 database support", "${PN}-core ${PN}-datetime ${PN}-lang ${PN}-crypt ${PN}-io ${PN}-threading",
342 "lib-dynload/_sqlite3.*.so sqlite3/dbapi2.* sqlite3/__init__.* sqlite3/dump.*" )
343
344 m.addPackage( "${PN}-sqlite3-tests", "Python Sqlite3 database support tests", "${PN}-core ${PN}-sqlite3",
345 "sqlite3/test" )
346
347 m.addPackage( "${PN}-stringold", "Python string APIs [deprecated]", "${PN}-core ${PN}-re",
348 "lib-dynload/strop.*.so string.* stringold.*" )
349
350 m.addPackage( "${PN}-syslog", "Python syslog interface", "${PN}-core",
351 "lib-dynload/syslog.*.so" )
352
353 m.addPackage( "${PN}-terminal", "Python terminal controlling support", "${PN}-core ${PN}-io",
354 "pty.* tty.*" )
355
356 m.addPackage( "${PN}-tests", "Python tests", "${PN}-core",
357 "test" ) # package
358
359 m.addPackage( "${PN}-threading", "Python threading & synchronization support", "${PN}-core ${PN}-lang",
360 "_threading_local.* dummy_thread.* dummy_threading.* mutex.* threading.* Queue.*" )
361
362 m.addPackage( "${PN}-tkinter", "Python Tcl/Tk bindings", "${PN}-core",
363 "lib-dynload/_tkinter.*.so lib-tk tkinter" ) # package
364
365 m.addPackage( "${PN}-unittest", "Python unit testing framework", "${PN}-core ${PN}-stringold ${PN}-lang ${PN}-io ${PN}-difflib ${PN}-pprint ${PN}-shell",
366 "unittest/" )
367
368 m.addPackage( "${PN}-unixadmin", "Python Unix administration support", "${PN}-core",
369 "lib-dynload/nis.*.so lib-dynload/grp.*.so lib-dynload/pwd.*.so getpass.*" )
370
371 m.addPackage( "${PN}-xml", "Python basic XML support", "${PN}-core ${PN}-elementtree ${PN}-re",
372 "lib-dynload/pyexpat.*.so xml xmllib.*" ) # package
373
374 m.addPackage( "${PN}-xmlrpc", "Python XML-RPC support", "${PN}-core ${PN}-xml ${PN}-netserver ${PN}-lang",
375 "xmlrpclib.* SimpleXMLRPCServer.* DocXMLRPCServer.* xmlrpc" )
376
377 m.addPackage( "${PN}-mailbox", "Python mailbox format support", "${PN}-core ${PN}-mime",
378 "mailbox.*" )
379
380 m.make()
diff --git a/scripts/contrib/test_build_time.sh b/scripts/contrib/test_build_time.sh
new file mode 100755
index 0000000000..9e5725ae54
--- /dev/null
+++ b/scripts/contrib/test_build_time.sh
@@ -0,0 +1,237 @@
1#!/bin/bash
2
3# Build performance regression test script
4#
5# Copyright 2011 Intel Corporation
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#
22#
23# DESCRIPTION
24# This script is intended to be used in conjunction with "git bisect run"
25# in order to find regressions in build time, however it can also be used
26# independently. It cleans out the build output directories, runs a
27# specified worker script (an example is test_build_time_worker.sh) under
28# TIME(1), logs the results to TEST_LOGDIR (default /tmp) and returns a
29# value telling "git bisect run" whether the build time is good (under
30# the specified threshold) or bad (over it). There is also a tolerance
31# option but it is not particularly useful as it only subtracts the
32# tolerance from the given threshold and uses it as the actual threshold.
33#
34# It is also capable of taking a file listing git revision hashes to be
35# test-applied to the repository in order to get past build failures that
36# would otherwise cause certain revisions to have to be skipped; if a
37# revision does not apply cleanly then the script assumes it does not
38# need to be applied and ignores it.
39#
40# Please see the help output (syntax below) for some important setup
41# instructions.
42#
43# AUTHORS
44# Paul Eggleton <paul.eggleton@linux.intel.com>
45
46
47syntax() {
48 echo "syntax: $0 <script> <time> <tolerance> [patchrevlist]"
49 echo ""
50 echo " script - worker script file (if in current dir, prefix with ./)"
51 echo " time - time threshold (in seconds, suffix m for minutes)"
52 echo " tolerance - tolerance (in seconds, suffix m for minutes or % for"
53 echo " percentage, can be 0)"
54 echo " patchrevlist - optional file listing revisions to apply as patches on top"
55 echo ""
56 echo "You must set TEST_BUILDDIR to point to a previously created build directory,"
57 echo "however please note that this script will wipe out the TMPDIR defined in"
58 echo "TEST_BUILDDIR/conf/local.conf as part of its initial setup (as well as your"
59 echo "~/.ccache)"
60 echo ""
61 echo "To get rid of the sudo prompt, please add the following line to /etc/sudoers"
62 echo "(use 'visudo' to edit this; also it is assumed that the user you are running"
63 echo "as is a member of the 'wheel' group):"
64 echo ""
65 echo "%wheel ALL=(ALL) NOPASSWD: /sbin/sysctl -w vm.drop_caches=[1-3]"
66 echo ""
67 echo "Note: it is recommended that you disable crond and any other process that"
68 echo "may cause significant CPU or I/O usage during build performance tests."
69}
70
71# Note - we exit with 250 here because that will tell git bisect run that
72# something bad happened and stop
73if [ "$1" = "" ] ; then
74 syntax
75 exit 250
76fi
77
78if [ "$2" = "" ] ; then
79 syntax
80 exit 250
81fi
82
83if [ "$3" = "" ] ; then
84 syntax
85 exit 250
86fi
87
88if ! [[ "$2" =~ ^[0-9][0-9m.]*$ ]] ; then
89 echo "'$2' is not a valid number for threshold"
90 exit 250
91fi
92
93if ! [[ "$3" =~ ^[0-9][0-9m.%]*$ ]] ; then
94 echo "'$3' is not a valid number for tolerance"
95 exit 250
96fi
97
98if [ "$TEST_BUILDDIR" = "" ] ; then
99 echo "Please set TEST_BUILDDIR to a previously created build directory"
100 exit 250
101fi
102
103if [ ! -d "$TEST_BUILDDIR" ] ; then
104 echo "TEST_BUILDDIR $TEST_BUILDDIR not found"
105 exit 250
106fi
107
108git diff --quiet
109if [ $? != 0 ] ; then
110 echo "Working tree is dirty, cannot proceed"
111 exit 251
112fi
113
114if [ "$BB_ENV_EXTRAWHITE" != "" ] ; then
115 echo "WARNING: you are running after sourcing the build environment script, this is not recommended"
116fi
117
118runscript=$1
119timethreshold=$2
120tolerance=$3
121
122if [ "$4" != "" ] ; then
123 patchrevlist=`cat $4`
124else
125 patchrevlist=""
126fi
127
128if [[ timethreshold == *m* ]] ; then
129 timethreshold=`echo $timethreshold | sed s/m/*60/ | bc`
130fi
131
132if [[ $tolerance == *m* ]] ; then
133 tolerance=`echo $tolerance | sed s/m/*60/ | bc`
134elif [[ $tolerance == *%* ]] ; then
135 tolerance=`echo $tolerance | sed s/%//`
136 tolerance=`echo "scale = 2; (($tolerance * $timethreshold) / 100)" | bc`
137fi
138
139tmpdir=`grep "^TMPDIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/TMPDIR[ \t]*=[ \t\?]*"//' -e 's/"//'`
140if [ "x$tmpdir" = "x" ]; then
141 echo "Unable to determine TMPDIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
142 exit 250
143fi
144sstatedir=`grep "^SSTATE_DIR" $TEST_BUILDDIR/conf/local.conf | sed -e 's/SSTATE_DIR[ \t\?]*=[ \t]*"//' -e 's/"//'`
145if [ "x$sstatedir" = "x" ]; then
146 echo "Unable to determine SSTATE_DIR from $TEST_BUILDDIR/conf/local.conf, bailing out"
147 exit 250
148fi
149
150if [ `expr length $tmpdir` -lt 4 ] ; then
151 echo "TMPDIR $tmpdir is less than 4 characters, bailing out"
152 exit 250
153fi
154
155if [ `expr length $sstatedir` -lt 4 ] ; then
156 echo "SSTATE_DIR $sstatedir is less than 4 characters, bailing out"
157 exit 250
158fi
159
160echo -n "About to wipe out TMPDIR $tmpdir, press Ctrl+C to break out... "
161for i in 9 8 7 6 5 4 3 2 1
162do
163 echo -ne "\x08$i"
164 sleep 1
165done
166echo
167
168pushd . > /dev/null
169
170rm -f pseudodone
171echo "Removing TMPDIR $tmpdir..."
172rm -rf $tmpdir
173echo "Removing TMPDIR $tmpdir-*libc..."
174rm -rf $tmpdir-*libc
175echo "Removing SSTATE_DIR $sstatedir..."
176rm -rf $sstatedir
177echo "Removing ~/.ccache..."
178rm -rf ~/.ccache
179
180echo "Syncing..."
181sync
182sync
183echo "Dropping VM cache..."
184#echo 3 > /proc/sys/vm/drop_caches
185sudo /sbin/sysctl -w vm.drop_caches=3 > /dev/null
186
187if [ "$TEST_LOGDIR" = "" ] ; then
188 logdir="/tmp"
189else
190 logdir="$TEST_LOGDIR"
191fi
192rev=`git rev-parse HEAD`
193logfile="$logdir/timelog_$rev.log"
194echo -n > $logfile
195
196gitroot=`git rev-parse --show-toplevel`
197cd $gitroot
198for patchrev in $patchrevlist ; do
199 echo "Applying $patchrev"
200 patchfile=`mktemp`
201 git show $patchrev > $patchfile
202 git apply --check $patchfile &> /dev/null
203 if [ $? != 0 ] ; then
204 echo " ... patch does not apply without errors, ignoring"
205 else
206 echo "Applied $patchrev" >> $logfile
207 git apply $patchfile &> /dev/null
208 fi
209 rm $patchfile
210done
211
212sync
213echo "Quiescing for 5s..."
214sleep 5
215
216echo "Running $runscript at $rev..."
217timeoutfile=`mktemp`
218/usr/bin/time -o $timeoutfile -f "%e\nreal\t%E\nuser\t%Us\nsys\t%Ss\nmaxm\t%Mk" $runscript 2>&1 | tee -a $logfile
219exitstatus=$PIPESTATUS
220
221git reset --hard HEAD > /dev/null
222popd > /dev/null
223
224timeresult=`head -n1 $timeoutfile`
225cat $timeoutfile | tee -a $logfile
226rm $timeoutfile
227
228if [ $exitstatus != 0 ] ; then
229 # Build failed, exit with 125 to tell git bisect run to skip this rev
230 echo "*** Build failed (exit code $exitstatus), skipping..." | tee -a $logfile
231 exit 125
232fi
233
234ret=`echo "scale = 2; $timeresult > $timethreshold - $tolerance" | bc`
235echo "Returning $ret" | tee -a $logfile
236exit $ret
237
diff --git a/scripts/contrib/test_build_time_worker.sh b/scripts/contrib/test_build_time_worker.sh
new file mode 100755
index 0000000000..8e20a9ea7d
--- /dev/null
+++ b/scripts/contrib/test_build_time_worker.sh
@@ -0,0 +1,37 @@
1#!/bin/bash
2
3# This is an example script to be used in conjunction with test_build_time.sh
4
5if [ "$TEST_BUILDDIR" = "" ] ; then
6 echo "TEST_BUILDDIR is not set"
7 exit 1
8fi
9
10buildsubdir=`basename $TEST_BUILDDIR`
11if [ ! -d $buildsubdir ] ; then
12 echo "Unable to find build subdir $buildsubdir in current directory"
13 exit 1
14fi
15
16if [ -f oe-init-build-env ] ; then
17 . ./oe-init-build-env $buildsubdir
18elif [ -f poky-init-build-env ] ; then
19 . ./poky-init-build-env $buildsubdir
20else
21 echo "Unable to find build environment setup script"
22 exit 1
23fi
24
25if [ -f ../meta/recipes-sato/images/core-image-sato.bb ] ; then
26 target="core-image-sato"
27else
28 target="poky-image-sato"
29fi
30
31echo "Build started at `date "+%Y-%m-%d %H:%M:%S"`"
32echo "bitbake $target"
33bitbake $target
34ret=$?
35echo "Build finished at `date "+%Y-%m-%d %H:%M:%S"`"
36exit $ret
37
diff --git a/scripts/cp-noerror b/scripts/cp-noerror
new file mode 100755
index 0000000000..28eb90d4a0
--- /dev/null
+++ b/scripts/cp-noerror
@@ -0,0 +1,52 @@
1#!/usr/bin/env python
2#
3# Allow copying of $1 to $2 but if files in $1 disappear during the copy operation,
4# don't error.
5# Also don't error if $1 disappears.
6#
7
8import sys
9import os
10import shutil
11
12def copytree(src, dst, symlinks=False, ignore=None):
13 """Based on shutil.copytree"""
14 names = os.listdir(src)
15 try:
16 os.makedirs(dst)
17 except OSError:
18 # Already exists
19 pass
20 errors = []
21 for name in names:
22 srcname = os.path.join(src, name)
23 dstname = os.path.join(dst, name)
24 try:
25 d = dstname
26 if os.path.isdir(dstname):
27 d = os.path.join(dstname, os.path.basename(srcname))
28 if os.path.exists(d):
29 continue
30 try:
31 os.link(srcname, dstname)
32 except OSError:
33 shutil.copy2(srcname, dstname)
34 # catch the Error from the recursive copytree so that we can
35 # continue with other files
36 except shutil.Error, err:
37 errors.extend(err.args[0])
38 except EnvironmentError, why:
39 errors.append((srcname, dstname, str(why)))
40 try:
41 shutil.copystat(src, dst)
42 except OSError, why:
43 errors.extend((src, dst, str(why)))
44 if errors:
45 raise shutil.Error, errors
46
47try:
48 copytree(sys.argv[1], sys.argv[2])
49except shutil.Error:
50 pass
51except OSError:
52 pass
diff --git a/scripts/create-pull-request b/scripts/create-pull-request
new file mode 100755
index 0000000000..503248bbf0
--- /dev/null
+++ b/scripts/create-pull-request
@@ -0,0 +1,240 @@
1#!/bin/bash
2#
3# Copyright (c) 2010-2013, Intel Corporation.
4# All Rights Reserved
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14# the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19#
20
21#
22# This script is intended to be used to prepare a series of patches
23# and a cover letter in an appropriate and consistent format for
24# submission to Open Embedded and The Yocto Project, as well as to
25# related projects and layers.
26#
27
28ODIR=pull-$$
29RELATIVE_TO="master"
30COMMIT_ID="HEAD"
31PREFIX="PATCH"
32RFC=0
33
34usage() {
35CMD=$(basename $0)
36cat <<EOM
37Usage: $CMD [-h] [-o output_dir] [-m msg_body_file] [-s subject] [-r relative_to] [-i commit_id] -u remote [-b branch]
38 -b branch Branch name in the specified remote (default: current branch)
39 -c Create an RFC (Request for Comment) patch series
40 -h Display this help message
41 -i commit_id Ending commit (default: HEAD)
42 -m msg_body_file The file containing a blurb to be inserted into the summary email
43 -o output_dir Specify the output directory for the messages (default: pull-PID)
44 -p prefix Use [prefix N/M] instead of [PATCH N/M] as the subject prefix
45 -r relative_to Starting commit (default: master)
46 -s subject The subject to be inserted into the summary email
47 -u remote The git remote where the branch is located
48
49 Examples:
50 $CMD -u contrib -b nitin/basic
51 $CMD -u contrib -r distro/master -i nitin/distro -b nitin/distro
52 $CMD -u contrib -r master -i misc -b nitin/misc -o pull-misc
53 $CMD -u contrib -p "RFC PATCH" -b nitin/experimental
54EOM
55}
56
57# Parse and validate arguments
58while getopts "b:chi:m:o:p:r:s:u:" OPT; do
59 case $OPT in
60 b)
61 BRANCH="$OPTARG"
62 ;;
63 c)
64 RFC=1
65 ;;
66 h)
67 usage
68 exit 0
69 ;;
70 i)
71 COMMIT_ID="$OPTARG"
72 ;;
73 m)
74 BODY="$OPTARG"
75 if [ ! -e "$BODY" ]; then
76 echo "ERROR: Body file does not exist"
77 exit 1
78 fi
79 ;;
80 o)
81 ODIR="$OPTARG"
82 ;;
83 p)
84 PREFIX="$OPTARG"
85 ;;
86 r)
87 RELATIVE_TO="$OPTARG"
88 ;;
89 s)
90 SUBJECT="$OPTARG"
91 ;;
92 u)
93 REMOTE="$OPTARG"
94 REMOTE_URL=$(git config remote.$REMOTE.url)
95 if [ $? -ne 0 ]; then
96 echo "ERROR: git config failed to find a url for '$REMOTE'"
97 echo
98 echo "To add a remote url for $REMOTE, use:"
99 echo " git config remote.$REMOTE.url <url>"
100 exit 1
101 fi
102
103 # Rewrite private URLs to public URLs
104 # Determine the repository name for use in the WEB_URL later
105 case "$REMOTE_URL" in
106 *@*)
107 USER_RE="[A-Za-z0-9_.@][A-Za-z0-9_.@-]*\$\?"
108 PROTO_RE="[a-z][a-z+]*://"
109 GIT_RE="\(^\($PROTO_RE\)\?$USER_RE@\)\([^:/]*\)[:/]\(.*\)"
110 REMOTE_URL=${REMOTE_URL%.git}
111 REMOTE_REPO=$(echo $REMOTE_URL | sed "s#$GIT_RE#\4#")
112 REMOTE_URL=$(echo $REMOTE_URL | sed "s#$GIT_RE#git://\3/\4#")
113 ;;
114 *)
115 echo "WARNING: Unrecognized remote URL: $REMOTE_URL"
116 echo " The pull and browse URLs will likely be incorrect"
117 ;;
118 esac
119 ;;
120 esac
121done
122
123if [ -z "$BRANCH" ]; then
124 BRANCH=$(git branch | grep -e "^\* " | cut -d' ' -f2)
125 echo "NOTE: Assuming remote branch '$BRANCH', use -b to override."
126fi
127
128if [ -z "$REMOTE_URL" ]; then
129 echo "ERROR: Missing parameter -u, no git remote!"
130 usage
131 exit 1
132fi
133
134if [ $RFC -eq 1 ]; then
135 PREFIX="RFC $PREFIX"
136fi
137
138
139# Set WEB_URL from known remotes
140WEB_URL=""
141case "$REMOTE_URL" in
142 *git.yoctoproject.org*)
143 WEB_URL="http://git.yoctoproject.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
144 ;;
145 *git.pokylinux.org*)
146 WEB_URL="http://git.pokylinux.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
147 ;;
148 *git.openembedded.org*)
149 WEB_URL="http://cgit.openembedded.org/cgit.cgi/$REMOTE_REPO/log/?h=$BRANCH"
150 ;;
151 *github.com*)
152 WEB_URL="https://github.com/$REMOTE_REPO/tree/$BRANCH"
153 ;;
154esac
155
156# Perform a sanity test on the web URL. Issue a warning if it is not
157# accessible, but do not abort as users may want to run offline.
158if [ -n "$WEB_URL" ]; then
159 wget --no-check-certificate -q $WEB_URL -O /dev/null
160 if [ $? -ne 0 ]; then
161 echo "WARNING: Branch '$BRANCH' was not found on the contrib git tree."
162 echo " Please check your remote and branch parameter before sending."
163 echo ""
164 fi
165fi
166
167if [ -e $ODIR ]; then
168 echo "ERROR: output directory $ODIR exists."
169 exit 1
170fi
171mkdir $ODIR
172
173
174# Generate the patches and cover letter
175git format-patch -M40 --subject-prefix="$PREFIX" -n -o $ODIR --thread=shallow --cover-letter $RELATIVE_TO..$COMMIT_ID > /dev/null
176
177
178# Customize the cover letter
179CL="$ODIR/0000-cover-letter.patch"
180PM="$ODIR/pull-msg"
181git request-pull $RELATIVE_TO $REMOTE_URL $COMMIT_ID >> "$PM"
182if [ $? -ne 0 ]; then
183 echo "ERROR: git request-pull reported an error"
184 exit 1
185fi
186
187# The cover letter already has a diffstat, remove it from the pull-msg
188# before inserting it.
189sed -n "0,\#$REMOTE_URL# p" "$PM" | sed -i "/BLURB HERE/ r /dev/stdin" "$CL"
190rm "$PM"
191
192# If this is an RFC, make that clear in the cover letter
193if [ $RFC -eq 1 ]; then
194(cat <<EOM
195Please review the following changes for suitability for inclusion. If you have
196any objections or suggestions for improvement, please respond to the patches. If
197you agree with the changes, please provide your Acked-by.
198
199EOM
200) | sed -i "/BLURB HERE/ r /dev/stdin" "$CL"
201fi
202
203# Insert the WEB_URL if there is one
204if [ -n "$WEB_URL" ]; then
205 echo " $WEB_URL" | sed -i "\#$REMOTE_URL# r /dev/stdin" "$CL"
206fi
207
208
209# If the user specified a message body, insert it into the cover letter and
210# remove the BLURB token.
211if [ -n "$BODY" ]; then
212 sed -i "/BLURB HERE/ r $BODY" "$CL"
213 sed -i "/BLURB HERE/ d" "$CL"
214fi
215
216# If the user specified a subject, replace the SUBJECT token with it.
217if [ -n "$SUBJECT" ]; then
218 sed -i -e "s/\*\*\* SUBJECT HERE \*\*\*/$SUBJECT/" "$CL"
219fi
220
221
222# Generate report for user
223cat <<EOM
224The following patches have been prepared:
225$(for PATCH in $(ls $ODIR/*); do echo " $PATCH"; done)
226
227Review their content, especially the summary mail:
228 $CL
229
230When you are satisfied, you can send them with:
231 send-pull-request -a -p $ODIR
232EOM
233
234# Check the patches for trailing white space
235egrep -q -e "^\+.*\s+$" $ODIR/*
236if [ $? -ne 1 ]; then
237 echo
238 echo "WARNING: Trailing white space detected at these locations"
239 egrep -nH --color -e "^\+.*\s+$" $ODIR/*
240fi
diff --git a/scripts/create-recipe b/scripts/create-recipe
new file mode 100755
index 0000000000..b192990080
--- /dev/null
+++ b/scripts/create-recipe
@@ -0,0 +1,2072 @@
1#!/usr/bin/perl -w
2
3# Copyright (C) 2012 Wind River Systems, Inc.
4#
5# Copyright (C) 2010 Intel Corporation
6#
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# As a special exception, you may create a larger work that contains
21# part or all of the autospectacle output and distribute that work
22# under terms of your choice.
23# Alternatively, if you modify or redistribute autospectacle itself,
24# you may (at your option) remove this special exception.
25#
26# This special exception was modeled after the bison exception
27# (as done by the Free Software Foundation in version 2.2 of Bison)
28#
29
30
31use File::Temp qw(tempdir);
32use File::Path qw(mkpath rmtree);
33use File::Spec ();
34use File::Basename qw(basename dirname);
35
36
37my $name = "";
38my $predef_version = "TO BE FILLED IN";
39my $version = $predef_version;
40my $pversion = $predef_version;
41my $description = "";
42my $summary = "";
43my $url = "";
44my $homepage = "";
45my @depends;
46my @rdepends;
47my @rawpythondeps;
48my $configure = "";
49my $localename = "";
50my @sources;
51my @mainfiles;
52my @patches;
53
54my $md5sum = "";
55my $sh256sum = "";
56my @inherits;
57
58my $printed_subpackages = 0;
59my $fulldir = "";
60
61my $builder = "";
62
63
64my $oscmode = 0;
65my $python = 0;
66
67my @banned_pkgconfig;
68my %failed_commands;
69my %failed_libs;
70my %failed_headers;
71
72
73
74######################################################################
75#
76# License management
77#
78# We store the sha1sum of common COPYING files in an associative array
79# %licenses.
80#
81# For all matching sha1's in the tarball, we then push the result
82# in the @license array (which we'll dedupe at the time of printing).
83#
84
85my %licenses;
86my @license;
87my %lic_files;
88
89sub setup_licenses
90{
91 $licenses{"06877624ea5c77efe3b7e39b0f909eda6e25a4ec"} = "GPLv2";
92 $licenses{"075d599585584bb0e4b526f5c40cb6b17e0da35a"} = "GPLv2";
93 $licenses{"10782dd732f42f49918c839e8a5e2894c508b079"} = "GPLv2";
94 $licenses{"2d29c273fda30310211bbf6a24127d589be09b6c"} = "GPLv2";
95 $licenses{"4df5d4b947cf4e63e675729dd3f168ba844483c7"} = "LGPLv2.1";
96 $licenses{"503df7650052cf38efde55e85f0fe363e59b9739"} = "GPLv2";
97 $licenses{"5405311284eab5ab51113f87c9bfac435c695bb9"} = "GPLv2";
98 $licenses{"5fb362ef1680e635fe5fb212b55eef4db9ead48f"} = "LGPLv2";
99 $licenses{"68c94ffc34f8ad2d7bfae3f5a6b996409211c1b1"} = "GPLv2";
100 $licenses{"66c77efd1cf9c70d4f982ea59487b2eeb6338e26"} = "LGPLv2.1";
101 $licenses{"74a8a6531a42e124df07ab5599aad63870fa0bd4"} = "GPLv2";
102 $licenses{"8088b44375ef05202c0fca4e9e82d47591563609"} = "LGPLv2.1";
103 $licenses{"8624bcdae55baeef00cd11d5dfcfa60f68710a02"} = "GPLv3";
104 $licenses{"8e57ffebd0ed4417edc22e3f404ea3664d7fed27"} = "MIT";
105 $licenses{"99b5245b4714b9b89e7584bfc88da64e2d315b81"} = "BSD";
106 $licenses{"aba8d76d0af67d57da3c3c321caa59f3d242386b"} = "MPLv1.1";
107 $licenses{"bf50bac24e7ec325dbb09c6b6c4dcc88a7d79e8f"} = "LGPLv2";
108 $licenses{"caeb68c46fa36651acf592771d09de7937926bb3"} = "LGPLv2.1";
109 $licenses{"dfac199a7539a404407098a2541b9482279f690d"} = "GPLv2";
110 $licenses{"e60c2e780886f95df9c9ee36992b8edabec00bcc"} = "LGPLv2.1";
111 $licenses{"c931aad3017d975b7f20666cde0953234a9efde3"} = "GPLv2";
112}
113
114sub guess_license_from_file {
115 my ($copying) = @_;
116
117 if (!-e $copying) {
118 return;
119 }
120
121 my $sha1output = `sha1sum $copying`;
122 $sha1output =~ /^([a-zA-Z0-9]*) /;
123 my $sha1 = $1;
124
125 chomp($sha1);
126
127 #
128 # if sha1 matches.. push there result
129 #
130 if (defined($licenses{$sha1})) {
131 my $lic = $licenses{$sha1};
132 push(@license, $lic);
133
134 my $md5output = `md5sum $copying`;
135 $md5output =~ /^([a-zA-Z0-9]*) /;
136 my $md5 = $1;
137 chomp($md5);
138 $lic_files{$copying} = $md5
139 }
140
141 #
142 # if file is found, and licence of python
143 # package is already aquired, add file.
144 #
145 if ($python == 1 && @license != 0) {
146 my $md5output = `md5sum $copying`;
147 $md5output =~ /^([a-zA-Z0-9]*) /;
148 my $md5 = $1;
149 chomp($md5);
150 $lic_files{$copying} = $md5
151 }
152
153 #
154 # We also must make sure that the COPYING/etc files
155 # end up in the main package as %doc..
156 #
157 $copying =~ s/$fulldir//g;
158 $copying =~ s/^\///g;
159 $copying = "\"\%doc " . $copying ."\"";
160
161 push(@mainfiles, $copying);
162}
163
164sub print_license
165{
166 my $count = @license;
167 if ($count == 0) {
168 print OUTFILE "License: TO BE FILLED IN\n";
169 return;
170 }
171
172 # remove dupes
173 undef %saw;
174 @saw{@license} = ();
175 @out = sort keys %saw;
176
177 print OUTFILE "License : ";
178 foreach (@out) {
179 print OUTFILE "$_ ";
180 }
181 print OUTFILE "\n";
182}
183
184# end of license section
185#
186#######################################################################
187
188######################################################################
189#
190# Package group management
191#
192# We set up an associative array of regexp patterns, where the content
193# of the array is the name of the group.
194#
195# These are "strings of regexps", which means one needs to escape
196# everything, and if you want the actual regexp to have a \,
197# it needs to be a \\ in this string.
198
199my %group_patterns;
200my @groups;
201my $group = "TO_BE/FILLED_IN";
202
203sub setup_group_rules
204{
205 $group_patterns{"^\\/usr\\/lib\\/.*so"} = "System/Libraries";
206 $group_patterns{"^\\/lib\\/.*so"} = "System/Libraries";
207 $group_patterns{"^\\/bin\\/.*"} = "Applications/System";
208 $group_patterns{"^\\/sbin\\/.*"} = "Applications/System";
209 $group_patterns{"^\\/usr\\/sbin\\/.*"} = "Applications/System";
210}
211
212sub guess_group_from_file
213{
214 my ($filename) = @_;
215 while (($key,$value) = each %group_patterns) {
216 if ($filename =~ /$key/) {
217 push(@groups, $value);
218 }
219 }
220
221}
222
223# end of group section
224#
225######################################################################
226
227
228######################################################################
229#
230# Files and package section
231#
232# This section creates the %files section, but also decides which
233# subpackages (devel and/or doc) we need to have.
234#
235# We start out with the @allfiles array, which will contain all the
236# files installed by the %build phase of the package. The task is
237# to sort these into @mainfiles, @develfiles and @docfiles.
238# In addition, an attempt is made to compress the files list by
239# replacing full filenames with "*" patterns.
240#
241# For this we use a set of regexps from the @files_match array,
242# which are then used as index to three associative arrays:
243# %files_target : numerical index for which package the regexp
244# would place the file at hand.
245# 0 - main package
246# 1 - devel package
247# 2 - doc package
248# 99 - don't package this at all
249#
250# %files_from: regexp to match the file against for filename-wildcarding
251# %files_to : pattern to append to the ()'d part of %files_from to end up
252# with the filename-wildcard.
253
254my @allfiles;
255my @develfiles;
256my @docfiles;
257
258
259my @files_match;
260my %files_target;
261my %files_from;
262my %files_to;
263
264my $totaldocs = 0;
265
266
267sub add_files_rule
268{
269 my ($match, $target, $from, $to) =@_;
270 push(@files_match, $match);
271 $files_target{"$match"} = $target;
272
273 if (length($from) > 0) {
274 $files_from{"$match"} = $from;
275 }
276
277 if (length($to) > 0) {
278 $files_to{"$match"} = $to;
279 }
280}
281
282sub setup_files_rules
283{
284
285#
286# Files for the Main package
287#
288
289 add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\\.", 0,
290 "(\\/usr\\/lib\\/.*\\.so\\.).*", "\*");
291
292
293 add_files_rule("^\\/usr\\/share\\/omf\\/", 0,
294 "(\\/usr\\/share\\/omf\\/.*?\\/).*", "\*");
295
296#
297# Files for the Devel subpackage
298#
299 add_files_rule("^\\/usr\\/share\\/gir-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.gir\$", 1,
300 "(\\/usr\\/share\\/gir-1\\.0\/).*", "\*\.gir");
301 add_files_rule("^\\/usr\\/lib\\/girepository-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.typelib\$", 1,
302 "(\\/usr\\/lib\\/girepository-1\\.0\/).*", "\*\.typelib");
303 add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\.h\$", 1,
304 "(\\/usr\\/include\/).*", "\*\.h");
305 add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?\\.h\$", 1,
306 "(\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?)[a-z0-9A-Z\\_\\-\\.]+\\.h", "\*\.h");
307 add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\$", 1,
308 "(\\/usr\\/lib\\/).*\\.so\$", "\*.so");
309 add_files_rule("^\\/usr\\/lib\\/pkgconfig\\/[a-z0-9A-Z\\_\\-\\.\+]+\\.pc\$", 1,
310 "(\\/usr\\/lib\\/pkgconfig\\/).*\\.pc\$", "\*.pc");
311 add_files_rule("^\\/usr\\/share\\/aclocal", 1, "", "");
312 add_files_rule("^\\/usr\\/lib\\/qt4\\/mkspecs/", 1, "", "");
313
314
315
316
317#
318# Files for the documentation subpackage
319#
320 add_files_rule("^\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/.\*", 2,
321 "(\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/).\*", "\*");
322 add_files_rule("^\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]*", 2,
323 "(\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]+\\/).*", "\*");
324 add_files_rule("^\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]*", 2,
325 "(\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]+\\/).*", "\*");
326 add_files_rule("^\\/usr\\/share\\/gnome\\/help\\/", 2,
327 "(\\/usr\\/share\\/gnome\\/help\\/.*?\\/.*?\\/).*", "\*");
328
329
330#
331# Files to just not package at all (picked up by other things)
332#
333 add_files_rule("^\\/usr\\/share\\/locale", 99, "", "");
334 # compiled python things will get auto cleaned by rpm
335# add_files_rule("\.pyo\$", 99, "", "");
336# add_files_rule("\.pyc\$", 99, "", "");
337
338}
339
340sub apply_files_rules
341{
342 my $filenumber = @allfiles;
343
344 if ($filenumber == 0) {
345 return;
346 }
347
348 while (@allfiles > 0) {
349 my $filename = $allfiles[0];
350 my $destname = $filename;
351 my $handled = 0;
352
353#
354# while we're here, try to guess what group our package is
355#
356 guess_group_from_file($filename);
357
358 foreach (@files_match) {
359 my $match = $_;
360
361 if ($filename =~ /$match/) {
362#
363# First try to see if we can turn the full filename into a
364# wildcard based filename
365#
366 if (defined($files_from{$match}) && defined($files_to{$match})) {
367 $from = $files_from{$match};
368 $to = $files_to{$match};
369 $destname =~ s/$from/$1$to/;
370# print "changing $filename to $destname\n";
371 }
372
373# devel package
374 if ($files_target{$match} == 1) {
375 $handled = 1;
376 push(@develfiles, $destname);
377 }
378# doc rules.. also prepend %doc
379 if ($files_target{$match} == 2) {
380 $handled = 1;
381 $destname = "\"%doc " . $destname . "\"";
382 push(@docfiles, $destname);
383 $totaldocs = $totaldocs + 1;
384 }
385# don't package
386 if ($files_target{$match} == 99) {
387 $handled = 1;
388 if ($filename =~ /\/usr\/share\/locale\/.*?\/LC_MESSAGES\/(.*)\.mo/) {
389 $localename = $1;
390 }
391 }
392 }
393 }
394
395
396#
397# if the destination name contains our package version,
398# use %version instead for future maintenance
399#
400 $destname =~ s/$version/\%\{version\}/g;
401 if ($handled == 0) {
402 push(@mainfiles, $destname);
403 }
404 shift(@allfiles);
405 }
406
407#
408# Now.. if we have less than 5 documentation files, just stick them in the main package
409#
410
411 $filenumber = @docfiles;
412
413 if ($filenumber <= 5) {
414 while (@docfiles > 0) {
415 my $filename = $docfiles[0];
416
417 push(@mainfiles, $filename);
418 shift(@docfiles);
419 }
420 }
421
422}
423
424sub print_files
425{
426 my $count = @mainfiles;
427 if ($count == 0) {
428 return;
429 }
430
431 # remove dupes
432 undef %saw;
433 @saw{@mainfiles} = ();
434 @out = sort keys %saw;
435
436 print OUTFILE "Files:\n";
437 foreach (@out) {
438 print OUTFILE " - $_\n";
439 }
440}
441
442sub print_devel
443{
444 my $count = @develfiles;
445 if ($count == 0) {
446 return;
447 }
448 print OUTFILE "SubPackages:\n";
449 $printed_subpackages = 1;
450 print OUTFILE " - Name: devel\n";
451 print OUTFILE " Summary: Development components for the $name package\n";
452 print OUTFILE " Group: Development/Libraries\n";
453 print OUTFILE " Description:\n";
454 print OUTFILE " - Development files for the $name package\n";
455
456 # remove dupes
457 undef %saw;
458 @saw{@develfiles} = ();
459 @out = sort keys %saw;
460
461 print OUTFILE " Files:\n";
462 foreach (@out) {
463 print OUTFILE " - $_\n";
464 }
465}
466
467sub print_doc
468{
469 my $count = @docfiles;
470 if ($count == 0) {
471 return;
472 }
473 if ($printed_subpackages == 0) {
474 print OUTFILE "SubPackages:\n";
475 $printed_subpackages = 1;
476 }
477 print OUTFILE " - Name: docs\n";
478 print OUTFILE " Summary: Documentation components for the $name package\n";
479 print OUTFILE " Group: Documentation\n";
480
481 # remove dupes
482 undef %saw;
483 @saw{@docfiles} = ();
484 @out = sort keys %saw;
485
486 print OUTFILE " Files:\n";
487 foreach (@out) {
488 print OUTFILE " - $_\n";
489 }
490}
491
492
493# end of %files section
494#
495######################################################################
496
497
498######################################################################
499#
500# What we can learn from configure.ac/configure
501#
502# - pkgconfig requirements
503# - regular build requirements
504# - package name / version
505
506
507sub setup_pkgconfig_ban
508{
509 push(@banned_pkgconfig, "^dnl\$");
510 push(@banned_pkgconfig, "^hal\$"); # we don't have nor want HAL
511 push(@banned_pkgconfig, "tslib-0.0"); # we don't want tslib-0.0 (legacy touchscreen interface)
512 push(@banned_pkgconfig, "intel-gen4asm");
513 push(@banned_pkgconfig, "^xp\$"); # xprint - deprecated and not in meego
514 push(@banned_pkgconfig, "^directfb\$"); # we use X, not directfb
515 push(@banned_pkgconfig, "^gtkmm-2.4\$"); # we use X, not directfb
516 push(@banned_pkgconfig, "^evil\$");
517 push(@banned_pkgconfig, "^directfb");
518 push(@banned_pkgconfig, "^sdl ");
519
520
521}
522
523sub setup_failed_commands
524{
525 $failed_commands{"doxygen"} = "doxygen";
526 $failed_commands{"scrollkeeper-config"} = "rarian-compat";
527 $failed_commands{"dot"} = "graphviz";
528 $failed_commands{"flex"} = "flex";
529 $failed_commands{"lex"} = "flex";
530 $failed_commands{"freetype-config"} = "freetype-devel";
531 $failed_commands{"makeinfo"} = "texinfo";
532 $failed_commands{"desktop-file-install"} = "desktop-file-utils";
533 $failed_commands{"deflateBound in -lz"} = "zlib-devel";
534 $failed_commands{"gconftool-2"} = "GConf-dbus";
535 $failed_commands{"jpeglib.h"} = "libjpeg-devel";
536 $failed_commands{"expat.h"} = "expat-devel";
537 $failed_commands{"bison"} = "bison";
538 $failed_commands{"msgfmt"} = "gettext";
539 $failed_commands{"curl-config"} = "libcurl-devel";
540 $failed_commands{"doxygen"} = "doxygen";
541 $failed_commands{"X"} = "pkgconfig(x11)";
542
543 $failed_commands{"gawk"} = "gawk";
544 $failed_commands{"xbkcomp"} = "xkbcomp";
545 $failed_commands{"Vorbis"} = "libvorbis-devel";
546 # checking Expat 1.95.x... no
547 $failed_commands{"Expat 1.95.x"} = "expat-devel";
548 $failed_commands{"xml2-config path"} = "libxml2-devel";
549
550 $failed_libs{"-lz"} = "zlib-devel";
551 $failed_libs{"-lncursesw"} = "ncurses-devel";
552 $failed_libs{"-ltiff"} = "libtiff-devel";
553 $failed_libs{"-lasound"} = "alsa-lib-devel";
554 $failed_libs{"Curses"} = "ncurses-devel";
555
556 $failed_headers{"X11/extensions/randr.h"} = "xrandr";
557 $failed_headers{"X11/Xlib.h"} = "x11";
558 $failed_headers{"X11/extensions/XShm.h"} = "xext";
559 $failed_headers{"X11/extensions/shape.h"} = "xext";
560 $failed_headers{"ncurses.h"} = "ncursesw";
561 $failed_headers{"curses.h"} = "ncursesw";
562 $failed_headers{"pci/pci.h"} = "libpci";
563 $failed_headers{"xf86.h"} = "xorg-server";
564 $failed_headers{"sqlite.h"} = "sqlite3";
565
566 $failed_headers{"X11/extensions/XIproto.h"} = "xi";
567 $failed_headers{"QElapsedTimer"} = "";
568}
569
570
571
572my @package_configs;
573my @buildreqs;
574my $uses_configure = 0;
575
576
577sub push_pkgconfig_buildreq
578{
579 my ($pr) = @_;
580
581 $pr =~ s/\s+//g;
582
583 # remove collateral ] ) etc damage in the string
584 $pr =~ s/\"//g;
585 $pr =~ s/\)//g;
586 $pr =~ s/\]//g;
587 $pr =~ s/\[//g;
588
589
590 # first, undo the space packing
591
592 $pr =~ s/\>\=/ \>\= /g;
593 $pr =~ s/\<\=/ \<\= /g;
594
595 $pr =~ s/\<1.1.1/ /g;
596
597 # don't show configure variables, we can't deal with them
598 if ($pr =~ /^\$/) {
599 return;
600 }
601 if ($pr =~ /AC_SUBST/) {
602 return;
603 }
604
605
606
607
608 # process banned pkgconfig options for things that we don't
609 # have or don't want.
610
611
612 # remore versions that are macros or strings, not numbers
613 $pr =~ s/\s\>\= \$.*//g;
614
615 $pr =~ s/\s\>\= [a-zA-Z]+.*//g;
616
617 # don't show configure variables, we can't deal with them
618 if ($pr =~ /\$/) {
619 return;
620 }
621
622 foreach (@banned_pkgconfig) {
623 my $ban = $_;
624 if ($pr =~ /$ban/) {
625 return;
626 }
627 }
628
629 push(@package_configs, $pr);
630}
631
632#
633# detect cases where we require both a generic pkgconfig, and a version specific
634# case
635#
636sub uniquify_pkgconfig
637{
638 # first remove real dupes
639 undef %saw;
640 @saw{@package_configs} = ();
641 @out = sort keys %saw;
642
643 my $count = 0;
644
645 while ($count < @out) {
646
647 my $entry = $out[$count];
648
649 foreach(@out) {
650 my $compare = $_;
651 if ($entry eq $compare) {
652 next;
653 }
654
655 $compare =~ s/ \>\=.*//g;
656 if ($entry eq $compare) {
657 $out[$count] = "";
658 }
659 }
660 $count = $count + 1;
661 }
662 @package_configs = @out;
663}
664
665
666sub process_configure_ac
667{
668 my ($filename) = @_;
669 my $line = "";
670 my $depth = 0;
671 my $keepgoing = 1;
672 my $buffer = "";
673
674 if (!-e $filename) {
675 return;
676 }
677
678 $uses_configure = 1;
679
680
681
682 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
683 seek(CONFIGURE, 0,0) or die "seek : $!";
684 while ($keepgoing && !eof(CONFIGURE)) {
685 $buffer = getc(CONFIGURE);
686
687 if ($buffer eq "(") {
688 $depth = $depth + 1;
689 }
690 if ($buffer eq ")" && $depth > 0) {
691 $depth = $depth - 1;
692 }
693
694 if (!($buffer eq "\n")) {
695 $line = $line . $buffer;
696 }
697
698 if (!($buffer eq "\n") || $depth > 0) {
699 redo unless eof(CONFIGURE);
700 }
701
702 if ($line =~ /PKG_CHECK_MODULES\((.*)\)/) {
703 my $match = $1;
704 $match =~ s/\s+/ /g;
705 $match =~ s/, /,/g;
706 my @pkgs = split(/,/, $match);
707 my $pkg;
708 if (defined($pkgs[1])) {
709 $pkg = $pkgs[1];
710 } else {
711 next;
712 }
713 if ($pkg =~ /\[(.*)\]/) {
714 $pkg = $1;
715 }
716
717 $pkg =~ s/\s+/ /g;
718 # deal with versioned pkgconfig's by removing the spaces around >= 's
719 $pkg =~ s/\>\=\s/\>\=/g;
720 $pkg =~ s/\s\>\=/\>\=/g;
721 $pkg =~ s/\=\s/\=/g;
722 $pkg =~ s/\s\=/\=/g;
723 $pkg =~ s/\<\=\s/\<\=/g;
724 $pkg =~ s/\<\s/\</g;
725 $pkg =~ s/\s\<\=/\<\=/g;
726 $pkg =~ s/\s\</\</g;
727
728 @words = split(/ /, $pkg);
729 foreach(@words) {
730 push_pkgconfig_buildreq($_);
731 }
732 }
733
734 if ($line =~ /PKG_CHECK_EXISTS\((.*)\)/) {
735 my $match = $1;
736 $match =~ s/\s+/ /g;
737 $match =~ s/, /,/g;
738 my @pkgs = split(/,/, $match);
739 my $pkg = $pkgs[0];
740 if ($pkg =~ /\[(.*)\]/) {
741 $pkg = $1;
742 }
743
744 $pkg =~ s/\s+/ /g;
745 # deal with versioned pkgconfig's by removing the spaces around >= 's
746 $pkg =~ s/\>\=\s/\>\=/g;
747 $pkg =~ s/\s\>\=/\>\=/g;
748 $pkg =~ s/\<\=\s/\<\=/g;
749 $pkg =~ s/\<\s/\</g;
750 $pkg =~ s/\s\<\=/\<\=/g;
751 $pkg =~ s/\s\</\</g;
752 $pkg =~ s/\=\s/\=/g;
753 $pkg =~ s/\s\=/\=/g;
754
755 @words = split(/ /, $pkg);
756 foreach(@words) {
757 push_pkgconfig_buildreq($_);
758 }
759 }
760
761 if ($line =~ /XDT_CHECK_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
762 my $pkg = $1;
763
764 $pkg =~ s/\s+/ /g;
765 # deal with versioned pkgconfig's by removing the spaces around >= 's
766 $pkg =~ s/\>\=\s/\>\=/g;
767 $pkg =~ s/\s\>\=/\>\=/g;
768 $pkg =~ s/\=\s/\=/g;
769 $pkg =~ s/\s\=/\=/g;
770
771 @words = split(/ /, $pkg);
772 foreach(@words) {
773 push_pkgconfig_buildreq($_);
774 }
775 }
776
777 if ($line =~ /XDT_CHECK_OPTIONAL_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
778 my $pkg = $1;
779
780 $pkg =~ s/\s+/ /g;
781 # deal with versioned pkgconfig's by removing the spaces around >= 's
782 $pkg =~ s/\>\=\s/\>\=/g;
783 $pkg =~ s/\s\>\=/\>\=/g;
784 $pkg =~ s/\=\s/\=/g;
785 $pkg =~ s/\s\=/\=/g;
786
787 @words = split(/ /, $pkg);
788 foreach(@words) {
789 push_pkgconfig_buildreq($_);
790 }
791 }
792
793 if ($line =~ /AC_CHECK_LIB\(\[expat\]/) {
794 push(@buildreqs, "expat-devel");
795 }
796 if ($line =~ /AC_CHECK_FUNC\(\[tgetent\]/) {
797 push(@buildreqs, "ncurses-devel");
798 }
799 if ($line =~ /_PROG_INTLTOOL/) {
800 push(@buildreqs, "intltool");
801 }
802 if ($line =~ /GETTEXT_PACKAGE/) {
803 push(@buildreqs, "gettext");
804 }
805 if ($line =~ /GTK_DOC_CHECK/) {
806 push_pkgconfig_buildreq("gtk-doc");
807 }
808 if ($line =~ /GNOME_DOC_INIT/) {
809 push(@buildreqs, "gnome-doc-utils");
810 }
811 if ($line =~ /AM_GLIB_GNU_GETTEXT/) {
812 push(@buildreqs, "gettext");
813 }
814
815 if ($line =~ /AC_INIT\((.*)\)/) {
816 my $match = $1;
817 $match =~ s/\s+/ /g;
818 @acinit = split(/,/, $match);
819# $name = $acinit[0];
820
821 if ($name =~ /\[(.*)\]/) {
822# $name = $1;
823 }
824
825 if (defined($acinit[3])) {
826# $name = $acinit[3];
827 if ($name =~ /\[(.*)\]/) {
828# $name = $1;
829 }
830 }
831 if (defined($acinit[1]) and $version eq $predef_version) {
832 my $ver = $acinit[1];
833 $ver =~ s/\[//g;
834 $ver =~ s/\]//g;
835 if ($ver =~ /\$/){} else {
836 $version = $ver;
837 $version =~ s/\s+//g;
838 }
839 }
840 }
841 if ($line =~ /AM_INIT_AUTOMAKE\((.*)\)/) {
842 my $match = $1;
843 $match =~ s/\s+/ /g;
844 @acinit = split(/,/, $match);
845# $name = $acinit[0];
846
847 if ($name =~ /\[(.*)\]/) {
848# $name = $1;
849 }
850
851 if (defined($acinit[3])) {
852# $name = $acinit[3];
853 if ($name =~ /\[(.*)\]/) {
854# $name = $1;
855 }
856 }
857 if (defined($acinit[1]) and $version eq $predef_version) {
858 my $ver = $acinit[1];
859 $ver =~ s/\[//g;
860 $ver =~ s/\]//g;
861 if ($ver =~ /\$/){} else {
862 $version = $ver;
863 $version =~ s/\s+//g;
864 }
865 }
866 }
867
868 $line = "";
869 }
870 close(CONFIGURE);
871}
872
873sub process_qmake_pro
874{
875 my ($filename) = @_;
876 my $line = "";
877 my $depth = 0;
878 my $keepgoing = 1;
879 my $buffer = "";
880 my $prev_char = "";
881
882 if (!-e $filename) {
883 return;
884 }
885
886
887 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
888 seek(CONFIGURE, 0,0) or die "seek : $!";
889 while ($keepgoing && !eof(CONFIGURE)) {
890 $buffer = getc(CONFIGURE);
891
892 if ($buffer eq "(") {
893 $depth = $depth + 1;
894 }
895 if ($buffer eq ")" && $depth > 0) {
896 $depth = $depth - 1;
897 }
898
899 if (!($buffer eq "\n")) {
900 $line = $line . $buffer;
901 }
902
903 if (!($buffer eq "\n") || ($prev_char eq "\\") ) {
904 $prev_char = $buffer;
905 redo unless eof(CONFIGURE);
906 }
907 $prev_char = " ";
908
909 if ($line =~ /PKGCONFIG.*?\=(.*)/) {
910 my $l = $1;
911 my @pkgs;
912
913 $l =~ s/\\//g;
914 $l =~ s/\s/ /g;
915 @pkgs = split(/ /, $l);
916 foreach (@pkgs) {
917 if (length($_)>1) {
918 push_pkgconfig_buildreq($_);
919 }
920 }
921 }
922
923 $line = "";
924 }
925 close(CONFIGURE);
926}
927
928#
929# We also check configure if it exists, it's nice for some things
930# because various configure.ac macros have been expanded for us already.
931#
932sub process_configure
933{
934 my ($filename) = @_;
935 my $line = "";
936 my $depth = 0;
937 my $keepgoing = 1;
938
939 if (!-e $filename) {
940 return;
941 }
942
943 $uses_configure = 1;
944
945 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
946 seek(CONFIGURE, 0,0) or die "seek : $!";
947 while ($keepgoing && !eof(CONFIGURE)) {
948 $buffer = getc(CONFIGURE);
949
950 if ($buffer eq "(") {
951 $depth = $depth + 1;
952 }
953 if ($buffer eq ")" && $depth > 0) {
954 $depth = $depth - 1;
955 }
956
957 if (!($buffer eq "\n")) {
958 $line = $line . $buffer;
959 }
960
961 if (!($buffer eq "\n") || $depth > 0) {
962 redo unless eof(CONFIGURE);
963 }
964
965
966
967 if ($line =~ /^PACKAGE_NAME=\'(.*?)\'/) {
968 $name = $1;
969 }
970 if ($line =~ /^PACKAGE_TARNAME=\'(.*?)\'/) {
971 $name = $1;
972 }
973 if ($line =~ /^PACKAGE_VERSION=\'(.*?)\'/) {
974 $version = $1;
975 $version =~ s/\s+//g;
976 }
977 if ($line =~ /^PACKAGE_URL=\'(.*?)\'/) {
978 if (length($1) > 2) {
979 $url = $1;
980 }
981 }
982
983
984 $line = "";
985 }
986 close(CONFIGURE);
987}
988
989sub print_pkgconfig
990{
991 my $count = @package_configs;
992 if ($count == 0) {
993 return;
994 }
995
996 uniquify_pkgconfig();
997
998 print OUTFILE "PkgConfigBR:\n";
999 foreach (@out) {
1000 $line = $_;
1001 $line =~ s/^\s+//g;
1002 if (length($line) > 1) {
1003 print OUTFILE " - $line\n";
1004 }
1005 }
1006}
1007
1008sub print_buildreq
1009{
1010 my $count = @buildreqs;
1011 if ($count == 0) {
1012 return;
1013 }
1014
1015 # remove dupes
1016 undef %saw;
1017 @saw{@buildreqs} = ();
1018 @out = sort keys %saw;
1019
1020 print OUTFILE "PkgBR:\n";
1021 foreach (@out) {
1022 print OUTFILE " - $_\n";
1023 }
1024}
1025
1026
1027# end of configure section
1028#
1029######################################################################
1030
1031
1032######################################################################
1033#
1034# Guessing the Description and Summary for a package
1035#
1036# We'll look at various sources of information for this:
1037# - spec files in the package
1038# - debain files in the package
1039# - DOAP files in the package
1040# - pkgconfig files in the package
1041# - the README file in the package
1042# - freshmeat.net online
1043#
1044
1045sub guess_description_from_spec {
1046 my ($specfile) = @_;
1047
1048 my $state = 0;
1049 my $cummul = "";
1050
1051 open(SPEC, $specfile);
1052 while (<SPEC>) {
1053 my $line = $_;
1054 if ($state == 1 && $line =~ /^\%/) {
1055 $state = 2;
1056 }
1057 if ($state == 1) {
1058 $cummul = $cummul . $line;
1059 }
1060 if ($state==0 && $line =~ /\%description/) {
1061 $state = 1;
1062 }
1063
1064 if ($line =~ /Summary:\s*(.*)/ && length($summary) < 2) {
1065 $summary = $1;
1066 }
1067 if ($line =~ /URL:\s*(.*)/ && length($url) < 2) {
1068 $url = $1;
1069 }
1070 }
1071 close(SPEC);
1072 if (length($cummul) > 4) {
1073 $description = $cummul;
1074 }
1075}
1076
1077#
1078# DOAP is a project to create an XML/RDF vocabulary to describe software projects, and in particular open source.
1079# so if someone ships a .doap file... we can learn from it.
1080#
1081sub guess_description_from_doap {
1082 my ($doapfile) = @_;
1083
1084 open(DOAP, $doapfile);
1085 while (<DOAP>) {
1086 my $line = $_;
1087 # <shortdesc xml:lang="en">Virtual filesystem implementation for gio</shortdesc>
1088 if ($line =~ /\<shortdesc .*?\>(.*)\<\/shortdesc\>/) {
1089 $summary = $1;
1090 }
1091 if ($line =~ /\<homepage .*?resource=\"(.*)\"\s*\/>/) {
1092 $url = $1;
1093 }
1094 }
1095 close(DOAP);
1096}
1097
1098#
1099# Debian control files have some interesting fields we can glean information
1100# from as well.
1101#
1102sub guess_description_from_debian_control {
1103 my ($file) = @_;
1104
1105 my $state = 0;
1106 my $cummul = "";
1107
1108 $file = $file . "/debian/control";
1109
1110 open(FILE, $file) || return;
1111 while (<FILE>) {
1112 my $line = $_;
1113 if ($state == 1 && length($line) < 2) {
1114 $state = 2;
1115 }
1116 if ($state == 1) {
1117 $cummul = $cummul . $line;
1118 }
1119 if ($state==0 && $line =~ /\Description: (.*)/) {
1120 $state = 1;
1121 $cummul = $1;
1122 }
1123
1124 }
1125 close(FILE);
1126 if (length($cummul) > 4) {
1127 $description = $cummul;
1128 }
1129}
1130
1131#
1132# the pkgconfig files have often a one line description
1133# of the software... good for Summary
1134#
1135sub guess_description_from_pkgconfig {
1136 my ($file) = @_;
1137
1138 open(FILE, $file);
1139 while (<FILE>) {
1140 my $line = $_;
1141
1142 if ($line =~ /Description:\s*(.*)/ && length($summary) < 2) {
1143 $summary = $1;
1144 }
1145 }
1146 close(FILE);
1147}
1148
1149#
1150# Freshmeat can provide us with a good one paragraph description
1151# of the software..
1152#
1153sub guess_description_from_freshmeat {
1154 my ($tarname) = @_;
1155 my $cummul = "";
1156 my $state = 0;
1157 open(HTML, "curl -s http://freshmeat.net/projects/$tarname |");
1158 while (<HTML>) {
1159 my $line = $_;
1160
1161 if ($state == 1) {
1162 $cummul = $cummul . $line;
1163 }
1164 if ($state == 0 && $line =~ /\<div class\=\"project-detail\"\>/) {
1165 $state = 1;
1166 }
1167 if ($state == 1 && $line =~/\<\/p\>/) {
1168 $state = 2;
1169 }
1170 }
1171 close(HTML);
1172 $cummul =~ s/\<p\>//g;
1173 $cummul =~ s/\r//g;
1174 $cummul =~ s/\<\/p\>//g;
1175 $cummul =~ s/^\s*//g;
1176 if (length($cummul)>10) {
1177 $description = $cummul;
1178 }
1179}
1180#
1181# If all else fails, just take the first paragraph of the
1182# readme file
1183#
1184sub guess_description_from_readme {
1185 my ($file) = @_;
1186
1187 my $state = 0;
1188 my $cummul = "";
1189
1190 open(FILE, $file);
1191 while (<FILE>) {
1192 my $line = $_;
1193 if ($state == 1 && $line =~ /^\n/ && length($cummul) > 80) {
1194 $state = 2;
1195 }
1196 if ($state == 0 && length($line)>1) {
1197 $state = 1;
1198 }
1199 if ($state == 1) {
1200 $cummul = $cummul . $line;
1201 }
1202 if ($line =~ /(http\:\/\/.*$name.*\.org)/) {
1203 my $u = $1;
1204 if ($u =~ /bug/ || length($url) > 1) {
1205 } else {
1206 $url = $u;
1207 }
1208 }
1209 }
1210 close(FILE);
1211 if (length($cummul) > 4 && length($description)<3) {
1212 $description = $cummul;
1213 }
1214}
1215
1216#
1217# Glue all the guesses together
1218#
1219sub guess_description {
1220 my ($directory) = @_;
1221
1222
1223 @files = <$directory/README*>;
1224 foreach (@files) {
1225 guess_description_from_readme($_);
1226 }
1227
1228 if (length($name)>2) {
1229 guess_description_from_freshmeat($name);
1230 }
1231
1232 @files = <$directory/*.spec*>;
1233 foreach (@files) {
1234 guess_description_from_spec($_);
1235 }
1236
1237 guess_description_from_debian_control($directory);
1238
1239 $name =~ s/ //g;
1240 @files = <$directory/$name.pc*>;
1241 foreach (@files) {
1242 guess_description_from_pkgconfig($_);
1243 }
1244 @files = <$directory/*.pc.*>;
1245 foreach (@files) {
1246 guess_description_from_pkgconfig($_);
1247 }
1248 @files = <$directory/*.pc>;
1249 foreach (@files) {
1250 guess_description_from_pkgconfig($_);
1251 }
1252 @files = <$directory/*.doap>;
1253 foreach (@files) {
1254 guess_description_from_doap($_);
1255 }
1256
1257 if (length($summary) < 2) {
1258 $summary = $description;
1259 $summary =~ s/\n/ /g;
1260 $summary =~ s/\s+/ /g;
1261 if ($summary =~ /(.*?)\./) {
1262 $summary = $1;
1263 }
1264 }
1265
1266}
1267
1268# end of Description / Summary section
1269#
1270######################################################################
1271
1272
1273
1274#
1275# Build the package, and wait for rpm to complain about unpackaged
1276# files.... which we then use as basis for our %files section
1277#
1278sub guess_files_from_rpmbuild {
1279 my $infiles = 0;
1280 open(OUTPUTF, "rpmbuild --nodeps --define \"\%_sourcedir $orgdir \" -ba $name.spec 2>&1 |");
1281 while (<OUTPUTF>) {
1282 my $line2 = $_;
1283
1284 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1285 $infiles = 2;
1286 }
1287 if ($infiles == 1 && $line2 =~ /^Building/) {
1288 $infiles = 2;
1289 }
1290
1291 if ($infiles == 1) {
1292 $line2 =~ s/\s*//g;
1293 push(@allfiles, $line2);
1294 }
1295 if ($line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1296 $infiles = 1;
1297 }
1298 }
1299 close(OUTPUTF);
1300 if (@allfiles == 0) {
1301 print "Build failed ... stopping here.\n";
1302 exit(0);
1303 }
1304
1305}
1306
1307sub guess_files_from_oscbuild {
1308 my $infiles = 0;
1309 my $restart = 0;
1310 my $mustrestart = 0;
1311 my $rcount = 0;
1312 my $done_python = 0;
1313
1314 system("osc addremove &> /dev/null");
1315 system("osc ci -m \"Initial import by autospectacle\" &> /dev/null");
1316
1317retry:
1318 if ($restart > 0) {
1319 write_yaml();
1320 print "Restarting the build\n";
1321 }
1322 $restart = 0;
1323 $infiles = 0;
1324 $mustrestart = 0;
1325 open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
1326 while (<OUTPUTF>) {
1327 my $line2 = $_;
1328
1329# print "line is $line2\n";
1330 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1331 $infiles = 2;
1332 }
1333 if ($infiles == 1 && $line2 =~ /^Building/) {
1334 $infiles = 2;
1335 }
1336 if ($infiles == 1) {
1337 $line2 =~ s/\s*//g;
1338 push(@allfiles, $line2);
1339 }
1340 if ($line2 =~ /No package \'(.*)\' found/) {
1341 push_pkgconfig_buildreq("$1");
1342 $restart = $restart + 1;
1343 print " Adding pkgconfig($1) requirement\n";
1344 }
1345 if ($line2 =~ /Package requirements \((.*?)\) were not met/) {
1346 $pkg = $1;
1347 # deal with versioned pkgconfig's by removing the spaces around >= 's
1348 $pkg =~ s/\>\=\s/\>\=/g;
1349 $pkg =~ s/\s\>\=/\>\=/g;
1350 $pkg =~ s/\=\s/\=/g;
1351 $pkg =~ s/\s\=/\=/g;
1352 my @req = split(/ /,$pkg);
1353 foreach (@req) {
1354 push_pkgconfig_buildreq("$_");
1355
1356 $restart = $restart + 1;
1357 print " Adding pkgconfig($_) requirement\n";
1358 }
1359 }
1360 if ($line2 =~ /which: no qmake/) {
1361 $restart += 1;
1362 push_pkgconfig_buildreq("Qt");
1363 print " Adding Qt requirement\n";
1364 }
1365 if ($line2 =~ /Cannot find development files for any supported version of libnl/) {
1366 $restart += 1;
1367 push_pkgconfig_buildreq("libnl-1");
1368 print " Adding libnl requirement\n";
1369 }
1370 if ($line2 =~ /<http:\/\/www.cmake.org>/) {
1371 $restart += 1;
1372 push(@buildreqs, "cmake");
1373 print " Adding cmake requirement\n";
1374 }
1375 if ($line2 =~ /checking for (.*?)\.\.\. not_found/ || $line2 =~ /checking for (.*?)\.\.\. no/ || $line2 =~ /checking (.*?)\.\.\. no/) {
1376 $pkg = $1;
1377 while (($key,$value) = each %failed_commands) {
1378 if ($pkg eq $key) {
1379 push(@buildreqs, $value);
1380 print " Adding $value requirement\n";
1381 $restart += $restart + 1;
1382 $mustrestart = 1;
1383 }
1384 }
1385
1386 }
1387
1388 if ($line2 =~ /checking for [a-zA-Z0-9\_]+ in (.*?)\.\.\. no/) {
1389 $pkg = $1;
1390 while (($key,$value) = each %failed_libs) {
1391 if ($pkg eq $key) {
1392 push(@buildreqs, $value);
1393 print " Adding $value requirement\n";
1394 $restart += $restart + 1;
1395 $mustrestart = 1;
1396 }
1397 }
1398
1399 }
1400
1401 if ($line2 =~ /-- Could NOT find ([a-zA-Z0-9]+)/) {
1402 $pkg = $1;
1403 while (($key,$value) = each %failed_libs) {
1404 if ($pkg eq $key) {
1405 push(@buildreqs, $value);
1406 print " Adding $value requirement\n";
1407 $restart += $restart + 1;
1408 $mustrestart = 1;
1409 }
1410 }
1411
1412 }
1413
1414 if ($line2 =~ /fatal error\: (.*)\: No such file or directory/) {
1415 $pkg = $1;
1416 while (($key,$value) = each %failed_headers) {
1417 if ($pkg eq $key) {
1418 push_pkgconfig_buildreq($value);
1419 print " Adding $value requirement\n";
1420 $restart += $restart + 1;
1421 }
1422 }
1423
1424 }
1425 if ($line2 =~ /checking for UDEV\.\.\. no/) {
1426 print " Adding pkgconfig(udev) requirement\n";
1427 push_pkgconfig_buildreq("udev");
1428 }
1429 if ($line2 =~ /checking for Apache .* module support/) {
1430 print " Adding pkgconfig(httpd-devel) requirement\n";
1431 push(@buildreqs, "httpd-devel");
1432 if ($rcount < 3) {
1433 $restart = $restart + 1;
1434 }
1435 }
1436 if ($line2 =~ /([a-zA-Z0-9\-\_]*)\: command not found/i) {
1437 my $cmd = $1;
1438 my $found = 0;
1439
1440 while (($key,$value) = each %failed_commands) {
1441 if ($cmd eq $key) {
1442 push(@buildreqs, $value);
1443 print " Adding $value requirement\n";
1444 $restart += $restart + 1;
1445 $mustrestart = 1;
1446 $found = 1;
1447 }
1448 }
1449
1450 if ($found < 1) {
1451 print " Command $cmd not found!\n";
1452 }
1453 }
1454 if ($line2 =~ /checking for.*in -ljpeg... no/) {
1455 push(@buildreqs, "libjpeg-devel");
1456 print " Adding libjpeg-devel requirement\n";
1457 $restart = $restart + 1;
1458 }
1459 if ($line2 =~ /fatal error\: zlib\.h\: No such file or directory/) {
1460 push(@buildreqs, "zlib-devel");
1461 print " Adding zlib-devel requirement\n";
1462 $restart = $restart + 1;
1463 }
1464 if ($line2 =~ /error\: xml2-config not found/) {
1465 push_pkgconfig_buildreq("libxml-2.0");
1466 print " Adding libxml2-devel requirement\n";
1467 $restart = $restart + 1;
1468 }
1469 if ($line2 =~ /checking \"location of ncurses\.h file\"/) {
1470 push(@buildreqs, "ncurses-devel");
1471 print " Adding ncurses-devel requirement\n";
1472 $restart = $restart + 1;
1473 }
1474 if (($line2 =~ / \/usr\/include\/python2\.6$/ || $line2 =~ / to compile python extensions/) && $done_python == 0) {
1475 push(@buildreqs, "python-devel");
1476 print " Adding python-devel requirement\n";
1477 $restart = $restart + 1;
1478 $done_python = 1;
1479 }
1480 if ($line2 =~ /error: must install xorg-macros 1.6/) {
1481 push_pkgconfig_buildreq("xorg-macros");
1482 print " Adding xorg-macros requirement\n";
1483 $restart = $restart + 1;
1484 }
1485 if ($line2 =~ /installing .*?.gmo as [a-zA-Z0-9\-\.\/\_]+?\/([a-zA-Z0-9\-\_\.]+)\.mo$/) {
1486 my $loc = $1;
1487 if ($loc eq $localename) {} else {
1488 print " Changing localename from $localename to $loc\n";
1489 $localename = $loc;
1490 $restart = $restart + 1;
1491 }
1492 }
1493
1494 if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1495 $infiles = 1;
1496 }
1497 }
1498 close(OUTPUTF);
1499 if (@allfiles == 0 || $mustrestart > 0) {
1500 if ($restart >= 1)
1501 {
1502 $rcount = $rcount + 1;
1503 if ($rcount < 10) {
1504 goto retry;
1505 }
1506 }
1507 print "Build failed ... stopping here.\n";
1508 exit(0);
1509 }
1510
1511}
1512
1513sub process_rpmlint {
1514 my $infiles = 0;
1515
1516
1517 if ($oscmode == 0) {
1518 return;
1519 }
1520
1521 print "Verifying package ....\n";
1522
1523 system("osc addremove &> /dev/null");
1524 system("osc ci -m \"Final import by autospectacle\" &> /dev/null");
1525
1526 open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
1527 while (<OUTPUTF>) {
1528 my $line2 = $_;
1529
1530# print "line is $line2\n";
1531 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1532 $infiles = 2;
1533 }
1534 if ($infiles == 1 && $line2 =~ /^Building/) {
1535 $infiles = 2;
1536 }
1537 if ($infiles == 1) {
1538 $line2 =~ s/\s*//g;
1539 push(@allfiles, $line2);
1540 }
1541 if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1542 $infiles = 1;
1543 }
1544 }
1545 close(OUTPUTF);
1546
1547}
1548
1549sub guess_name_from_url {
1550 my ($bigurl) = @_;
1551
1552 @spliturl = split(/\//, $bigurl);
1553 while (@spliturl > 1) {
1554 shift(@spliturl);
1555 }
1556 my $tarfile = $spliturl[0];
1557
1558 # Ensure correct name resolution from .zip&tgz archives
1559 $tarfile =~ s/\.zip/\.tar/;
1560 $tarfile =~ s/\.tgz/\.tar/;
1561 $tarfile =~ s/\_/\-/g;
1562 if ($tarfile =~ /(.*?)\-([0-9\.\-\~]+.*?)\.tar/) {
1563 $name = $1;
1564 $version = $2;
1565 $version =~ s/\-/\_/g;
1566 }
1567}
1568
1569############################################################################
1570#
1571# Output functions
1572#
1573
1574sub print_name_and_description
1575{
1576 my @lines;
1577
1578 print OUTFILE "Name : $name\n";
1579 print OUTFILE "Version : $version\n";
1580 print OUTFILE "Release : 1\n";
1581
1582 # remove dupes
1583 undef %saw;
1584 @saw{@groups} = ();
1585 @out = sort keys %saw;
1586
1587 if (@out == 1) {
1588 foreach (@out) {
1589 print OUTFILE "Group : $_\n";
1590 }
1591 } else {
1592 print OUTFILE "Group : $group\n";
1593 }
1594 #
1595 # Work around spectacle bug
1596 $summary =~ s/\:\s/ /g;
1597 $summary =~ s/^([a-z])/\u$1/ig;
1598 $summary =~ s/\@//g;
1599 $summary = substr($summary, 0, 79);
1600
1601 $summary =~ s/\.^//g;
1602 if (length($summary) < 1) {
1603 $summary = "TO BE FILLED IN";
1604 }
1605 #
1606 print OUTFILE "Summary : $summary\n";
1607 print OUTFILE "Description: |\n";
1608
1609 $description =~ s/&quot;/\"/g;
1610 $description =~ s/\@//g;
1611 @lines = split(/\n/, $description);
1612 foreach (@lines) {
1613 print OUTFILE " $_\n";
1614 }
1615 if (length($url)>1) {
1616 print OUTFILE "URL : $url\n";
1617 }
1618
1619 # remove dupes
1620 undef %saw;
1621 @saw{@sources} = ();
1622 @out = sort keys %saw;
1623
1624 print OUTFILE "Sources : \n";
1625 foreach (@out) {
1626 $source = $_;
1627 $source =~ s/$version/\%\{version\}/g;
1628
1629 print OUTFILE " - $source\n";
1630 }
1631
1632 if (@patches > 0) {
1633 print OUTFILE "Patches: \n";
1634 foreach (@patches) {
1635 my $patch = $_;
1636 print OUTFILE " - $patch\n";
1637 }
1638 }
1639
1640 print OUTFILE "\n";
1641 if (length($configure)>2) {
1642 print OUTFILE "Configure : $configure\n";
1643 }
1644 if (length($localename) > 2) {
1645 print OUTFILE "LocaleName : $localename\n";
1646 }
1647 if (length($builder) > 2) {
1648 print OUTFILE "Builder : $builder\n";
1649 }
1650}
1651
1652sub write_makefile
1653{
1654 open(MAKEFILE, ">Makefile");
1655
1656 print MAKEFILE "PKG_NAME := $name\n";
1657 print MAKEFILE "SPECFILE = \$(addsuffix .spec, \$(PKG_NAME))\n";
1658 print MAKEFILE "YAMLFILE = \$(addsuffix .yaml, \$(PKG_NAME))\n";
1659 print MAKEFILE "\n";
1660 print MAKEFILE "include /usr/share/packaging-tools/Makefile.common\n";
1661
1662 close(MAKEFILE);
1663}
1664
1665sub write_changelog
1666{
1667 open(CHANGELOG, ">$name.changes");
1668 $date = ` date +"%a %b %d %Y"`;
1669 chomp($date);
1670 print CHANGELOG "* $date - Autospectacle <autospectacle\@meego.com> - $version\n";
1671 print CHANGELOG "- Initial automated packaging\n";
1672 close(CHANGELOG);
1673}
1674
1675sub write_yaml
1676{
1677 open(OUTFILE, ">$name.yaml");
1678 print_name_and_description();
1679 print_license();
1680 print_pkgconfig();
1681 print_buildreq();
1682 print_files();
1683 print_devel();
1684 print_doc();
1685 close(OUTFILE);
1686
1687 write_makefile();
1688 write_changelog();
1689
1690 system("rm $name.spec 2>/dev/null");
1691 system("specify &> /dev/null");
1692 if ($oscmode > 0) {
1693 system("osc addremove");
1694 system("osc ci -m \"Import by autospectacle\" &> /dev/null");
1695 }
1696
1697}
1698
1699sub write_bbfile
1700{
1701 my $curdir = `pwd`;
1702 chomp($curdir);
1703
1704 if ($python == 1) {
1705 $name =~ s/python-//;
1706 $name = lc("python-" . $name);
1707 }
1708
1709 if (-e "$curdir/${name}_$version.bb") {
1710 print "Wont overwrite file:";
1711 print "$curdir/${name}_$version.bb, exiting\n";
1712 return;
1713 }
1714 open(BBFILE, ">${name}_$version.bb");
1715
1716 print BBFILE "SUMMARY = \"$summary\"\n";
1717 print BBFILE "DESCRIPTION = \"$description\"\n";
1718 print BBFILE "HOMEPAGE = \"$homepage\"\n";
1719
1720 if ($python == 1) {
1721 print BBFILE "SRCNAME = \"$summary\"\n";
1722 }
1723
1724 print BBFILE "LICENSE = \"@license\"\n";
1725 print BBFILE "LIC_FILES_CHKSUM = \"";
1726 foreach (keys %lic_files) {
1727 print BBFILE "file://" . basename($_) . ";md5=$lic_files{$_} \\\n";
1728 }
1729 print BBFILE "\"\n\n";
1730
1731 if (@license <= 0) {
1732 print "Can NOT get license from package source files.\n";
1733 print "Please update the LICENSE and LIC_FILES_CHKSUM manually.\n";
1734 }
1735
1736 if (@buildreqs > 0) {
1737 my %saw;
1738 my @out = grep(!$saw{$_}++,@buildreqs);
1739 print BBFILE "DEPENDS = \"@out\"\n\n";
1740 };
1741
1742 if (@rdepends > 0) {
1743 print BBFILE "RDEPENDS_\$\{PN\} += \"";
1744 foreach (@rdepends) {
1745 print BBFILE "$_ \\\n\t";
1746 }
1747 print BBFILE "\"\n";
1748 }
1749
1750 print BBFILE 'PR = "r0"' . "\n";
1751 if ($python == 1) {
1752 print BBFILE "PV = \"$pversion\"\n\n";
1753 }
1754
1755 print BBFILE "SRC_URI = \"";
1756 foreach (@sources) {
1757 print BBFILE "$_ \\\n";
1758 }
1759 print BBFILE "\"\n\n";
1760 print BBFILE "SRC_URI[md5sum] = \"$md5sum\"\n";
1761 print BBFILE "SRC_URI[sha256sum] = \"$sha256sum\"\n\n";
1762 if ($python == 1) {
1763 print BBFILE "S = \"\${WORKDIR}/\${SRCNAME}-\${PV}\"\n";
1764 }
1765
1766 if (@inherits) {
1767 print BBFILE "inherit ";
1768 foreach (@inherits) {
1769 print BBFILE "$_ ";
1770 }
1771 print BBFILE "\n";
1772 }
1773
1774 close(BBFILE);
1775 print "Create bb file: $curdir/${name}_$version.bb\n";
1776}
1777
1778sub calculate_sums
1779{
1780 @_ = basename $dir;
1781 my $md5output = `md5sum @_`;
1782 $md5output =~ /^([a-zA-Z0-9]*) /;
1783 $md5sum = $1;
1784 chomp($md5sum);
1785 my $sha256output = `sha256sum @_`;
1786 $sha256output =~ /^([a-zA-Z0-9]*) /;
1787 $sha256sum = $1;
1788 chomp($sha256sum);
1789}
1790
1791
1792############################################################################
1793#
1794# Main program
1795#
1796
1797if ( @ARGV < 1 || $ARGV[0] eq "--help" ) {
1798 print "Usage: $0 [-r] <url-of-source-tarballs>\n";
1799 exit(1);
1800}
1801
1802# Recusive parsing of python dependencies using
1803# easy_install
1804my $recurse_python = 0;
1805if ($ARGV[0] eq "-r") {
1806 $recurse_python = 1;
1807 shift @ARGV;
1808}
1809
1810if (@ARGV > 1) {
1811 my $i = 1;
1812 while ($i < @ARGV) {
1813 my $patch = $ARGV[$i];
1814 print "Adding patch $patch\n";
1815 push(@patches, $patch);
1816 $i++;
1817 }
1818}
1819
1820setup_licenses();
1821setup_files_rules();
1822setup_group_rules();
1823setup_pkgconfig_ban();
1824setup_failed_commands();
1825
1826if (-e ".osc/_packages") {
1827 $oscmode = 1;
1828}
1829
1830my $tmpdir = tempdir();
1831
1832$dir = $ARGV[0];
1833guess_name_from_url($dir);
1834push(@sources, $dir);
1835
1836#system("cd $tmpdir; curl -s -O $dir");
1837$orgdir = `pwd`;
1838chomp($orgdir);
1839my $outputdir = $name;
1840if (! $name) {
1841 $outputdir = basename $dir;
1842}
1843mkpath($outputdir);
1844chdir($outputdir);
1845print "Downloading package: $dir\n";
1846system("wget --quiet $dir") == 0 or die "Download $dir failed.";
1847
1848calculate_sums($outputdir);
1849
1850print "Unpacking to : $tmpdir\n";
1851
1852my @tgzfiles = <$orgdir/$outputdir/*.tgz>;
1853foreach (@tgzfiles) {
1854 my $tgz = basename $_;
1855 my $tar = $tgz;
1856 $tar =~ s/tgz/tar\.gz/g;
1857 $dir =~ s/tgz/tar\.gz/g;
1858 system("mv $orgdir/$outputdir/$tgz $orgdir/$outputdir/$tar");
1859 guess_name_from_url($dir);
1860}
1861
1862#
1863# I really really hate the fact that meego deleted the -a option from tar.
1864# this is a step backwards in time that is just silly.
1865#
1866
1867my @sourcetars = <$orgdir/$outputdir/*\.tar\.bz2 $orgdir/$outputdir/*\.tar\.gz $orgdir/$outputdir/*\.zip>;
1868if ( length @sourcetars == 0) {
1869 print "Can NOT find source tarball. Exiting...\n";
1870 exit (1);
1871}
1872if (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.tar\.bz2") {
1873 system("cd $tmpdir; tar -jxf $sourcetars[0] &>/dev/null");
1874} elsif (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.tar\.gz") {
1875 system("cd $tmpdir; tar -zxf $sourcetars[0] &>/dev/null");
1876} elsif (defined($sourcetars[0]) and $sourcetars[0] =~ ".*\.zip") {
1877 system("cd $tmpdir; unzip $sourcetars[0] &>/dev/null");
1878}
1879
1880print "Parsing content ....\n";
1881my @dirs = <$tmpdir/*>;
1882foreach (@dirs) {
1883 $dir = $_;
1884}
1885
1886$fulldir = $dir;
1887
1888if ( -e "$dir/setup.py" ) {
1889 $python = 1;
1890 $tmp_stools = `grep -r setuptools $dir/setup.py`;
1891 if (length($tmp_stools) > 2) {
1892 push(@inherits, "setuptools");
1893 } else {
1894 push(@inherits, "distutils");
1895 }
1896
1897 $templic = `cd $dir; python setup.py --license;`;
1898 $templic =~ s/[\r\n]+//g;
1899 push(@license, $templic);
1900 $summary = `cd $dir; python setup.py --name`;
1901 $summary =~ s/[\r\n]+//g;
1902 $description = `cd $dir; python setup.py --description`;
1903 $description =~ s/[\r\n]+//g;
1904 $homepage = `cd $dir; python setup.py --url`;
1905 $homepage =~ s/[\r\n]+//g;
1906 $pversion = `cd $dir; python setup.py -V`;
1907 $pversion =~ s/[\r\n]+//g;
1908# $findoutput = `cd $dir; python setup.py --requires`;
1909# if (length($findoutput) < 3) {
1910 $findoutput = `find $dir/*.egg-info/ -name "requires.txt" 2>/dev/null`;
1911# }
1912 @findlist = split(/\n/, $findoutput);
1913 foreach (@findlist) {
1914 push(@rawpythondeps, `sed -e '/^\$/d' "$_" | sed '/^\\[/d'`);
1915 chomp(@rawpythondeps);
1916 push(@rdepends, `sed -e 's/python-//g' "$_" | sed '/^\\[/d'`);
1917 chomp(@rdepends);
1918 if ($recurse_python == 1) {
1919 foreach (@rawpythondeps) {
1920 my $ptempdir = tempdir();
1921 $purl = `easy_install -aeb $ptempdir "$_" 2>/dev/null`;
1922 $purl =~ s/#.*//g;
1923 @purllist = $purl =~ m/Downloading (.*:\/\/.*\n)/g;
1924 chomp(@purllist);
1925
1926 # Remove empty lines
1927 @purllist = grep(/\S/, @purllist);
1928
1929 # Recursively create recipes for dependencies
1930 if (@purllist != 0) {
1931 if (fork) {
1932 # Parent, do nothing
1933 } else {
1934 # child, execute
1935 print "Recursively creating recipe for: $purllist[0]\n";
1936 exec("cd .. ; create-recipe -r $purllist[0]");
1937 }
1938 }
1939 }
1940 wait;
1941 }
1942
1943 foreach $item (@rdepends) {
1944 @pyclean = split(/(\=|\<|\>).*/, $item);
1945 if (defined($pyclean[0])) {
1946 $item = lc("python-" . $pyclean[0]);
1947 }
1948 }
1949 }
1950}
1951
1952if ( -e "$dir/autogen.sh" ) {
1953 $configure = "autogen";
1954 $uses_configure = 1;
1955 push(@inherits, "autotools");
1956}
1957if ( -e "$dir/BUILD-CMAKE" ) {
1958 $configure = "cmake";
1959 push(@buildreqs, "cmake");
1960 $uses_configure = 1;
1961 push(@inherits, "cmake");
1962}
1963
1964if ( -e "$dir/configure" ) {
1965 $configure = "";
1966}
1967
1968my @files = <$dir/configure\.*>;
1969
1970my $findoutput = `find $dir -name "configure.ac" 2>/dev/null`;
1971my @findlist = split(/\n/, $findoutput);
1972foreach (@findlist) {
1973 push(@files, $_);
1974}
1975foreach (@files) {
1976 process_configure_ac("$_");
1977}
1978
1979$findoutput = `find $dir -name "*.pro" 2>/dev/null`;
1980@findlist = split(/\n/, $findoutput);
1981foreach (@findlist) {
1982 process_qmake_pro("$_");
1983}
1984
1985if (-e "$dir/$name.pro") {
1986 $builder = "qmake";
1987 push_pkgconfig_buildreq("Qt");
1988 push(@inherits, "qmake2");
1989}
1990
1991#
1992# This is a good place to generate configure.in
1993#
1994if (length($configure) > 2) {
1995 if ($configure eq "autogen") {
1996 system("cd $dir ; ./autogen.sh &> /dev/null");
1997 }
1998}
1999
2000
2001@files = <$dir/configure>;
2002foreach (@files) {
2003 process_configure("$_");
2004}
2005
2006if ($uses_configure == 0) {
2007 $configure = "none";
2008}
2009
2010@files = <$dir/docs/license.txt>;
2011foreach (@files) {
2012 guess_license_from_file("$_");
2013}
2014
2015@files = <$dir/COPY*>;
2016foreach (@files) {
2017 guess_license_from_file("$_");
2018}
2019
2020@files = <$dir/LICENSE*>;
2021foreach (@files) {
2022 guess_license_from_file("$_");
2023}
2024
2025
2026@files = <$dir/GPL*>;
2027foreach (@files) {
2028 guess_license_from_file("$_");
2029}
2030
2031
2032if ($python != 1) {
2033 guess_description($dir);
2034}
2035
2036#
2037# Output of bbfile file
2038#
2039write_bbfile();
2040chdir($orgdir);
2041exit 0;
2042
2043#
2044# Output of the yaml file
2045#
2046
2047
2048if ($oscmode == 1) {
2049 print "Creating OBS project $name ...\n";
2050 system("osc mkpac $name &> /dev/null");
2051 system("mkdir $name &> /dev/null");
2052 chdir($name);
2053 system("mv ../$name*\.tar\.* .");
2054}
2055
2056write_yaml();
2057print "Building package ....\n";
2058
2059if ($oscmode == 0) {
2060 guess_files_from_rpmbuild();
2061} else {
2062 guess_files_from_oscbuild();
2063}
2064
2065apply_files_rules();
2066
2067$printed_subpackages = 0;
2068write_yaml();
2069
2070process_rpmlint();
2071
2072print "Spectacle creation complete.\n";
diff --git a/scripts/crosstap b/scripts/crosstap
new file mode 100755
index 0000000000..58317cf91c
--- /dev/null
+++ b/scripts/crosstap
@@ -0,0 +1,148 @@
1#!/bin/bash
2#
3# Run a systemtap script on remote target
4#
5# Examples (run on build host, target is 192.168.1.xxx):
6# $ source oe-init-build-env"
7# $ cd ~/my/systemtap/scripts"
8#
9# $ crosstap root@192.168.1.xxx myscript.stp"
10# $ crosstap root@192.168.1.xxx myscript-with-args.stp 99 ninetynine"
11#
12# Copyright (c) 2012, Intel Corporation.
13# All rights reserved.
14#
15# This program is free software; you can redistribute it and/or modify
16# it under the terms of the GNU General Public License version 2 as
17# published by the Free Software Foundation.
18#
19# This program is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22# See the GNU General Public License for more details.
23#
24# You should have received a copy of the GNU General Public License
25# along with this program; if not, write to the Free Software
26# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28function usage() {
29 echo "Usage: $0 <user@hostname> <sytemtap-script> [additional systemtap-script args]"
30}
31
32function setup_usage() {
33 echo ""
34 echo "'crosstap' requires a local sdk build of the target system"
35 echo "(or a build that includes 'tools-profile') in order to build"
36 echo "kernel modules that can probe the target system."
37 echo ""
38 echo "Practically speaking, that means you need to do the following:"
39 echo " - If you're running a pre-built image, download the release"
40 echo " and/or BSP tarballs used to build the image."
41 echo " - If you're working from git sources, just clone the metadata"
42 echo " and BSP layers needed to build the image you'll be booting."
43 echo " - Make sure you're properly set up to build a new image (see"
44 echo " the BSP README and/or the widely available basic documentation"
45 echo " that discusses how to build images)."
46 echo " - Build an -sdk version of the image e.g.:"
47 echo " $ bitbake core-image-sato-sdk"
48 echo " OR"
49 echo " - Build a non-sdk image but include the profiling tools:"
50 echo " [ edit local.conf and add 'tools-profile' to the end of"
51 echo " the EXTRA_IMAGE_FEATURES variable ]"
52 echo " $ bitbake core-image-sato"
53 echo ""
54 echo " [ NOTE that 'crosstap' needs to be able to ssh into the target"
55 echo " system, which isn't enabled by default in -minimal images. ]"
56 echo ""
57 echo "Once you've build the image on the host system, you're ready to"
58 echo "boot it (or the equivalent pre-built image) and use 'crosstap'"
59 echo "to probe it (you need to source the environment as usual first):"
60 echo ""
61 echo " $ source oe-init-build-env"
62 echo " $ cd ~/my/systemtap/scripts"
63 echo " $ crosstap root@192.168.1.xxx myscript.stp"
64 echo ""
65}
66
67function systemtap_target_arch() {
68 SYSTEMTAP_TARGET_ARCH=$1
69 case $SYSTEMTAP_TARGET_ARCH in
70 i?86)
71 SYSTEMTAP_TARGET_ARCH="i386"
72 ;;
73 x86?64*)
74 SYSTEMTAP_TARGET_ARCH="x86_64"
75 ;;
76 arm*)
77 SYSTEMTAP_TARGET_ARCH="arm"
78 ;;
79 powerpc*)
80 SYSTEMTAP_TARGET_ARCH="powerpc"
81 ;;
82 *)
83 ;;
84 esac
85}
86
87if [ $# -lt 2 ]; then
88 usage
89 exit 1
90fi
91
92if [ -z "$BUILDDIR" ]; then
93 echo "Error: Unable to find the BUILDDIR environment variable."
94 echo "Did you forget to source your build system environment setup script?"
95 exit 1
96fi
97
98pushd $PWD
99cd $BUILDDIR
100BITBAKE_VARS=`bitbake -e virtual/kernel`
101popd
102
103STAGING_BINDIR_TOOLCHAIN=$(echo "$BITBAKE_VARS" | grep ^STAGING_BINDIR_TOOLCHAIN \
104 | cut -d '=' -f2 | cut -d '"' -f2)
105STAGING_BINDIR_TOOLPREFIX=$(echo "$BITBAKE_VARS" | grep ^TARGET_PREFIX \
106 | cut -d '=' -f2 | cut -d '"' -f2)
107SYSTEMTAP_HOST_INSTALLDIR=$(echo "$BITBAKE_VARS" | grep ^STAGING_DIR_NATIVE \
108 | cut -d '=' -f2 | cut -d '"' -f2)
109TARGET_ARCH=$(echo "$BITBAKE_VARS" | grep ^TRANSLATED_TARGET_ARCH \
110 | cut -d '=' -f2 | cut -d '"' -f2)
111TARGET_KERNEL_BUILDDIR=$(echo "$BITBAKE_VARS" | grep ^B= \
112 | cut -d '=' -f2 | cut -d '"' -f2)
113
114systemtap_target_arch "$TARGET_ARCH"
115
116if [ ! -d $TARGET_KERNEL_BUILDDIR ] ||
117 [ ! -f $TARGET_KERNEL_BUILDDIR/vmlinux ]; then
118 echo -e "\nError: No target kernel build found."
119 echo -e "Did you forget to create a local build of your image?"
120 setup_usage
121 exit 1
122fi
123
124if [ ! -f $SYSTEMTAP_HOST_INSTALLDIR/usr/bin/stap ]; then
125 echo -e "\nError: Native (host) systemtap not found."
126 echo -e "Did you accidentally build a local non-sdk image? (or forget to"
127 echo -e "add 'tools-profile' to EXTRA_IMAGE_FEATURES in your local.conf)?"
128 setup_usage
129 exit 1
130fi
131
132target_user_hostname="$1"
133full_script_name="$2"
134script_name=$(basename "$2")
135script_base=${script_name%.*}
136shift 2
137
138${SYSTEMTAP_HOST_INSTALLDIR}/usr/bin/stap \
139 -a ${SYSTEMTAP_TARGET_ARCH} \
140 -B CROSS_COMPILE="${STAGING_BINDIR_TOOLCHAIN}/${STAGING_BINDIR_TOOLPREFIX}" \
141 -r ${TARGET_KERNEL_BUILDDIR} \
142 -I ${SYSTEMTAP_HOST_INSTALLDIR}/usr/share/systemtap/tapset \
143 -R ${SYSTEMTAP_HOST_INSTALLDIR}/usr/share/systemtap/runtime \
144 --remote=$target_user_hostname \
145 -m $script_base \
146 $full_script_name "$@"
147
148exit 0
diff --git a/scripts/gen-site-config b/scripts/gen-site-config
new file mode 100755
index 0000000000..7da7a0bd8a
--- /dev/null
+++ b/scripts/gen-site-config
@@ -0,0 +1,53 @@
1#! /bin/sh
2# Copyright (c) 2005-2008 Wind River Systems, Inc.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License version 2 as
6# published by the Free Software Foundation.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17cat << EOF
18AC_PREREQ(2.57)
19AC_INIT([site_wide],[1.0.0])
20
21EOF
22
23# Disable as endian is set in the default config
24#echo AC_C_BIGENDIAN
25#echo
26
27if [ -e $1/types ] ; then
28 while read type ; do
29 echo "AC_CHECK_SIZEOF([$type])"
30 done < $1/types
31
32 echo
33fi
34
35if [ -e $1/funcs ]; then
36 while read func ; do
37 echo "AC_CHECK_FUNCS([$func])"
38 done < $1/funcs
39
40 echo
41fi
42
43if [ -e $1/headers ]; then
44 while read header ; do
45 echo "AC_CHECK_HEADERS([$header])"
46 done < $1/headers
47
48 echo
49fi
50
51cat << EOF
52AC_OUTPUT
53EOF
diff --git a/scripts/help2man b/scripts/help2man
new file mode 100755
index 0000000000..2bb8d868bd
--- /dev/null
+++ b/scripts/help2man
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3exit 1
diff --git a/scripts/hob b/scripts/hob
new file mode 100755
index 0000000000..8d33ab1782
--- /dev/null
+++ b/scripts/hob
@@ -0,0 +1,6 @@
1#!/usr/bin/env bash
2export BB_ENV_EXTRAWHITE="DISABLE_SANITY_CHECKS $BB_ENV_EXTRAWHITE"
3DISABLE_SANITY_CHECKS=1 bitbake -u hob $@
4
5ret=$?
6exit $ret
diff --git a/scripts/jhbuild/jhbuild2oe.py b/scripts/jhbuild/jhbuild2oe.py
new file mode 100755
index 0000000000..9b31cafb69
--- /dev/null
+++ b/scripts/jhbuild/jhbuild2oe.py
@@ -0,0 +1,278 @@
1#!/usr/bin/env python
2# Available modulesets:
3#
4# bootstrap.modules
5# freedesktop.modules
6# gcj.modules
7# gnome-2.10.modules
8# gnome-2.12.modules
9# gnome-2.14.modules
10# gnome-2.16.modules
11# gnutls.modules
12# gtk28.modules
13# gtk.modules
14# xorg-7.0.modules
15# xorg.modules
16
17moduleset = 'xorg.modules'
18
19
20
21import cElementTree as ElementTree
22# import lxml.etree as ElementTree
23import re, os, bb, bb.data
24
25class Handlers(object):
26 """
27 Class to act as a store for handlers of jhbuild xml elements, and as a
28 dispatcher of parsed Elements to those handlers.
29
30 These handlers exist to take an xml element from the jhbuild files and
31 either produce bitbake metadata in self.packages, or produce data which
32 will be used by other element handlers to do so.
33
34 Handlers(filename) -> new object to parse and process jhbuild file of
35 name 'filename'.
36 """
37
38 cvsrootpat = re.compile(r'''
39 \s* # Skip leading whitespace
40 :(?P<scheme>[^:]+): # scheme (i.e. pserver, ext)
41 ((?P<user>\S+?)@)? # username
42 (?P<host>\S+?): # non-greedy match of the remote host
43 (?P<path>\S+) # remote path
44 ''', re.VERBOSE)
45
46
47 def __init__(self, msfile):
48 self.msfile = msfile
49 self.msbasename = os.path.basename(msfile)
50 self.msdirname = os.path.dirname(msfile)
51
52 self.handled = {}
53
54 self.cvsroots = {}
55 self.repositories = {}
56 self.packages = []
57
58 def handle(self, element, parent):
59 import sys
60 """
61 XML Element dispatch function. Can be called both from outside the
62 Handlers object to initiate handling, and from within individual XML
63 element handlers to ensure that dependent elements have been handled.
64
65 Does not handle a given XML Element more than once, as it retains
66 information about the handling state of the Elements it encounters.
67 """
68
69 try:
70 state = self.handled[element]
71 except KeyError:
72 pass
73 except:
74 return
75
76 try:
77 self.__class__.__dict__[element.tag](self, element, parent)
78 self.handled[element] = True
79 except KeyError:
80 self.handled[element] = False
81 sys.__stderr__.write('Unhandled element: %s\n' % element.tag)
82 except Exception:
83 sys.__stderr__.write('Error handling %s: %s:\n %s\n' % (element.tag, sys.exc_type, sys.exc_value))
84 self.handled[element] = False
85
86 print('handle(%s, %s) -> %s' % (element, parent, self.handled[element]))
87 return self.handled[element]
88
89 def cvsroot(self, element, parent):
90 # Rip apart the cvsroot style location to build a cvs:// url for
91 # bitbake's usage in the cvsmodule handler.
92 # root=":pserver:anoncvs@cvs.freedesktop.org:/cvs/fontconfig"
93 print("cvsroot(%s, %s)" % (element, parent))
94
95 root = element.attrib.get('root')
96 rootmatch = re.match(Handlers.cvsrootpat, root)
97 name = element.attrib.get('name')
98 user = rootmatch.group('user') or ''
99 if user != '':
100 pw = element.attrib.get('password') or ''
101 if pw != '':
102 pw = ':' + pw + '@'
103 else:
104 user = user + '@'
105 print('user: %s' % user)
106 print('pw: %s' % pw)
107
108 host = rootmatch.group('host')
109 print('host: %s' % host)
110 path = rootmatch.group('path') or '/'
111 print('path: %s' % path)
112
113 root = "cvs://%s%s%s%s" % (user, pw, host, path)
114 print('root: %s' % root)
115 self.cvsroots[name] = root
116
117 def cvsmodule(self, element, parent):
118 rootlist = [root for root in list(parent) if root.attrib.get('name') == element.attrib.get('cvsroot')]
119 if len(rootlist) < 1:
120 raise Exception("Error: cvsmodule '%s' requires cvsroot '%s'." % (element.attrib.get('module'), element.attrib.get('cvsroot')))
121
122 cvsroot = rootlist[0]
123
124
125 def include(self, element, parent):
126 href = element.attrib.get('href')
127 fullhref = os.path.join(self.msdirname, href)
128 tree = ElementTree.ElementTree(file=fullhref)
129 elem = tree.getroot()
130
131 # Append the children of the newly included root element to the parent
132 # element, and manually handle() them, as the currently running
133 # iteration isn't going to hit them.
134 for child in elem:
135 self.handle(child, elem)
136 parent.append(elem)
137
138 def repository(self, element, parent):
139 # TODO:
140 # Convert the URL in the href attribute, if necessary, to the format
141 # which bitbake expects to see in SRC_URI.
142 name = element.attrib.get('name')
143 self.repositories[name] = element.attrib.get('href')
144
145
146 def moduleset(self, element, parent):
147 for child in element:
148 self.handle(child, element)
149
150 def packagename(self, name):
151 # mangle name into an appropriate bitbake package name
152 return name.replace('/', '-')
153
154 def metamodule(self, element, parent):
155 # grab the deps
156 deps = None
157 for child in element:
158 if child.tag == 'dependencies':
159 deps = [self.packagename(dep.attrib.get('package')) for dep in child if dep.tag == "dep"]
160
161 # create the package
162 d = bb.data.init()
163 pn = self.packagename(element.attrib.get('id'))
164 d.setVar('PN', pn)
165 bb.data.setVar('DEPENDS', ' '.join(deps), d)
166 d.setVar('_handler', 'metamodule')
167 self.packages.append(d)
168
169 def autotools(self, element, parent):
170 deps = None
171 branch = None
172 for child in element:
173 if child.tag == 'dependencies':
174 deps = [self.packagename(dep.attrib.get('package')) for dep in child if dep.tag == "dep"]
175 elif child.tag == 'branch':
176 branch = child
177
178 # create the package
179 d = bb.data.init()
180 id = element.attrib.get('id')
181 if id is None:
182 raise Exception('Error: autotools element has no id attribute.')
183 pn = self.packagename(id)
184 d.setVar('PN', pn)
185 if deps is not None:
186 bb.data.setVar('DEPENDS', ' '.join(deps), d)
187
188 if branch is not None:
189 # <branch repo="git.freedesktop.org" module="xorg/xserver"/>
190 repo = os.path.join(self.repositories[branch.attrib.get('repo')], branch.attrib.get('module'))
191 d.setVar('SRC_URI', repo)
192
193 checkoutdir = branch.attrib.get('checkoutdir')
194 if checkoutdir is not None:
195 bb.data.setVar('S', os.path.join('${WORKDIR}', checkoutdir), d)
196
197 # build class
198 d.setVar('INHERITS', 'autotools')
199 d.setVarFlag('INHERITS', 'operator', '+=')
200 d.setVar('_handler', 'autotools')
201 self.packages.append(d)
202
203class Emitter(object):
204 """
205 Class which contains a single method for the emission of a bitbake
206 package from the bitbake data produced by a Handlers object.
207 """
208
209 def __init__(self, filefunc = None, basedir = None):
210 def _defaultfilefunc(package):
211 # return a relative path to the bitbake .bb which will be written
212 return package.getVar('PN', 1) + '.bb'
213
214 self.filefunc = filefunc or _defaultfilefunc
215 self.basedir = basedir or os.path.abspath(os.curdir)
216
217 def write(self, package, template = None):
218 # 1) Assemble new file contents in ram, either new from bitbake
219 # metadata, or a combination of the template and that metadata.
220 # 2) Open the path returned by the filefunc + the basedir for writing.
221 # 3) Write the new bitbake data file.
222 fdata = ''
223 if template:
224 f = file(template, 'r')
225 fdata = f.read()
226 f.close()
227
228 for key in bb.data.keys(package):
229 fdata = fdata.replace('@@'+key+'@@', package.getVar(key))
230 else:
231 for key in bb.data.keys(package):
232 if key == '_handler':
233 continue
234 elif key == 'INHERITS':
235 fdata += 'inherit %s\n' % package.getVar('INHERITS')
236 else:
237 oper = package.getVarFlag(key, 'operator') or '='
238 fdata += '%s %s "%s"\n' % (key, oper, package.getVar(key))
239
240 if not os.path.exists(os.path.join(self.basedir, os.path.dirname(self.filefunc(package)))):
241 os.makedirs(os.path.join(self.basedir, os.path.dirname(self.filefunc(package))))
242
243 out = file(os.path.join(self.basedir, self.filefunc(package)), 'w')
244 out.write(fdata)
245 out.close()
246
247def _test():
248 msfile = os.path.join(os.path.abspath(os.curdir), 'modulesets', moduleset)
249 tree = ElementTree.ElementTree(file=msfile)
250 elem = tree.getroot()
251
252 handlers = Handlers(msfile)
253 handlers.handle(elem, None)
254
255 def filefunc(package):
256 # return a relative path to the bitbake .bb which will be written
257 src_uri = package.getVar('SRC_URI', 1)
258 filename = package.getVar('PN', 1) + '.bb'
259 if not src_uri:
260 return filename
261 else:
262 substr = src_uri[src_uri.find('xorg/'):]
263 subdirlist = substr.split('/')[:2]
264 subdir = '-'.join(subdirlist)
265 return os.path.join(subdir, filename)
266
267 emitter = Emitter(filefunc)
268 for package in handlers.packages:
269 template = emitter.filefunc(package) + '.in'
270 if os.path.exists(template):
271 print("%s exists, emitting based on template" % template)
272 emitter.write(package, template)
273 else:
274 print("%s does not exist, emitting non-templated" % template)
275 emitter.write(package)
276
277if __name__ == "__main__":
278 _test()
diff --git a/scripts/jhbuild/modulesets/bootstrap.modules b/scripts/jhbuild/modulesets/bootstrap.modules
new file mode 100644
index 0000000000..9096b14662
--- /dev/null
+++ b/scripts/jhbuild/modulesets/bootstrap.modules
@@ -0,0 +1,87 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="tarball" name="ftp.gnu.org"
5 href="http://ftp.gnu.org/gnu/"/>
6 <repository type="tarball" name="pkgconfig"
7 href="http://pkgconfig.freedesktop.org/releases/"/>
8 <repository type="tarball" name="python"
9 href="http://www.python.org/ftp/python/"/>
10
11 <autotools id="gettext" autogen-sh="configure">
12 <branch repo="ftp.gnu.org"
13 module="gettext/gettext-0.14.5.tar.gz" version="0.14.5"
14 size="7105715" md5sum="e2f6581626a22a0de66dce1d81d00de3" />
15 </autotools>
16
17 <autotools id="autoconf" autogen-sh="configure">
18 <branch repo="ftp.gnu.org"
19 module="autoconf/autoconf-2.59.tar.bz2" version="2.59"
20 size="925073" md5sum="1ee40f7a676b3cfdc0e3f7cd81551b5f" />
21 </autotools>
22
23 <autotools id="libtool" autogen-sh="configure">
24 <branch repo="ftp.gnu.org"
25 module="libtool/libtool-1.5.22.tar.gz" version="1.5.22"
26 size="2921483" md5sum="8e0ac9797b62ba4dcc8a2fb7936412b0">
27 <patch file="libtool-1.5.18-multilib.patch" strip="1" />
28 </branch>
29 </autotools>
30
31 <autotools id="automake-1.4" autogen-sh="configure">
32 <branch repo="ftp.gnu.org"
33 module="automake/automake-1.4-p6.tar.gz" version="1.4-p6"
34 size="375060" md5sum="24872b81b95d78d05834c39af2cfcf05" />
35 </autotools>
36 <autotools id="automake-1.7" autogen-sh="configure">
37 <branch repo="ftp.gnu.org"
38 module="automake/automake-1.7.9.tar.bz2" version="1.7.9"
39 size="577705" md5sum="571fd0b0598eb2a27dcf68adcfddfacb" />
40 </autotools>
41 <autotools id="automake-1.8" autogen-sh="configure">
42 <branch repo="ftp.gnu.org"
43 module="automake/automake-1.8.5.tar.bz2" version="1.8.5"
44 size="663182" md5sum="0114aa6d7dc32112834b68105fb8d7e2" />
45 </autotools>
46 <autotools id="automake-1.9" autogen-sh="configure">
47 <branch repo="ftp.gnu.org"
48 module="automake/automake-1.9.6.tar.bz2" version="1.9.6"
49 size="765505" md5sum="c11b8100bb311492d8220378fd8bf9e0" />
50 </autotools>
51
52 <autotools id="pkg-config" autogen-sh="configure">
53 <branch repo="pkgconfig"
54 module="pkg-config-0.20.tar.gz" version="0.20"
55 size="969993" md5sum="fb42402593e4198bc252ab248dd4158b" />
56 </autotools>
57
58 <autotools id="python" autogenargs="--enable-shared" autogen-sh="configure">
59 <branch repo="python"
60 module="2.4.3/Python-2.4.3.tar.bz2" version="2.4.3"
61 size="8005915" md5sum="141c683447d5e76be1d2bd4829574f02" />
62 </autotools>
63
64 <repository type="tarball" name="pyrex"
65 href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/"/>
66 <distutils id="pyrex">
67 <branch repo="pyrex"
68 module="Pyrex-0.9.4.1.tar.gz" version="0.9.4.1"
69 size="181507" md5sum="425f0543c634bc7a86fe4fce02e0e882" />
70 </distutils>
71
72 <metamodule id="meta-bootstrap">
73 <dependencies>
74 <dep package="gettext" />
75 <dep package="autoconf" />
76 <dep package="libtool" />
77 <dep package="automake-1.4" />
78 <dep package="automake-1.7" />
79 <dep package="automake-1.8" />
80 <dep package="automake-1.9" />
81 <dep package="pkg-config" />
82 <dep package="python" />
83 <dep package="pyrex" />
84 </dependencies>
85 </metamodule>
86
87</moduleset>
diff --git a/scripts/jhbuild/modulesets/freedesktop.modules b/scripts/jhbuild/modulesets/freedesktop.modules
new file mode 100644
index 0000000000..698853e377
--- /dev/null
+++ b/scripts/jhbuild/modulesets/freedesktop.modules
@@ -0,0 +1,281 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="cairo.freedesktop.org"
5 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/cairo"
6 password=""/>
7 <repository type="cvs" name="dbus.freedesktop.org"
8 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/dbus"
9 password=""/>
10 <repository type="cvs" name="fontconfig.freedesktop.org"
11 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/fontconfig"
12 password=""/>
13 <repository type="cvs" name="hal.freedesktop.org"
14 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/hal"
15 password=""/>
16 <repository type="cvs" name="icon-theme.freedesktop.org"
17 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/icon-theme"
18 password=""/>
19 <repository type="cvs" name="startup-notification.freedesktop.org"
20 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/startup-notification"
21 password=""/>
22 <repository type="cvs" name="tango.freedesktop.org"
23 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/tango"
24 password=""/>
25 <repository type="cvs" name="xorg.freedesktop.org"
26 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/xorg"
27 password=""/>
28 <repository type="cvs" name="poppler.freedesktop.org"
29 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/poppler"
30 password=""/>
31 <repository type="cvs" name="system-tools-backends.freedesktop.org"
32 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/system-tools-backends"
33 password=""/>
34 <repository type="cvs" name="gnome.org"
35 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
36 password=""/>
37
38 <repository type="svn" name="avahi.0pointer.de"
39 href="svn://svn.0pointer.de/avahi/"/>
40 <repository type="svn" name="libdaemon.0pointer.de"
41 href="svn://svn.0pointer.de/libdaemon/"/>
42
43 <repository type="git" name="git.freedesktop.org"
44 href="git://anongit.freedesktop.org/git/"/>
45
46 <repository type="tarball" name="cpan" href="http://search.cpan.org/CPAN/" />
47
48
49 <autotools id="cairo">
50 <branch repo="git.freedesktop.org" module="cairo"/>
51 <dependencies>
52 <dep package="fontconfig"/>
53 <dep package="libXrender"/>
54 <dep package="gtk-doc"/>
55 </dependencies>
56 <after>
57 <dep package="glitz"/>
58 </after>
59 </autotools>
60
61 <tarball id="cairo-1-0" version="1.0.4">
62 <source href="http://cairographics.org/releases/cairo-1.0.4.tar.gz"
63 size="1475777" md5sum="9002b0e69b3f94831a22d3f2a7735ce2"/>
64 <dependencies>
65 <dep package="fontconfig"/>
66 <dep package="libXrender"/>
67 </dependencies>
68 <after>
69 <dep package="glitz"/>
70 </after>
71 </tarball>
72
73 <autotools id="glitz">
74 <branch repo="cairo.freedesktop.org"/>
75 </autotools>
76
77 <autotools id="pycairo-1-0">
78 <branch repo="cairo.freedesktop.org" module="pycairo"
79 revision="RELEASE_1_0_2" checkoutdir="pycairo-1-0"/>
80 <dependencies>
81 <dep package="cairo-1-0"/>
82 </dependencies>
83 </autotools>
84
85 <autotools id="pycairo">
86 <branch repo="cairo.freedesktop.org"/>
87 <dependencies>
88 <dep package="cairo"/>
89 </dependencies>
90 </autotools>
91
92 <autotools id="cairomm">
93 <branch repo="cairo.freedesktop.org"/>
94 <dependencies>
95 <dep package="cairo"/>
96 </dependencies>
97 </autotools>
98
99 <autotools id="dbus" supports-non-srcdir-builds="no">
100 <branch repo="dbus.freedesktop.org"/>
101 <dependencies>
102 <dep package="glib"/>
103 </dependencies>
104 <after>
105 <dep package="gtk+"/>
106 </after>
107 </autotools>
108
109 <autotools id="dbus-0.23" supports-non-srcdir-builds="no">
110 <branch repo="dbus.freedesktop.org" module="dbus"
111 revision="dbus-0-23" checkoutdir="dbus-0.23"/>
112 <dependencies>
113 <dep package="glib"/>
114 </dependencies>
115 <after>
116 <dep package="gtk+"/>
117 </after>
118 </autotools>
119
120 <!-- Not maintained - try dbusmm instead -->
121 <autotools id="dbus-cpp">
122 <branch repo="dbus.freedesktop.org"/>
123 <dependencies>
124 <dep package="dbus"/>
125 </dependencies>
126 </autotools>
127
128 <autotools id="dbusmm">
129 <branch repo="dbus.freedesktop.org"/>
130 <dependencies>
131 <dep package="dbus"/>
132 </dependencies>
133 </autotools>
134
135 <autotools id="dbus-glib">
136 <branch repo="git.freedesktop.org" module="dbus/dbus-glib"/>
137 <dependencies>
138 <dep package="libxml2"/>
139 <dep package="dbus"/>
140 <dep package="glib"/>
141 </dependencies>
142 </autotools>
143
144 <distutils id="dbus-python">
145 <branch repo="git.freedesktop.org" module="dbus/dbus-python"/>
146 <dependencies>
147 <dep package="dbus"/>
148 <dep package="dbus-glib"/>
149 </dependencies>
150 </distutils>
151
152 <autotools id="PolicyKit">
153 <branch repo="hal.freedesktop.org"/>
154 <dependencies>
155 <dep package="dbus-glib"/>
156 </dependencies>
157 </autotools>
158
159 <autotools id="hal">
160 <branch repo="hal.freedesktop.org"/>
161 <dependencies>
162 <dep package="dbus"/>
163 <dep package="PolicyKit"/>
164 </dependencies>
165 </autotools>
166
167 <autotools id="hal-0-4">
168 <branch repo="hal.freedesktop.org" module="hal"
169 revision="hal-0_4-stable-branch" checkoutdir="hal-0.4"/>
170 <dependencies>
171 <dep package="dbus-0.23"/>
172 </dependencies>
173 </autotools>
174
175 <autotools id="fontconfig">
176 <branch repo="fontconfig.freedesktop.org" revision="fc-2_4_branch"/>
177 </autotools>
178
179 <autotools id="icon-slicer">
180 <branch repo="icon-theme.freedesktop.org"/>
181 </autotools>
182 <autotools id="icon-naming-utils">
183 <branch repo="icon-theme.freedesktop.org"/>
184 </autotools>
185 <tarball id="hicolor-icon-theme" version="0.9"
186 supports-non-srcdir-builds="no">
187 <source href="http://icon-theme.freedesktop.org/releases/hicolor-icon-theme-0.9.tar.gz"
188 size="32574" md5sum="1d0821cb80d394eac30bd8cec5b0b60c"/>
189 </tarball>
190
191 <autotools id="tango-icon-theme">
192 <branch repo="tango.freedesktop.org"/>
193 <dependencies>
194 <dep package="icon-naming-utils"/>
195 </dependencies>
196 </autotools>
197 <autotools id="tango-icon-theme-extras">
198 <branch repo="tango.freedesktop.org"/>
199 <dependencies>
200 <dep package="tango-icon-theme"/>
201 </dependencies>
202 </autotools>
203
204 <autotools id="startup-notification">
205 <branch repo="startup-notification.freedesktop.org"/>
206 </autotools>
207
208 <autotools id="RenderProto">
209 <branch repo="git.freedesktop.org"
210 module="xorg/proto/renderproto" checkoutdir="RenderProto" />
211 </autotools>
212 <autotools id="libXrender" supports-non-srcdir-builds="no">
213 <branch repo="git.freedesktop.org"
214 module="xorg/lib/libXrender" checkoutdir="libXrender" />
215 <dependencies>
216 <dep package="RenderProto"/>
217 </dependencies>
218 </autotools>
219 <autotools id="libXft" supports-non-srcdir-builds="no">
220 <branch repo="git.freedesktop.org"
221 module="xorg/lib/libXft" checkoutdir="libXft" />
222 <dependencies>
223 <dep package="fontconfig"/>
224 <dep package="libXrender"/>
225 </dependencies>
226 </autotools>
227
228 <autotools id="poppler">
229 <branch repo="poppler.freedesktop.org"/>
230 <dependencies>
231 <dep package="cairo"/>
232 </dependencies>
233 </autotools>
234
235 <autotools id="poppler-0-4">
236 <branch repo="poppler.freedesktop.org" module="poppler"
237 revision="POPPLER_0_4_X" checkoutdir="poppler-0-4"/>
238 <dependencies>
239 <dep package="cairo-1-0"/>
240 </dependencies>
241 </autotools>
242
243 <perl id="perl-net-dbus">
244 <branch repo="cpan"
245 module="authors/id/D/DA/DANBERR/Net-DBus-0.33.2.tar.gz" version="0.33.2"
246 size="83279" md5sum="7e722c48c4bca7740cf28512287571b7"/>
247 <dependencies>
248 <dep package="dbus"/>
249 </dependencies>
250 </perl>
251
252 <autotools id="system-tools-backends">
253 <branch repo="system-tools-backends.freedesktop.org"
254 revision="BEFORE_DBUS_MERGE"/>
255 <suggests>
256 <dep package="perl-net-dbus"/>
257 </suggests>
258 </autotools>
259
260 <autotools id="system-tools-backends-1.4">
261 <branch repo="system-tools-backends.freedesktop.org"
262 module="system-tools-backends" revision="stb-1-4"
263 checkoutdir="system-tools-backends-1.4"/>
264 </autotools>
265
266 <autotools id="libdaemon">
267 <branch repo="libdaemon.0pointer.de" module="trunk" checkoutdir="libdaemon"/>
268 </autotools>
269
270 <!-- explicit disabling of qt3 and qt4 can be removed once avahi
271 correctly detects what is available. -->
272 <autotools id="avahi" autogenargs="--disable-qt3 --disable-qt4 --disable-mono --disable-monodoc --disable-manpages --enable-compat-howl --enable-compat-libdns_sd">
273 <branch repo="avahi.0pointer.de" module="trunk" checkoutdir="avahi"/>
274 <dependencies>
275 <dep package="libdaemon"/>
276 <dep package="dbus-python"/>
277 <dep package="pygtk"/>
278 </dependencies>
279 </autotools>
280
281</moduleset>
diff --git a/scripts/jhbuild/modulesets/gcj.modules b/scripts/jhbuild/modulesets/gcj.modules
new file mode 100644
index 0000000000..01b35c6b62
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gcj.modules
@@ -0,0 +1,135 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
2<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
3<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
4<moduleset>
5
6 <cvsroot name="gcc.gnu.org"
7 root=":pserver:anoncvs@gcc.gnu.org:/cvs/gcc"
8 password="" />
9 <cvsroot name="rhug.sources.redhat.com"
10 root=":pserver:anoncvs@sources.redhat.com:/cvs/rhug"
11 password="" />
12 <cvsroot name="gdb.sources.redhat.com"
13 root=":pserver:anoncvs@sources.redhat.com:/cvs/src"
14 password="anoncvs" />
15 <cvsroot name="gnome.org"
16 root=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
17 password="" />
18 <cvsroot name="classpath.savannah.gnu.org"
19 root=":ext:anoncvs@savannah.gnu.org:/cvsroot/classpath"
20 password="" />
21 <cvsroot name="cairo.freedesktop.org"
22 root=":pserver:anoncvs@cvs.freedesktop.org:/cvs/cairo"
23 password="" />
24
25 <include href="gnome-2.12.modules" />
26
27 <gdbmodule id="gdb" cvsroot="gdb.sources.redhat.com" />
28
29 <gcjmodule id="gcj" cvsroot="gcc.gnu.org">
30 <dependencies>
31 <dep package="cairo" />
32 <dep package="gtk+" />
33 </dependencies>
34 </gcjmodule>
35
36 <cvsmodule id="java-gcj-compat" cvsroot="rhug.sources.redhat.com">
37 <dependencies>
38 <dep package="ecj-for-jhbuild" />
39 <dep package="gjdoc" />
40 </dependencies>
41 </cvsmodule>
42
43 <cvsmodule id="ecj-for-jhbuild" cvsroot="rhug.sources.redhat.com"
44 supports-non-srcdir-builds="no">
45 <dependencies>
46 <dep package="gcj" />
47 </dependencies>
48 </cvsmodule>
49
50 <cvsmodule id="gjdoc" cvsroot="classpath.savannah.gnu.org" >
51 <dependencies>
52 <dep package="gcj" />
53 </dependencies>
54 </cvsmodule>
55
56 <cvsmodule id="jg-common" cvsroot="gnome.org">
57 <suggests>
58 <dep package="gcj" />
59 </suggests>
60 <dependencies>
61 <dep package="glib" />
62 </dependencies>
63 </cvsmodule>
64
65 <cvsmodule id="cairo-java" cvsroot="cairo.freedesktop.org">
66 <suggests>
67 <dep package="gcj" />
68 </suggests>
69 <dependencies>
70 <dep package="jg-common" />
71 <dep package="cairo" />
72 </dependencies>
73 </cvsmodule>
74
75 <cvsmodule id="libgtk-java" cvsroot="gnome.org">
76 <suggests>
77 <dep package="gcj" />
78 </suggests>
79 <dependencies>
80 <dep package="jg-common" />
81 <dep package="cairo-java" />
82 </dependencies>
83 </cvsmodule>
84
85 <cvsmodule id="libgnomevfs-java" cvsroot="gnome.org">
86 <suggests>
87 <dep package="gcj" />
88 </suggests>
89 <dependencies>
90 <dep package="libgtk-java" />
91 </dependencies>
92 </cvsmodule>
93
94 <cvsmodule id="libgnome-java" cvsroot="gnome.org">
95 <suggests>
96 <dep package="gcj" />
97 </suggests>
98 <dependencies>
99 <dep package="libgnome" />
100 <dep package="libgnomeui" />
101 <dep package="libgnomecanvas" />
102 <dep package="libgtk-java" />
103 </dependencies>
104 </cvsmodule>
105
106 <cvsmodule id="libglade-java" cvsroot="gnome.org">
107 <suggests>
108 <dep package="gcj" />
109 </suggests>
110 <dependencies>
111 <dep package="libgtk-java" />
112 <dep package="libgnome-java" />
113 </dependencies>
114 </cvsmodule>
115
116 <cvsmodule id="libgconf-java" cvsroot="gnome.org">
117 <suggests>
118 <dep package="gcj" />
119 </suggests>
120 <dependencies>
121 <dep package="libgtk-java" />
122 <dep package="libgnome-java" />
123 </dependencies>
124 </cvsmodule>
125
126 <metamodule id="java-gnome">
127 <dependencies>
128 <dep package="libgtk-java" />
129 <dep package="libgnome-java" />
130 <dep package="libglade-java" />
131 <dep package="libgconf-java" />
132 </dependencies>
133 </metamodule>
134
135</moduleset>
diff --git a/scripts/jhbuild/modulesets/gnome-2.10.modules b/scripts/jhbuild/modulesets/gnome-2.10.modules
new file mode 100644
index 0000000000..4d2043203a
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gnome-2.10.modules
@@ -0,0 +1,1621 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4
5 <repository type="cvs" name="gnome.org" default="yes"
6 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
7 password=""/>
8 <repository type="cvs" name="cairo.freedesktop.org"
9 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/cairo"
10 password=""/>
11 <repository type="cvs" name="mozilla.org"
12 cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
13 password="anonymous"/>
14 <repository type="cvs" name="gstreamer.freedesktop.org"
15 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/gstreamer"
16 password=""/>
17 <repository type="cvs" name="menu.freedesktop.org"
18 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/menus"
19 password=""/>
20 <repository type="cvs" name="mime.freedesktop.org"
21 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/mime"
22 password=""/>
23 <repository type="cvs" name="xklavier.freedesktop.org"
24 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/xklavier"
25 password=""/>
26
27 <repository type="cvs" name="elysium-project.sf.net"
28 cvsroot=":pserver:anonymous@elysium-project.cvs.sourceforge.net:/cvsroot/elysium-project"
29 password=""/>
30 <repository type="cvs" name="gaim.sf.net"
31 cvsroot=":pserver:anonymous@gaim.cvs.sourceforge.net:/cvsroot/gaim"
32 password=""/>
33 <repository type="cvs" name="clearlooks.sf.net"
34 cvsroot=":pserver:anonymous@clearlooks.cvs.sourceforge.net:/cvsroot/clearlooks"
35 password=""/>
36
37 <repository type="arch" name="rhythmbox"
38 archive="rhythmbox-devel@gnome.org--2004"
39 href="http://web.rhythmbox.org/arch/2004"/>
40
41 <tarball id="scrollkeeper" version="0.3.14" supports-non-srcdir-builds="no">
42 <source href="http://unc.dl.sourceforge.net/sourceforge/scrollkeeper/scrollkeeper-0.3.14.tar.gz"
43 size="679513" md5sum="161eb3f29e30e7b24f84eb93ac696155"/>
44 <dependencies>
45 <dep package="libxml2"/>
46 <dep package="libxslt"/>
47 <dep package="intltool"/>
48 </dependencies>
49 <patches>
50 <patch file="scrollkeeper_clean_xml_validation_context.patch" strip="1"/>
51 <patch file="scrollkeeper_language_fix.patch" strip="1"/>
52 <patch file="scrollkeeper_rw_offset_fix.patch" strip="1"/>
53 </patches>
54 </tarball>
55
56 <include href="freedesktop.modules"/>
57 <include href="gnutls.modules"/>
58
59 <autotools id="cairo-gtk-engine">
60 <branch repo="cairo.freedesktop.org"/>
61 <dependencies>
62 <dep package="gtk+"/>
63 <dep package="cairo"/>
64 </dependencies>
65 </autotools>
66
67 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
68 <branch repo="mime.freedesktop.org"/>
69 <dependencies>
70 <dep package="intltool"/>
71 </dependencies>
72 </autotools>
73
74 <autotools id="desktop-file-utils">
75 <branch repo="menu.freedesktop.org"/>
76 <dependencies>
77 <dep package="glib"/>
78 <dep package="intltool"/>
79 </dependencies>
80 </autotools>
81
82 <autotools id="libxklavier" supports-non-srcdir-builds="no">
83 <branch repo="xklavier.freedesktop.org"/>
84 </autotools>
85
86 <autotools id="intltool">
87 <branch/>
88 <dependencies>
89 <dep package="gnome-common"/>
90 </dependencies>
91 </autotools>
92 <autotools id="gnome-common">
93 <branch revision="gnome-2-12"/>
94 </autotools>
95 <autotools id="libxml2">
96 <branch module="gnome-xml" checkoutdir="libxml2"/>
97 </autotools>
98 <autotools id="libxslt">
99 <branch/>
100 <dependencies>
101 <dep package="libxml2"/>
102 </dependencies>
103 </autotools>
104 <autotools id="gtk-doc">
105 <branch/>
106 <dependencies>
107 <dep package="libxslt"/>
108 </dependencies>
109 </autotools>
110 <autotools id="glib">
111 <branch revision="glib-2-6"/>
112 <dependencies>
113 <dep package="gtk-doc"/>
114 </dependencies>
115 </autotools>
116 <autotools id="pango">
117 <branch revision="pango-1-8"/>
118 <dependencies>
119 <dep package="glib"/>
120 <dep package="libXft"/>
121 </dependencies>
122 </autotools>
123 <autotools id="atk">
124 <branch revision="gnome-2-10"/>
125 <dependencies>
126 <dep package="glib"/>
127 </dependencies>
128 </autotools>
129 <autotools id="gtk+">
130 <branch revision="gtk-2-6"/>
131 <dependencies>
132 <dep package="pango"/>
133 <dep package="atk"/>
134 <dep package="shared-mime-info"/>
135 </dependencies>
136 </autotools>
137 <autotools id="gail">
138 <branch/>
139 <dependencies>
140 <dep package="gtk+"/>
141 <dep package="atk"/>
142 <dep package="libgnomecanvas"/>
143 </dependencies>
144 </autotools>
145 <autotools id="gtkhtml2">
146 <branch/>
147 <dependencies>
148 <dep package="gtk+"/>
149 <dep package="libxml2"/>
150 <dep package="gail"/>
151 </dependencies>
152 </autotools>
153 <autotools id="libIDL">
154 <branch/>
155 <dependencies>
156 <dep package="glib"/>
157 </dependencies>
158 </autotools>
159 <autotools id="ORBit2">
160 <branch revision="gnome-2-10"/>
161 <dependencies>
162 <dep package="libIDL"/>
163 <dep package="gnome-common"/>
164 </dependencies>
165 </autotools>
166 <autotools id="gconf">
167 <branch revision="gnome-2-10"/>
168 <dependencies>
169 <dep package="ORBit2"/>
170 <dep package="libxml2"/>
171 <dep package="gtk+"/>
172 </dependencies>
173 </autotools>
174 <autotools id="libbonobo">
175 <branch revision="gnome-2-10"/>
176 <dependencies>
177 <dep package="ORBit2"/>
178 <dep package="intltool"/>
179 <dep package="gnome-common"/>
180 <dep package="libxml2"/>
181 </dependencies>
182 </autotools>
183 <autotools id="gnome-mime-data">
184 <branch/>
185 <dependencies>
186 <dep package="gnome-common"/>
187 </dependencies>
188 </autotools>
189 <autotools id="gnome-icon-theme">
190 <branch revision="gnome-2-10"/>
191 <dependencies>
192 <dep package="hicolor-icon-theme"/>
193 </dependencies>
194 </autotools>
195 <tarball id="howl" version="1.0.0">
196 <source href="http://www.porchdogsoft.com/download/howl-1.0.0.tar.gz"
197 size="542782" md5sum="c389d3ffba0e69a179de2ec650f1fdcc"/>
198 <patches>
199 <patch file="howl-1.0.0-buildfix.patch" strip="1"/>
200 </patches>
201 </tarball>
202 <autotools id="gnome-vfs">
203 <branch revision="gnome-2-10"/>
204 <dependencies>
205 <dep package="libbonobo"/>
206 <dep package="gconf"/>
207 <dep package="desktop-file-utils"/>
208 <dep package="shared-mime-info"/>
209 <dep package="gnome-mime-data"/>
210 <dep package="howl"/>
211 <dep package="hal-0.4"/>
212 </dependencies>
213 </autotools>
214 <autotools id="gnome-keyring">
215 <branch/>
216 <dependencies>
217 <dep package="gtk+"/>
218 </dependencies>
219 </autotools>
220 <autotools id="libart_lgpl">
221 <branch/>
222 </autotools>
223 <autotools id="libgnome">
224 <branch revision="gnome-2-10"/>
225 <dependencies>
226 <dep package="libxml2"/>
227 <dep package="libxslt"/>
228 <dep package="libbonobo"/>
229 <dep package="gnome-vfs"/>
230 <dep package="gconf"/>
231 <dep package="esound"/>
232 </dependencies>
233 </autotools>
234 <autotools id="libgnomecanvas">
235 <branch revision="gnome-2-10"/>
236 <dependencies>
237 <dep package="gtk+"/>
238 <dep package="libart_lgpl"/>
239 <dep package="libglade"/>
240 <dep package="gnome-common"/>
241 </dependencies>
242 </autotools>
243 <autotools id="libbonoboui">
244 <branch revision="gnome-2-10"/>
245 <dependencies>
246 <dep package="libgnome"/>
247 <dep package="libbonobo"/>
248 <dep package="libgnomecanvas"/>
249 <dep package="libglade"/>
250 </dependencies>
251 </autotools>
252 <autotools id="libgnomeui">
253 <branch revision="gnome-2-10"/>
254 <dependencies>
255 <dep package="libbonoboui"/>
256 <dep package="libglade"/>
257 <dep package="gnome-icon-theme"/>
258 <dep package="gnome-keyring"/>
259 </dependencies>
260 </autotools>
261 <autotools id="libglade">
262 <branch/>
263 <dependencies>
264 <dep package="gtk+"/>
265 <dep package="libxml2"/>
266 </dependencies>
267 </autotools>
268 <autotools id="pygtk" supports-non-srcdir-builds="no">
269 <branch revision="pygtk-2-6"/>
270 <dependencies>
271 <dep package="gtk+"/>
272 <dep package="libglade"/>
273 </dependencies>
274 </autotools>
275 <autotools id="pyorbit">
276 <branch/>
277 <dependencies>
278 <dep package="ORBit2"/>
279 </dependencies>
280 </autotools>
281 <autotools id="gnome-python">
282 <branch/>
283 <dependencies>
284 <dep package="pygtk"/>
285 <dep package="pyorbit"/>
286 <dep package="libgnomecanvas"/>
287 <dep package="libgnomeui"/>
288 </dependencies>
289 </autotools>
290 <autotools id="gnome-python-extras">
291 <branch/>
292 <dependencies>
293 <dep package="pygtk"/>
294 <dep package="gnome-python"/>
295 <dep package="gnome-panel"/>
296 <dep package="gtkhtml2"/>
297 <dep package="libgnomeprint"/>
298 <dep package="libgnomeprintui"/>
299 <dep package="gtksourceview"/>
300 <dep package="libwnck"/>
301 </dependencies>
302 </autotools>
303 <autotools id="bug-buddy">
304 <branch revision="gnome-2-10"/>
305 <dependencies>
306 <dep package="libgnomeui"/>
307 <dep package="gnome-menus"/>
308 </dependencies>
309 </autotools>
310 <autotools id="libwnck">
311 <branch revision="gnome-2-10"/>
312 <dependencies>
313 <dep package="gtk+"/>
314 <dep package="startup-notification"/>
315 </dependencies>
316 </autotools>
317 <autotools id="gnome-desktop" autogenargs="--with-gnome-distributor=JHBuild">
318 <branch revision="gnome-2-10"/>
319 <dependencies>
320 <dep package="libgnomeui"/>
321 <dep package="startup-notification"/>
322 <dep package="gnome-themes"/>
323 <dep package="scrollkeeper"/>
324 </dependencies>
325 </autotools>
326 <autotools id="gnome-menus">
327 <branch revision="gnome-2-10"/>
328 <dependencies>
329 <dep package="gnome-vfs"/>
330 </dependencies>
331 </autotools>
332 <autotools id="gnome-panel">
333 <branch revision="gnome-2-10"/>
334 <dependencies>
335 <dep package="scrollkeeper"/>
336 <dep package="libgnomeui"/>
337 <dep package="gnome-desktop"/>
338 <dep package="libwnck"/>
339 <dep package="evolution-data-server"/>
340 <dep package="gnome-menus"/>
341 </dependencies>
342 </autotools>
343 <autotools id="gnome-session">
344 <branch revision="gnome-2-10"/>
345 <dependencies>
346 <dep package="libgnomeui"/>
347 <dep package="libwnck"/>
348 <dep package="esound"/>
349 </dependencies>
350 </autotools>
351 <autotools id="gnome-applets">
352 <branch revision="gnome-2-10"/>
353 <dependencies>
354 <dep package="gnome-panel"/>
355 <dep package="libgtop"/>
356 <dep package="gail"/>
357 <dep package="libxklavier"/>
358 <dep package="gstreamer"/>
359 <dep package="gst-plugins"/>
360 <dep package="gucharmap"/>
361 <dep package="system-tools-backends"/>
362 </dependencies>
363 </autotools>
364 <autotools id="gnome-games">
365 <branch revision="gnome-2-10"/>
366 <dependencies>
367 <dep package="librsvg"/>
368 <dep package="scrollkeeper"/>
369 <dep package="libgnomeui"/>
370 <dep package="gob"/>
371 </dependencies>
372 </autotools>
373 <autotools id="libcroco" supports-non-srcdir-builds="no">
374 <branch/>
375 <dependencies>
376 <dep package="libxml2"/>
377 <dep package="pango"/>
378 </dependencies>
379 </autotools>
380 <autotools id="librsvg" supports-non-srcdir-builds="no">
381 <branch revision="gnome-2-10"/>
382 <dependencies>
383 <dep package="libxml2"/>
384 <dep package="gtk+"/>
385 <dep package="libart_lgpl"/>
386 <dep package="gnome-common"/>
387 <dep package="libgsf"/>
388 <dep package="libcroco"/>
389 <dep package="libgnomeprintui"/>
390 </dependencies>
391 </autotools>
392 <autotools id="eel">
393 <branch revision="gnome-2-10"/>
394 <dependencies>
395 <dep package="librsvg"/>
396 <dep package="libgnomeui"/>
397 <dep package="gail"/>
398 <dep package="gnome-menus"/>
399 </dependencies>
400 </autotools>
401 <autotools id="nautilus">
402 <branch revision="gnome-2-10"/>
403 <dependencies>
404 <dep package="scrollkeeper"/>
405 <dep package="esound"/>
406 <dep package="eel"/>
407 <dep package="librsvg"/>
408 <dep package="libgnomeui"/>
409 <dep package="gnome-desktop"/>
410 </dependencies>
411 </autotools>
412 <autotools id="nautilus-cd-burner">
413 <branch revision="gnome-2-10"/>
414 <dependencies>
415 <dep package="nautilus"/>
416 </dependencies>
417 </autotools>
418 <autotools id="nautilus-media" supports-non-srcdir-builds="no">
419 <branch/>
420 <dependencies>
421 <dep package="nautilus"/>
422 <dep package="gstreamer"/>
423 <dep package="gst-plugins"/>
424 </dependencies>
425 </autotools>
426 <autotools id="nautilus-vcs">
427 <branch/>
428 <dependencies>
429 <dep package="nautilus"/>
430 </dependencies>
431 </autotools>
432 <autotools id="metacity">
433 <branch revision="gnome-2-10"/>
434 <dependencies>
435 <dep package="gtk+"/>
436 <dep package="gconf"/>
437 <dep package="intltool"/>
438 <dep package="libglade"/>
439 </dependencies>
440 </autotools>
441 <autotools id="libgtop">
442 <branch revision="gnome-2-10"/>
443 <dependencies>
444 <dep package="glib"/>
445 </dependencies>
446 </autotools>
447 <autotools id="gnome-system-monitor">
448 <branch revision="gnome-2-10"/>
449 <dependencies>
450 <dep package="libgnomeui"/>
451 <dep package="libwnck"/>
452 <dep package="libgtop"/>
453 </dependencies>
454 </autotools>
455 <autotools id="gnome-control-center" supports-non-srcdir-builds="no">
456 <branch revision="gnome-2-10"/>
457 <dependencies>
458 <dep package="libgnomeui"/>
459 <dep package="esound"/>
460 <dep package="gnome-desktop"/>
461 <dep package="metacity"/>
462 <dep package="nautilus"/>
463 <dep package="libxklavier"/>
464 <dep package="gnome-menus"/>
465 </dependencies>
466 </autotools>
467 <autotools id="yelp">
468 <branch revision="gnome-2-10"/>
469 <dependencies>
470 <dep package="scrollkeeper"/>
471 <dep package="libgnomeui"/>
472 <dep package="gtkhtml2"/>
473 <dep package="gnome-vfs"/>
474 <dep package="gnome-doc-utils"/>
475 <dep package="mozilla"/>
476 </dependencies>
477 </autotools>
478 <autotools id="devhelp">
479 <branch/>
480 <dependencies>
481 <dep package="libgnomeui"/>
482 <dep package="gnome-vfs"/>
483 <dep package="mozilla"/>
484 </dependencies>
485 </autotools>
486 <autotools id="gnome-utils">
487 <branch revision="gnome-2-10"/>
488 <dependencies>
489 <dep package="libgnomeui"/>
490 <dep package="gnome-panel"/>
491 </dependencies>
492 </autotools>
493 <autotools id="gconf-editor" supports-non-srcdir-builds="no">
494 <branch/>
495 <dependencies>
496 <dep package="libgnomeui"/>
497 <dep package="gconf"/>
498 </dependencies>
499 </autotools>
500 <tarball id="audiofile" version="0.2.6" supports-non-srcdir-builds="no">
501 <source href="http://www.68k.org/~michael/audiofile/audiofile-0.2.6.tar.gz"
502 size="374688" md5sum="9c1049876cd51c0f1b12c2886cce4d42"/>
503 </tarball>
504 <autotools id="esound">
505 <branch/>
506 <dependencies>
507 <dep package="audiofile"/>
508 </dependencies>
509 </autotools>
510 <autotools id="gnome-media">
511 <branch revision="gnome-2-10"/>
512 <dependencies>
513 <dep package="scrollkeeper"/>
514 <dep package="libgnomeui"/>
515 <dep package="esound"/>
516 <dep package="gail"/>
517 <dep package="gstreamer"/>
518 <dep package="gst-plugins"/>
519 <dep package="nautilus-cd-burner"/>
520 </dependencies>
521 </autotools>
522 <autotools id="gdm2">
523 <branch revision="gnome-2-10"/>
524 <dependencies>
525 <dep package="librsvg"/>
526 </dependencies>
527 </autotools>
528 <autotools id="vte">
529 <branch/>
530 <dependencies>
531 <dep package="gtk+"/>
532 </dependencies>
533 </autotools>
534 <autotools id="gnome-terminal">
535 <branch revision="gnome-2-10"/>
536 <dependencies>
537 <dep package="libglade"/>
538 <dep package="libgnomeui"/>
539 <dep package="vte"/>
540 <dep package="startup-notification"/>
541 </dependencies>
542 </autotools>
543 <autotools id="gtk-engines">
544 <branch revision="gtk-engines-2-6"/>
545 <dependencies>
546 <dep package="gtk+"/>
547 </dependencies>
548 </autotools>
549 <autotools id="libgnomeprint">
550 <branch revision="gnome-2-10"/>
551 <dependencies>
552 <dep package="intltool"/>
553 <dep package="libart_lgpl"/>
554 <dep package="glib"/>
555 <dep package="gnome-common"/>
556 <dep package="pango"/>
557 <dep package="libgnomecups"/>
558 </dependencies>
559 </autotools>
560 <autotools id="libgnomeprintui">
561 <branch revision="gnome-2-10"/>
562 <dependencies>
563 <dep package="libgnomeprint"/>
564 <dep package="gtk+"/>
565 <dep package="libgnomecanvas"/>
566 <dep package="gnome-icon-theme"/>
567 </dependencies>
568 </autotools>
569 <autotools id="gedit">
570 <branch revision="gnome-2-10"/>
571 <dependencies>
572 <dep package="scrollkeeper"/>
573 <dep package="libgnomeui"/>
574 <dep package="eel"/>
575 <dep package="libgnomeprintui"/>
576 <dep package="gtksourceview"/>
577 </dependencies>
578 </autotools>
579 <autotools id="gedit-plugins">
580 <branch/>
581 <dependencies>
582 <dep package="gedit"/>
583 <dep package="libgnomeui"/>
584 <dep package="eel"/>
585 <dep package="libgnomeprintui"/>
586 </dependencies>
587 </autotools>
588 <autotools id="memprof">
589 <branch/>
590 <dependencies>
591 <dep package="libgnomeui"/>
592 </dependencies>
593 </autotools>
594 <autotools id="eog">
595 <branch revision="gnome-2-10"/>
596 <dependencies>
597 <dep package="eel"/>
598 <dep package="libgnomeui"/>
599 <dep package="libgnomeprint"/>
600 </dependencies>
601 </autotools>
602 <autotools id="gal">
603 <branch revision="gnome-2-10"/>
604 <dependencies>
605 <dep package="libgnomeui"/>
606 <dep package="libgnomeprintui"/>
607 </dependencies>
608 </autotools>
609 <autotools id="libgsf">
610 <branch/>
611 <dependencies>
612 <dep package="glib"/>
613 <dep package="gnome-vfs"/>
614 <dep package="libbonobo"/>
615 </dependencies>
616 </autotools>
617 <autotools id="goffice">
618 <branch/>
619 <dependencies>
620 <dep package="glib"/>
621 <dep package="libgsf"/>
622 <dep package="libxml2"/>
623 <dep package="pango"/>
624 <dep package="libglade"/>
625 <dep package="libgnomeprint"/>
626 <dep package="libgnomeprintui"/>
627 <dep package="libart_lgpl"/>
628 </dependencies>
629 </autotools>
630 <autotools id="gnumeric">
631 <branch/>
632 <dependencies>
633 <dep package="goffice"/>
634 <dep package="libgsf"/>
635 <dep package="libgda"/>
636 <dep package="pygtk"/>
637 <dep package="libgnomeprintui"/>
638 </dependencies>
639 </autotools>
640 <autotools id="gimp" autogenargs="--disable-print">
641 <branch/>
642 <dependencies>
643 <dep package="gtk+"/>
644 <dep package="libart_lgpl"/>
645 </dependencies>
646 </autotools>
647 <autotools id="glade">
648 <branch revision="gnome-2-10"/>
649 <dependencies>
650 <dep package="gtk+"/>
651 <dep package="libxml2"/>
652 <dep package="libgnomeui"/>
653 <dep package="libgnomeprintui"/>
654 </dependencies>
655 </autotools>
656 <autotools id="glade2c">
657 <branch/>
658 <dependencies>
659 <dep package="gtk+"/>
660 <dep package="libxml2"/>
661 <dep package="libgnomeui"/>
662 </dependencies>
663 </autotools>
664 <autotools id="sawfish">
665 <branch revision="gnome-2"/>
666 <dependencies>
667 <dep package="rep-gtk"/>
668 </dependencies>
669 </autotools>
670 <autotools id="rep-gtk">
671 <branch/>
672 <dependencies>
673 <dep package="librep"/>
674 <dep package="gtk+"/>
675 </dependencies>
676 </autotools>
677 <autotools id="librep">
678 <branch/>
679 </autotools>
680 <autotools id="rhythmbox">
681 <branch repo="rhythmbox" module="rhythmbox--main--0.9" checkoutdir="rhythmbox"/>
682 <dependencies>
683 <dep package="libgnomeui"/>
684 <dep package="gst-plugins"/>
685 </dependencies>
686 </autotools>
687 <autotools id="gstreamer" autogenargs="-- --disable-plugin-builddir --disable-tests" supports-non-srcdir-builds="no">
688 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
689 <dependencies>
690 <dep package="glib"/>
691 <dep package="libxml2"/>
692 </dependencies>
693 </autotools>
694 <autotools id="gst-plugins" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
695 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
696 <dependencies>
697 <dep package="gstreamer"/>
698 <dep package="gnome-vfs"/>
699 <dep package="gtk+"/>
700 </dependencies>
701 </autotools>
702 <autotools id="planner">
703 <branch/>
704 <dependencies>
705 <dep package="glib"/>
706 <dep package="libxml2"/>
707 <dep package="libgnomeui"/>
708 <dep package="libgnomeprintui"/>
709 <dep package="libgsf"/>
710 </dependencies>
711 </autotools>
712 <autotools id="file-roller">
713 <branch revision="gnome-2-10"/>
714 <dependencies>
715 <dep package="scrollkeeper"/>
716 <dep package="nautilus"/>
717 </dependencies>
718 </autotools>
719 <autotools id="balsa">
720 <branch revision="BALSA_2"/>
721 <dependencies>
722 <dep package="libgnomeui"/>
723 </dependencies>
724 </autotools>
725 <autotools id="pan">
726 <branch/>
727 <dependencies>
728 <dep package="libgnomeui"/>
729 <dep package="gnet"/>
730 </dependencies>
731 </autotools>
732 <autotools id="gcalctool" supports-non-srcdir-builds="no">
733 <branch revision="gnome-2-10"/>
734 <dependencies>
735 <dep package="scrollkeeper"/>
736 <dep package="libgnomeui"/>
737 </dependencies>
738 </autotools>
739 <autotools id="ggv" supports-non-srcdir-builds="no">
740 <branch revision="gnome-2-10"/>
741 <dependencies>
742 <dep package="scrollkeeper"/>
743 <dep package="libgnomeui"/>
744 </dependencies>
745 </autotools>
746 <autotools id="ekiga">
747 <branch revision="gnome-2-10"/>
748 <dependencies>
749 <dep package="libgnomeui"/>
750 </dependencies>
751 </autotools>
752 <autotools id="gucharmap" supports-non-srcdir-builds="no">
753 <branch revision="gnome-2-10"/>
754 <dependencies>
755 <dep package="libgnomeui"/>
756 </dependencies>
757 </autotools>
758 <autotools id="gtksourceview">
759 <branch revision="gnome-2-10"/>
760 <dependencies>
761 <dep package="gtk+"/>
762 <dep package="libxml2"/>
763 <dep package="libgnomeprint"/>
764 <dep package="gnome-vfs"/>
765 </dependencies>
766 </autotools>
767 <autotools id="glimmer">
768 <branch/>
769 <dependencies>
770 <dep package="gtksourceview"/>
771 <dep package="libgnomeprint"/>
772 </dependencies>
773 </autotools>
774 <autotools id="gdl">
775 <branch/>
776 <dependencies>
777 <dep package="libgnomeui"/>
778 <dep package="librsvg"/>
779 </dependencies>
780 </autotools>
781 <autotools id="gnome-build">
782 <branch/>
783 <dependencies>
784 <dep package="gdl"/>
785 <dep package="gnome-vfs"/>
786 <dep package="gtkhtml2"/>
787 </dependencies>
788 </autotools>
789 <autotools id="gdl">
790 <branch/>
791 <dependencies>
792 <dep package="glib"/>
793 </dependencies>
794 </autotools>
795 <autotools id="scaffold">
796 <branch/>
797 <dependencies>
798 <dep package="libgnomeui"/>
799 <dep package="vte"/>
800 <dep package="gdl"/>
801 </dependencies>
802 </autotools>
803 <autotools id="libsigc++2">
804 <branch/>
805 </autotools>
806 <autotools id="glibmm">
807 <branch revision="glibmm-2-6"/>
808 <dependencies>
809 <dep package="glib"/>
810 <dep package="libsigc++2"/>
811 </dependencies>
812 </autotools>
813 <autotools id="gtkmm">
814 <branch revision="gtkmm-2-6"/>
815 <dependencies>
816 <dep package="glibmm"/>
817 <dep package="gtk+"/>
818 </dependencies>
819 </autotools>
820 <autotools id="orbitcpp">
821 <branch/>
822 <dependencies>
823 <dep package="ORBit2"/>
824 </dependencies>
825 </autotools>
826 <autotools id="gnomemm/libgnomemm">
827 <branch/>
828 <dependencies>
829 <dep package="libgnome"/>
830 <dep package="gtkmm"/>
831 </dependencies>
832 </autotools>
833 <autotools id="gnomemm/libglademm">
834 <branch/>
835 <dependencies>
836 <dep package="libglade"/>
837 <dep package="gtkmm"/>
838 </dependencies>
839 </autotools>
840 <autotools id="gnomemm/libbonobomm">
841 <branch/>
842 <dependencies>
843 <dep package="libbonobo"/>
844 <dep package="gtkmm"/>
845 <dep package="orbitcpp"/>
846 </dependencies>
847 </autotools>
848 <autotools id="gnomemm/libbonobouimm">
849 <branch/>
850 <dependencies>
851 <dep package="libbonoboui"/>
852 <dep package="gnomemm/libbonobomm"/>
853 </dependencies>
854 </autotools>
855 <autotools id="gnomemm/libgnomecanvasmm">
856 <branch revision="gnome-2-10"/>
857 <dependencies>
858 <dep package="libgnomecanvas"/>
859 <dep package="gtkmm"/>
860 </dependencies>
861 </autotools>
862 <autotools id="gnomemm/gconfmm">
863 <branch/>
864 <dependencies>
865 <dep package="gconf"/>
866 <dep package="gtkmm"/>
867 </dependencies>
868 </autotools>
869 <autotools id="gnomemm/libgnomeuimm">
870 <branch/>
871 <dependencies>
872 <dep package="gtkmm"/>
873 <dep package="libgnomeui"/>
874 <dep package="gnomemm/libgnomemm"/>
875 <dep package="gnomemm/gconfmm"/>
876 <dep package="gnomemm/libgnomecanvasmm"/>
877 <dep package="gnomemm/libglademm"/>
878 <dep package="gnomemm/gnome-vfsmm"/>
879 </dependencies>
880 </autotools>
881 <autotools id="gnomemm/gnome-vfsmm">
882 <branch/>
883 <dependencies>
884 <dep package="glibmm"/>
885 <dep package="gnome-vfs"/>
886 </dependencies>
887 </autotools>
888 <autotools id="gnomemm/libpanelappletmm">
889 <branch/>
890 <dependencies>
891 <dep package="gtkmm"/>
892 </dependencies>
893 </autotools>
894 <autotools id="gnomemm/libgnomeprintmm">
895 <branch/>
896 <dependencies>
897 <dep package="gtkmm"/>
898 <dep package="libgnomeprint"/>
899 </dependencies>
900 </autotools>
901 <autotools id="gnomemm/libgnomeprintuimm">
902 <branch/>
903 <dependencies>
904 <dep package="gtkmm"/>
905 <dep package="gnomemm/libgnomeprintmm"/>
906 <dep package="libgnomeprintui"/>
907 </dependencies>
908 </autotools>
909 <autotools id="gnomemm/libgdamm">
910 <branch revision="libgda-1-2"/>
911 <dependencies>
912 <dep package="gtkmm"/>
913 <dep package="libgda"/>
914 </dependencies>
915 </autotools>
916 <autotools id="gnomemm/gtkmm_hello">
917 <branch/>
918 <dependencies>
919 <dep package="gtkmm"/>
920 </dependencies>
921 </autotools>
922 <autotools id="regexxer">
923 <branch/>
924 <dependencies>
925 <dep package="intltool"/>
926 <dep package="gtkmm"/>
927 <dep package="gnomemm/gconfmm"/>
928 <dep package="gnomemm/libglademm"/>
929 </dependencies>
930 </autotools>
931 <autotools id="gnet" autogenargs="--enable-glib2">
932 <branch revision="GNET_1_1"/>
933 <dependencies>
934 <dep package="glib"/>
935 </dependencies>
936 </autotools>
937 <autotools id="gnomeicu">
938 <branch/>
939 <dependencies>
940 <dep package="libgnomeui"/>
941 </dependencies>
942 </autotools>
943 <autotools id="at-spi">
944 <branch/>
945 <dependencies>
946 <dep package="libbonobo"/>
947 <dep package="gail"/>
948 </dependencies>
949 </autotools>
950 <autotools id="libgail-gnome">
951 <branch/>
952 <dependencies>
953 <dep package="at-spi"/>
954 <dep package="libgnomeui"/>
955 <dep package="gnome-panel"/>
956 </dependencies>
957 </autotools>
958 <autotools id="at-poke">
959 <branch/>
960 <dependencies>
961 <dep package="libgail-gnome"/>
962 </dependencies>
963 </autotools>
964 <autotools id="gnome-mag">
965 <branch/>
966 <dependencies>
967 <dep package="at-spi"/>
968 </dependencies>
969 </autotools>
970 <autotools id="gok">
971 <branch revision="gnome-2-10"/>
972 <dependencies>
973 <dep package="at-spi"/>
974 <dep package="libgnomeui"/>
975 <dep package="libwnck"/>
976 <dep package="esound"/>
977 <dep package="scrollkeeper"/>
978 </dependencies>
979 </autotools>
980 <autotools id="gnome-speech">
981 <branch/>
982 <dependencies>
983 <dep package="libbonobo"/>
984 </dependencies>
985 </autotools>
986 <autotools id="gnopernicus">
987 <branch revision="gnome-2-10"/>
988 <dependencies>
989 <dep package="gconf"/>
990 <dep package="libgnomeui"/>
991 <dep package="gnome-speech"/>
992 <dep package="gnome-mag"/>
993 </dependencies>
994 </autotools>
995 <autotools id="dasher" autogenargs="--with-a11y --with-gnome">
996 <branch revision="gnome-2-10"/>
997 <dependencies>
998 <dep package="at-spi"/>
999 <dep package="libgnomeui"/>
1000 <dep package="gnome-speech"/>
1001 <dep package="gnome-vfs"/>
1002 </dependencies>
1003 </autotools>
1004 <metamodule id="meta-gnome-devel-platform">
1005 <dependencies>
1006 <dep package="libgnome"/>
1007 <dep package="libbonobo"/>
1008 <dep package="libbonoboui"/>
1009 <dep package="libgnomeui"/>
1010 </dependencies>
1011 </metamodule>
1012 <metamodule id="meta-gnome-core">
1013 <dependencies>
1014 <dep package="gnome-desktop"/>
1015 <dep package="gnome-panel"/>
1016 <dep package="gnome-session"/>
1017 <dep package="gnome-terminal"/>
1018 <dep package="gnome-applets"/>
1019 </dependencies>
1020 </metamodule>
1021 <metamodule id="meta-nautilus">
1022 <dependencies>
1023 <dep package="nautilus"/>
1024 </dependencies>
1025 </metamodule>
1026 <metamodule id="meta-gnome-desktop">
1027 <dependencies>
1028 <dep package="meta-gnome-core"/>
1029 <dep package="gnome-control-center"/>
1030 <dep package="meta-nautilus"/>
1031 <dep package="yelp"/>
1032 <dep package="bug-buddy"/>
1033 <dep package="gedit"/>
1034 <dep package="gtk-engines"/>
1035 <dep package="eog"/>
1036 <dep package="ggv"/>
1037 <dep package="metacity"/>
1038 <dep package="gconf-editor"/>
1039 <dep package="gnome-utils"/>
1040 <dep package="gnome-system-monitor"/>
1041 <dep package="gstreamer"/>
1042 <dep package="gnome-media"/>
1043 <dep package="gnome-netstatus"/>
1044 <dep package="gcalctool"/>
1045 <dep package="gpdf"/>
1046 <dep package="gucharmap"/>
1047 <dep package="nautilus-cd-burner"/>
1048 <dep package="zenity"/>
1049 <dep package="libgail-gnome"/>
1050 <dep package="gnopernicus"/>
1051 <dep package="gok"/>
1052 <dep package="epiphany"/>
1053 <dep package="gnome-games"/>
1054 <dep package="gnome-user-docs"/>
1055 <dep package="file-roller"/>
1056 <dep package="gnome-system-tools"/>
1057 <dep package="gnome-nettool"/>
1058 <dep package="vino"/>
1059 <dep package="gnome-volume-manager"/>
1060 <dep package="totem"/>
1061 <dep package="gnome-menus"/>
1062 <dep package="gnome-backgrounds"/>
1063 <dep package="sound-juicer"/>
1064 <dep package="totem"/>
1065 <dep package="evolution"/>
1066 <dep package="evolution-webcal"/>
1067 <dep package="ekiga"/>
1068
1069 </dependencies>
1070 </metamodule>
1071 <metamodule id="meta-gnome-devel-tools">
1072 <dependencies>
1073 <dep package="glade"/>
1074 <dep package="memprof"/>
1075 <dep package="gconf-editor"/>
1076 <dep package="devhelp"/>
1077 <dep package="nautilus-vcs"/>
1078 </dependencies>
1079 </metamodule>
1080 <metamodule id="meta-gnome-python">
1081 <dependencies>
1082 <dep package="pygtk"/>
1083 <dep package="gnome-python"/>
1084 </dependencies>
1085 </metamodule>
1086 <metamodule id="meta-gnome-c++">
1087 <dependencies>
1088 <dep package="gtkmm"/>
1089 <dep package="gnomemm/libgnomeuimm"/>
1090 <dep package="gnomemm/gnome-vfsmm"/>
1091 <dep package="gnomemm/libpanelappletmm"/>
1092 <dep package="gnomemm/libbonobouimm"/>
1093 <dep package="gnomemm/libgnomeprintuimm"/>
1094 <dep package="libxml++"/>
1095 <dep package="gnomemm/libgdamm"/>
1096 <dep package="bakery"/>
1097 </dependencies>
1098 </metamodule>
1099 <metamodule id="meta-gnome-accessibility">
1100 <dependencies>
1101 <dep package="libgail-gnome"/>
1102 <dep package="at-poke"/>
1103 <dep package="dasher"/>
1104 <dep package="gnome-mag"/>
1105 <dep package="gok"/>
1106 <dep package="gnome-speech"/>
1107 <dep package="gnopernicus"/>
1108 </dependencies>
1109 </metamodule>
1110 <metamodule id="meta-gnome-proposed">
1111 <dependencies>
1112 </dependencies>
1113 </metamodule>
1114 <autotools id="sodipodi">
1115 <branch/>
1116 <dependencies>
1117 <dep package="gtk+"/>
1118 <dep package="libgnomeprintui"/>
1119 <dep package="libart_lgpl"/>
1120 <dep package="libxml2"/>
1121 </dependencies>
1122 </autotools>
1123 <autotools id="gnome-themes">
1124 <branch revision="gnome-2-10"/>
1125 <dependencies>
1126 <dep package="gtk-engines"/>
1127 </dependencies>
1128 </autotools>
1129 <autotools id="clearlooks">
1130 <branch repo="clearlooks.sf.net"/>
1131 <dependencies>
1132 <dep package="gtk+"/>
1133 <dep package="libgnome"/>
1134 </dependencies>
1135 </autotools>
1136 <autotools id="gob">
1137 <branch/>
1138 </autotools>
1139 <autotools id="libgnetwork">
1140 <branch/>
1141 <dependencies>
1142 <dep package="glib"/>
1143 <dep package="gconf"/>
1144 <dep package="intltool"/>
1145 </dependencies>
1146 </autotools>
1147 <autotools id="libgircclient">
1148 <branch/>
1149 <dependencies>
1150 <dep package="libgnetwork"/>
1151 </dependencies>
1152 </autotools>
1153 <autotools id="gnomechat">
1154 <branch/>
1155 <dependencies>
1156 <dep package="libgnetwork"/>
1157 <dep package="libgircclient"/>
1158 <dep package="libgnomeui"/>
1159 </dependencies>
1160 </autotools>
1161 <mozillamodule id="mozilla" autogenargs="--enable-default-toolkit=gtk2 --disable-mailnews --disable-ldap --disable-debug --enable-optimize --disable-tests --enable-crypto --enable-xft --with-system-zlib --disable-freetype2" cvsroot="mozilla.org" revision="MOZILLA_1_7_BRANCH">
1162 <dependencies>
1163 <dep package="gtk+"/>
1164 </dependencies>
1165 </mozillamodule>
1166 <autotools id="epiphany">
1167 <branch revision="gnome-2-10"/>
1168 <dependencies>
1169 <dep package="mozilla"/>
1170 <dep package="libgnomeui"/>
1171 </dependencies>
1172 </autotools>
1173 <autotools id="epiphany-extensions">
1174 <branch revision="gnome-2-10"/>
1175 <dependencies>
1176 <dep package="epiphany"/>
1177 </dependencies>
1178 </autotools>
1179 <autotools id="pyphany">
1180 <branch revision="gnome-2-10"/>
1181 <dependencies>
1182 <dep package="epiphany-extensions"/>
1183 <dep package="pygtk"/>
1184 </dependencies>
1185 </autotools>
1186 <autotools id="galeon">
1187 <branch/>
1188 <dependencies>
1189 <dep package="mozilla"/>
1190 <dep package="libgnomeui"/>
1191 </dependencies>
1192 </autotools>
1193 <autotools id="libsoup">
1194 <branch revision="gnome-2-10"/>
1195 <dependencies>
1196 <dep package="glib"/>
1197 <dep package="gnutls"/>
1198 <dep package="libxml2"/>
1199 </dependencies>
1200 </autotools>
1201 <autotools id="gtkhtml">
1202 <branch revision="gnome-2-10"/>
1203 <dependencies>
1204 <dep package="gtk+"/>
1205 <dep package="libgnomeui"/>
1206 <dep package="libbonoboui"/>
1207 <dep package="libglade"/>
1208 <dep package="gail"/>
1209 <dep package="libgnomeprint"/>
1210 <dep package="libgnomeprintui"/>
1211 <dep package="libsoup"/>
1212 <dep package="gal"/>
1213 </dependencies>
1214 </autotools>
1215 <autotools id="evolution-data-server" supports-non-srcdir-builds="no">
1216 <branch revision="gnome-2-10"/>
1217 <dependencies>
1218 <dep package="libbonobo"/>
1219 <dep package="libgnome"/>
1220 <dep package="libgnomeui"/>
1221 <dep package="libsoup"/>
1222 <dep package="libxml2"/>
1223 <dep package="gconf"/>
1224 <dep package="gnome-vfs"/>
1225 <dep package="mozilla"/>
1226 </dependencies>
1227 </autotools>
1228 <autotools id="evolution">
1229 <branch revision="gnome-2-10"/>
1230 <dependencies>
1231 <dep package="evolution-data-server"/>
1232 <dep package="gtkhtml"/>
1233 <dep package="libgnomeui"/>
1234 <dep package="libbonoboui"/>
1235 </dependencies>
1236 </autotools>
1237 <autotools id="evolution-webcal">
1238 <branch revision="gnome-2-10"/>
1239 <dependencies>
1240 <dep package="evolution-data-server"/>
1241 <dep package="libsoup"/>
1242 <dep package="libgnomeui"/>
1243 </dependencies>
1244 </autotools>
1245 <tarball id="xchat" version="2.4.1">
1246 <source href="http://xchat.org/files/source/2.4/xchat-2.4.1.tar.bz2"
1247 size="1214388" md5sum="aeb2337cc36dd4a9ac0cd6e909f67227"/>
1248 <dependencies>
1249 <dep package="gtk+"/>
1250 <dep package="libxml2"/>
1251 </dependencies>
1252 </tarball>
1253 <tarball id="camorama" version="0.17">
1254 <source href="http://camorama.fixedgear.org/downloads/camorama-0.17.tar.bz2"
1255 size="312233" md5sum="2b2784af53a1ba8fa4419aa806967b35"/>
1256 <dependencies>
1257 <dep package="gtk+"/>
1258 </dependencies>
1259 </tarball>
1260 <autotools id="gtk-engines-cleanice">
1261 <branch repo="elysium-project.sf.net"/>
1262 <dependencies>
1263 <dep package="gtk+"/>
1264 </dependencies>
1265 </autotools>
1266 <autotools id="gaim">
1267 <branch repo="gaim.sf.net"/>
1268 <dependencies>
1269 <dep package="libgnomeui"/>
1270 </dependencies>
1271 </autotools>
1272 <autotools id="zenity">
1273 <branch revision="gnome-2-10"/>
1274 <dependencies>
1275 <dep package="gtk+"/>
1276 <dep package="gconf"/>
1277 <dep package="libgnomecanvas"/>
1278 </dependencies>
1279 </autotools>
1280 <autotools id="gpdf">
1281 <branch/>
1282 <dependencies>
1283 <dep package="libgnomeui"/>
1284 <dep package="libbonoboui"/>
1285 <dep package="libgnomeprintui"/>
1286 </dependencies>
1287 </autotools>
1288 <autotools id="gnome-netstatus">
1289 <branch revision="gnome-2-10"/>
1290 <dependencies>
1291 <dep package="libgnomeui"/>
1292 <dep package="gnome-panel"/>
1293 </dependencies>
1294 </autotools>
1295 <autotools id="gnome-doc-utils">
1296 <branch revision="gnome-2-10"/>
1297 <dependencies>
1298 <dep package="libxslt"/>
1299 </dependencies>
1300 </autotools>
1301 <autotools id="totem" autogenargs="--enable-gstreamer">
1302 <branch revision="gnome-2-10"/>
1303 <dependencies>
1304 <dep package="gnome-desktop"/>
1305 <dep package="nautilus-cd-burner"/>
1306 <dep package="gstreamer"/>
1307 <dep package="gst-plugins"/>
1308 </dependencies>
1309 </autotools>
1310 <autotools id="gnome-themes-extras">
1311 <branch/>
1312 <dependencies>
1313 <dep package="gnome-themes"/>
1314 </dependencies>
1315 </autotools>
1316 <autotools id="libgda">
1317 <branch module="libgda" revision="release-1-2-branch"/>
1318 <dependencies>
1319 <dep package="glib"/>
1320 </dependencies>
1321 </autotools>
1322 <autotools id="libgnomedb" autogenargs="--enable-gnome=yes">
1323 <branch/>
1324 <dependencies>
1325 <dep package="libgda"/>
1326 <dep package="libgnomeui"/>
1327 <dep package="libbonoboui"/>
1328 </dependencies>
1329 </autotools>
1330 <autotools id="mergeant">
1331 <branch/>
1332 <dependencies>
1333 <dep package="libgnomedb"/>
1334 </dependencies>
1335 </autotools>
1336 <autotools id="gtranslator">
1337 <branch/>
1338 <dependencies>
1339 <dep package="libgnomeui"/>
1340 </dependencies>
1341 </autotools>
1342 <autotools id="gnome-spell">
1343 <branch/>
1344 <dependencies>
1345 <dep package="libgnomeui"/>
1346 </dependencies>
1347 </autotools>
1348 <autotools id="libgnomecups">
1349 <branch/>
1350 <dependencies>
1351 <dep package="glib"/>
1352 </dependencies>
1353 </autotools>
1354 <autotools id="gnome-cups-manager">
1355 <branch/>
1356 <dependencies>
1357 <dep package="libgnomecups"/>
1358 <dep package="libgnomeui"/>
1359 <dep package="libglade"/>
1360 </dependencies>
1361 </autotools>
1362 <autotools id="libxml++">
1363 <branch/>
1364 <dependencies>
1365 <dep package="libxml2"/>
1366 <dep package="glibmm"/>
1367 </dependencies>
1368 </autotools>
1369 <autotools id="bakery">
1370 <branch/>
1371 <dependencies>
1372 <dep package="libxml++"/>
1373 <dep package="gtkmm"/>
1374 <dep package="gnomemm/libglademm"/>
1375 <dep package="gnomemm/gconfmm"/>
1376 <dep package="gnomemm/gnome-vfsmm"/>
1377 </dependencies>
1378 </autotools>
1379 <autotools id="gnome-hello">
1380 <branch/>
1381 <dependencies>
1382 <dep package="glib"/>
1383 <dep package="libgnome"/>
1384 <dep package="libgnomeui"/>
1385 </dependencies>
1386 </autotools>
1387 <autotools id="gnome-system-tools">
1388 <branch revision="gnome-2-10"/>
1389 <dependencies>
1390 <dep package="glib"/>
1391 <dep package="libxml2"/>
1392 <dep package="gconf"/>
1393 <dep package="libgnomeui"/>
1394 <dep package="libbonoboui"/>
1395 <dep package="libglade"/>
1396 <dep package="system-tools-backends"/>
1397 </dependencies>
1398 </autotools>
1399 <autotools id="gnome-user-docs">
1400 <branch/>
1401 <dependencies>
1402 <dep package="scrollkeeper"/>
1403 </dependencies>
1404 </autotools>
1405 <autotools id="loudmouth">
1406 <branch/>
1407 <dependencies>
1408 <dep package="glib"/>
1409 </dependencies>
1410 </autotools>
1411 <autotools id="gossip">
1412 <branch revision="gossip-0-8"/>
1413 <dependencies>
1414 <dep package="loudmouth"/>
1415 <dep package="libgnomeui"/>
1416 </dependencies>
1417 </autotools>
1418 <autotools id="conglomerate">
1419 <branch/>
1420 <dependencies>
1421 <dep package="libxslt"/>
1422 <dep package="gconf"/>
1423 <dep package="libgnomeui"/>
1424 </dependencies>
1425 </autotools>
1426 <autotools id="sound-juicer">
1427 <branch revision="gnome-2-10"/>
1428 <dependencies>
1429 <dep package="libgnomeui"/>
1430 <dep package="gnome-media"/>
1431 <dep package="gstreamer"/>
1432 <dep package="gst-plugins"/>
1433 <dep package="nautilus-cd-burner"/>
1434 </dependencies>
1435 </autotools>
1436 <autotools id="gnome-network">
1437 <branch/>
1438 <dependencies>
1439 <dep package="glib"/>
1440 </dependencies>
1441 </autotools>
1442 <tarball id="guile" version="1.6.7">
1443 <source href="ftp://ftp.gnu.org/gnu/guile/guile-1.6.7.tar.gz"
1444 size="3039294" md5sum="c2ff2a2231f0cbb2e838dd8701a587c5"/>
1445 </tarball>
1446 <tarball id="autogen" version="5.6.5">
1447 <source href="http://internap.dl.sourceforge.net/sourceforge/autogen/autogen-5.6.5.tar.gz"
1448 size="1144260" md5sum="54a6cb0be7e6b526af9aba4a73013885"/>
1449 <dependencies>
1450 <dep package="guile"/>
1451 </dependencies>
1452 </tarball>
1453 <autotools id="anjuta">
1454 <branch/>
1455 <dependencies>
1456 <dep package="libbonoboui"/>
1457 <dep package="libgnomeprintui"/>
1458 <dep package="vte"/>
1459 <dep package="gnome-build"/>
1460 <dep package="autogen"/>
1461 </dependencies>
1462 </autotools>
1463 <autotools id="OpenApplet">
1464 <branch/>
1465 <dependencies>
1466 <dep package="gnome-panel"/>
1467 </dependencies>
1468 </autotools>
1469 <autotools id="gtetrinet">
1470 <branch/>
1471 <dependencies>
1472 <dep package="libgnomeui"/>
1473 </dependencies>
1474 </autotools>
1475 <autotools id="glom">
1476 <branch/>
1477 <dependencies>
1478 <dep package="gnomemm/libgdamm"/>
1479 <dep package="bakery"/>
1480 <dep package="libgnome"/>
1481 </dependencies>
1482 </autotools>
1483 <autotools id="vino">
1484 <branch revision="gnome-2-10"/>
1485 <dependencies>
1486 <dep package="libgnomeui"/>
1487 <dep package="libglade"/>
1488 <dep package="gconf"/>
1489 <dep package="gnutls"/>
1490 </dependencies>
1491 </autotools>
1492 <autotools id="gnome-keyring-manager">
1493 <branch revision="gnome-2-10"/>
1494 <dependencies>
1495 <dep package="libgnomeui"/>
1496 <dep package="gnome-keyring"/>
1497 <dep package="gconf"/>
1498 </dependencies>
1499 </autotools>
1500 <autotools id="gnome-volume-manager">
1501 <branch revision="gnome-2-10"/>
1502 <dependencies>
1503 <dep package="libgnomeui"/>
1504 <dep package="libglade"/>
1505 <dep package="hal-0.4"/>
1506 </dependencies>
1507 </autotools>
1508 <metamodule id="meta-storage">
1509 <dependencies>
1510 <dep package="storage/storage-store"/>
1511 <dep package="storage/vfs"/>
1512 <dep package="storage/applet"/>
1513 </dependencies>
1514 </metamodule>
1515 <autotools id="storage/storage-store">
1516 <branch/>
1517 <dependencies>
1518 <dep package="dbus-0.23"/>
1519 </dependencies>
1520 </autotools>
1521 <autotools id="storage/libstorage">
1522 <branch/>
1523 <dependencies>
1524 <dep package="gnome-vfs"/>
1525 <dep package="pygtk"/>
1526 </dependencies>
1527 </autotools>
1528 <autotools id="storage/libstorage-translators">
1529 <branch/>
1530 <dependencies>
1531 <dep package="storage/libstorage"/>
1532 </dependencies>
1533 </autotools>
1534 <autotools id="storage/vfs">
1535 <branch/>
1536 <dependencies>
1537 <dep package="storage/libstorage"/>
1538 <dep package="storage/libstorage-translators"/>
1539 </dependencies>
1540 </autotools>
1541 <autotools id="storage/pet">
1542 <branch/>
1543 </autotools>
1544 <autotools id="storage/libmrs">
1545 <branch/>
1546 <dependencies>
1547 <dep package="storage/pet"/>
1548 </dependencies>
1549 </autotools>
1550 <autotools id="storage/libmrs-converter">
1551 <branch/>
1552 <dependencies>
1553 <dep package="storage/libmrs"/>
1554 </dependencies>
1555 </autotools>
1556 <autotools id="storage/libstorage-nl">
1557 <branch/>
1558 <dependencies>
1559 <dep package="storage/libstorage"/>
1560 <dep package="storage/libmrs"/>
1561 <dep package="storage/libmrs-converter"/>
1562 </dependencies>
1563 </autotools>
1564 <autotools id="storage/applet">
1565 <branch/>
1566 <dependencies>
1567 <dep package="gnome-python"/>
1568 <dep package="storage/libstorage-nl"/>
1569 </dependencies>
1570 </autotools>
1571 <autotools id="gnome-nettool">
1572 <branch revision="gnome-2-10"/>
1573 <dependencies>
1574 <dep package="libgnomeui"/>
1575 </dependencies>
1576 </autotools>
1577 <autotools id="monkey-bubble">
1578 <branch/>
1579 <dependencies>
1580 <dep package="gstreamer"/>
1581 <dep package="gst-plugins"/>
1582 <dep package="libxml2"/>
1583 <dep package="gconf"/>
1584 <dep package="librsvg"/>
1585 <dep package="libgnomeui"/>
1586 </dependencies>
1587 </autotools>
1588 <autotools id="gnome-schedule">
1589 <branch/>
1590 <dependencies>
1591 <dep package="pygtk"/>
1592 <dep package="yelp"/>
1593 </dependencies>
1594 </autotools>
1595 <autotools id="gnome-backgrounds">
1596 <branch/>
1597 </autotools>
1598 <autotools id="evince">
1599 <branch/>
1600 <dependencies>
1601 <dep package="libgnomeui"/>
1602 <dep package="libgnomeprintui"/>
1603 <dep package="poppler"/>
1604 </dependencies>
1605 </autotools>
1606 <autotools id="nautilus-python" supports-non-srcdir-builds="no">
1607 <branch/>
1608 <dependencies>
1609 <dep package="nautilus"/>
1610 <dep package="pygtk"/>
1611 <dep package="gnome-python"/>
1612 </dependencies>
1613 </autotools>
1614 <autotools id="gst-python" autogenargs="--" supports-non-srcdir-builds="no">
1615 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
1616 <dependencies>
1617 <dep package="gstreamer"/>
1618 <dep package="gst-plugins"/>
1619 </dependencies>
1620 </autotools>
1621</moduleset>
diff --git a/scripts/jhbuild/modulesets/gnome-2.12.modules b/scripts/jhbuild/modulesets/gnome-2.12.modules
new file mode 100644
index 0000000000..ffbd89756f
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gnome-2.12.modules
@@ -0,0 +1,1747 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="gnome.org" default="yes"
5 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
6 password=""/>
7 <repository type="cvs" name="cairo.freedesktop.org"
8 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/cairo"
9 password=""/>
10 <repository type="cvs" name="mozilla.org"
11 cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
12 password="anonymous"/>
13 <repository type="cvs" name="gstreamer.freedesktop.org"
14 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/gstreamer"
15 password=""/>
16 <repository type="cvs" name="menu.freedesktop.org"
17 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/menus"
18 password=""/>
19 <repository type="cvs" name="mime.freedesktop.org"
20 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/mime"
21 password=""/>
22 <repository type="cvs" name="xklavier.freedesktop.org"
23 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/xklavier"
24 password=""/>
25
26 <repository type="cvs" name="elysium-project.sf.net"
27 cvsroot=":pserver:anonymous@elysium-project.cvs.sourceforge.net:/cvsroot/elysium-project"
28 password=""/>
29 <repository type="cvs" name="gaim.sf.net"
30 cvsroot=":pserver:anonymous@gaim.cvs.sourceforge.net:/cvsroot/gaim"
31 password=""/>
32 <repository type="cvs" name="inkscape.sf.net"
33 cvsroot=":pserver:anonymous@inkscape.cvs.sourceforge.net:/cvsroot/inkscape"
34 password=""/>
35 <repository type="svn" name="svn.galago-project.org"
36 href="http://svn.galago-project.org/"/>
37 <repository type="svn" name="svn.debian.org"
38 href="svn://svn.debian.org/"/>
39
40 <tarball id="scrollkeeper" version="0.3.14" supports-non-srcdir-builds="no">
41 <source href="http://unc.dl.sourceforge.net/sourceforge/scrollkeeper/scrollkeeper-0.3.14.tar.gz"
42 size="679513" md5sum="161eb3f29e30e7b24f84eb93ac696155"/>
43 <dependencies>
44 <dep package="libxml2"/>
45 <dep package="libxslt"/>
46 <dep package="intltool"/>
47 </dependencies>
48 <patches>
49 <patch file="scrollkeeper_clean_xml_validation_context.patch" strip="1"/>
50 <patch file="scrollkeeper_language_fix.patch" strip="1"/>
51 <patch file="scrollkeeper_rw_offset_fix.patch" strip="1"/>
52 </patches>
53 </tarball>
54
55 <autotools id="iso-codes">
56 <branch repo="svn.debian.org" module="pkg-isocodes/trunk/iso-codes" checkoutdir="iso-codes"/>
57 </autotools>
58
59 <include href="freedesktop.modules"/>
60 <include href="gnutls.modules"/>
61
62 <autotools id="cairo-gtk-engine">
63 <branch repo="cairo.freedesktop.org"/>
64 <dependencies>
65 <dep package="gtk+"/>
66 <dep package="cairo-1-0"/>
67 </dependencies>
68 </autotools>
69
70 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
71 <branch repo="mime.freedesktop.org"/>
72 <dependencies>
73 <dep package="intltool"/>
74 </dependencies>
75 </autotools>
76
77 <autotools id="desktop-file-utils">
78 <branch repo="menu.freedesktop.org"/>
79 <dependencies>
80 <dep package="glib"/>
81 <dep package="intltool"/>
82 </dependencies>
83 </autotools>
84
85 <autotools id="libxklavier" supports-non-srcdir-builds="no">
86 <branch repo="xklavier.freedesktop.org"/>
87 </autotools>
88 <autotools id="libbtctl">
89 <branch/>
90 <dependencies>
91 <dep package="gtk+"/>
92 <dep package="glib"/>
93 </dependencies>
94 </autotools>
95 <autotools id="gnome-bluetooth">
96 <branch/>
97 <dependencies>
98 <dep package="gtk+"/>
99 <dep package="glib"/>
100 <dep package="libbtctl"/>
101 <dep package="libglade"/>
102 <dep package="libgnomeui"/>
103 <dep package="gconf"/>
104 </dependencies>
105 </autotools>
106 <autotools id="phonemgr">
107 <branch/>
108 <dependencies>
109 <dep package="gtk+"/>
110 <dep package="glib"/>
111 <dep package="libbtctl"/>
112 <dep package="gnome-bluetooth"/>
113 <dep package="libglade"/>
114 <dep package="libgnomeui"/>
115 <dep package="libgnome"/>
116 <dep package="gconf"/>
117 </dependencies>
118 </autotools>
119
120 <autotools id="intltool">
121 <branch/>
122 <dependencies>
123 <dep package="gnome-common"/>
124 </dependencies>
125 </autotools>
126 <autotools id="gnome-common">
127 <branch revision="gnome-2-12"/>
128 </autotools>
129 <autotools id="libxml2">
130 <branch module="gnome-xml" checkoutdir="libxml2"/>
131 </autotools>
132 <autotools id="libxslt">
133 <branch/>
134 <dependencies>
135 <dep package="libxml2"/>
136 </dependencies>
137 </autotools>
138 <autotools id="gtk-doc">
139 <branch/>
140 <dependencies>
141 <dep package="libxslt"/>
142 <dep package="scrollkeeper"/>
143 </dependencies>
144 </autotools>
145 <autotools id="glib">
146 <branch revision="glib-2-8"/>
147 <dependencies>
148 <dep package="gtk-doc"/>
149 </dependencies>
150 </autotools>
151 <autotools id="pango">
152 <branch revision="pango-1-10"/>
153 <dependencies>
154 <dep package="glib"/>
155 <dep package="cairo-1-0"/>
156 <dep package="libXft"/>
157 </dependencies>
158 </autotools>
159 <autotools id="atk">
160 <branch revision="gnome-2-12"/>
161 <dependencies>
162 <dep package="glib"/>
163 </dependencies>
164 </autotools>
165 <autotools id="gtk+">
166 <branch revision="gtk-2-8"/>
167 <dependencies>
168 <dep package="cairo-1-0"/>
169 <dep package="pango"/>
170 <dep package="atk"/>
171 <dep package="shared-mime-info"/>
172 </dependencies>
173 </autotools>
174 <autotools id="gail">
175 <branch/>
176 <dependencies>
177 <dep package="gtk+"/>
178 <dep package="atk"/>
179 <dep package="libgnomecanvas"/>
180 </dependencies>
181 </autotools>
182 <autotools id="gtkhtml2">
183 <branch/>
184 <dependencies>
185 <dep package="gtk+"/>
186 <dep package="libxml2"/>
187 <dep package="gail"/>
188 </dependencies>
189 </autotools>
190 <autotools id="libIDL">
191 <branch/>
192 <dependencies>
193 <dep package="glib"/>
194 </dependencies>
195 </autotools>
196 <autotools id="ORBit2">
197 <branch revision="gnome-2-10"/>
198 <dependencies>
199 <dep package="libIDL"/>
200 <dep package="gnome-common"/>
201 </dependencies>
202 </autotools>
203 <autotools id="gconf">
204 <branch revision="gnome-2-12"/>
205 <dependencies>
206 <dep package="ORBit2"/>
207 <dep package="libxml2"/>
208 <dep package="gtk+"/>
209 </dependencies>
210 </autotools>
211 <autotools id="libbonobo">
212 <branch revision="gnome-2-12"/>
213 <dependencies>
214 <dep package="ORBit2"/>
215 <dep package="intltool"/>
216 <dep package="gnome-common"/>
217 <dep package="libxml2"/>
218 </dependencies>
219 </autotools>
220 <autotools id="gnome-mime-data">
221 <branch/>
222 <dependencies>
223 <dep package="gnome-common"/>
224 </dependencies>
225 </autotools>
226 <autotools id="gnome-icon-theme">
227 <branch revision="gnome-2-12"/>
228 <dependencies>
229 <dep package="hicolor-icon-theme"/>
230 </dependencies>
231 </autotools>
232 <tarball id="howl" version="1.0.0">
233 <source href="http://www.porchdogsoft.com/download/howl-1.0.0.tar.gz"
234 size="542782" md5sum="c389d3ffba0e69a179de2ec650f1fdcc"/>
235 <patches>
236 <patch file="howl-1.0.0-buildfix.patch" strip="1"/>
237 </patches>
238 </tarball>
239 <autotools id="gnome-vfs">
240 <branch revision="gnome-2-12"/>
241 <dependencies>
242 <dep package="libbonobo"/>
243 <dep package="gconf"/>
244 <dep package="desktop-file-utils"/>
245 <dep package="shared-mime-info"/>
246 <dep package="gnome-mime-data"/>
247 <dep package="howl"/>
248 <dep package="hal"/>
249 </dependencies>
250 </autotools>
251 <autotools id="gnome-keyring">
252 <branch revision="gnome-2-12"/>
253 <dependencies>
254 <dep package="gtk+"/>
255 </dependencies>
256 </autotools>
257 <autotools id="libart_lgpl">
258 <branch/>
259 </autotools>
260 <autotools id="libgnome">
261 <branch revision="gnome-2-12"/>
262 <dependencies>
263 <dep package="libxml2"/>
264 <dep package="libxslt"/>
265 <dep package="libbonobo"/>
266 <dep package="gnome-vfs"/>
267 <dep package="gconf"/>
268 <dep package="esound"/>
269 </dependencies>
270 </autotools>
271 <autotools id="libgnomecanvas">
272 <branch revision="gnome-2-12"/>
273 <dependencies>
274 <dep package="gtk+"/>
275 <dep package="libart_lgpl"/>
276 <dep package="libglade"/>
277 <dep package="gnome-common"/>
278 </dependencies>
279 </autotools>
280 <autotools id="libbonoboui">
281 <branch revision="gnome-2-10"/>
282 <dependencies>
283 <dep package="libgnome"/>
284 <dep package="libbonobo"/>
285 <dep package="libgnomecanvas"/>
286 <dep package="libglade"/>
287 </dependencies>
288 </autotools>
289 <autotools id="libgnomeui">
290 <branch revision="gnome-2-12"/>
291 <dependencies>
292 <dep package="libbonoboui"/>
293 <dep package="libglade"/>
294 <dep package="gnome-icon-theme"/>
295 <dep package="gnome-keyring"/>
296 </dependencies>
297 </autotools>
298 <autotools id="libglade">
299 <branch/>
300 <dependencies>
301 <dep package="gtk+"/>
302 <dep package="libxml2"/>
303 </dependencies>
304 </autotools>
305 <autotools id="pygtk">
306 <branch revision="pygtk-2-8"/>
307 <dependencies>
308 <dep package="gtk+"/>
309 <dep package="libglade"/>
310 </dependencies>
311 <after>
312 <dep package="pycairo-1-0"/>
313 </after>
314 </autotools>
315 <autotools id="pyorbit">
316 <branch/>
317 <dependencies>
318 <dep package="ORBit2"/>
319 </dependencies>
320 </autotools>
321 <autotools id="gnome-python">
322 <branch/>
323 <dependencies>
324 <dep package="pygtk"/>
325 <dep package="pyorbit"/>
326 <dep package="libgnomecanvas"/>
327 <dep package="libgnomeui"/>
328 </dependencies>
329 </autotools>
330 <autotools id="gnome-python-extras">
331 <branch/>
332 <dependencies>
333 <dep package="pygtk"/>
334 <dep package="gnome-python"/>
335 <dep package="gnome-panel"/>
336 <dep package="gtkhtml2"/>
337 <dep package="libgnomeprint"/>
338 <dep package="libgnomeprintui"/>
339 <dep package="gtksourceview"/>
340 <dep package="libwnck"/>
341 <!-- Needs libgda 1.2, not HEAD <dep package="libgda" /> -->
342 <dep package="nautilus-cd-burner"/>
343 <dep package="libgtop"/>
344 <dep package="totem"/>
345 <dep package="gdl"/>
346 <dep package="gnome-media"/>
347 </dependencies>
348 </autotools>
349 <autotools id="bug-buddy">
350 <branch revision="gnome-2-12"/>
351 <dependencies>
352 <dep package="libgnomeui"/>
353 <dep package="gnome-menus"/>
354 <dep package="gnome-doc-utils"/>
355 </dependencies>
356 </autotools>
357 <autotools id="libwnck">
358 <branch revision="gnome-2-12"/>
359 <dependencies>
360 <dep package="gtk+"/>
361 <dep package="startup-notification"/>
362 </dependencies>
363 </autotools>
364 <autotools id="gnome-desktop" autogenargs="--with-gnome-distributor=JHBuild">
365 <branch revision="gnome-2-12"/>
366 <dependencies>
367 <dep package="libgnomeui"/>
368 <dep package="startup-notification"/>
369 <dep package="gnome-themes"/>
370 <dep package="scrollkeeper"/>
371 <dep package="gnome-doc-utils"/>
372 </dependencies>
373 </autotools>
374 <autotools id="gnome-menus">
375 <branch revision="gnome-2-12"/>
376 <dependencies>
377 <dep package="intltool"/>
378 <dep package="gnome-common"/>
379 <dep package="glib"/>
380 <dep package="pygtk"/>
381 </dependencies>
382 </autotools>
383 <autotools id="gnome-panel">
384 <branch revision="gnome-2-12"/>
385 <dependencies>
386 <dep package="scrollkeeper"/>
387 <dep package="libgnomeui"/>
388 <dep package="gnome-desktop"/>
389 <dep package="libwnck"/>
390 <dep package="evolution-data-server"/>
391 <dep package="gnome-menus"/>
392 <dep package="gnome-vfs"/>
393 <dep package="libglade"/>
394 <dep package="gnome-doc-utils"/>
395 </dependencies>
396 </autotools>
397 <autotools id="gnome-session">
398 <branch revision="gnome-2-12"/>
399 <dependencies>
400 <dep package="libgnomeui"/>
401 <dep package="libwnck"/>
402 <dep package="esound"/>
403 </dependencies>
404 </autotools>
405 <autotools id="gnome-applets">
406 <branch revision="gnome-2-12"/>
407 <dependencies>
408 <dep package="gnome-panel"/>
409 <dep package="libgtop"/>
410 <dep package="gail"/>
411 <dep package="libxklavier"/>
412 <dep package="gstreamer"/>
413 <dep package="gst-plugins"/>
414 <dep package="gucharmap"/>
415 <dep package="system-tools-backends"/>
416 </dependencies>
417 </autotools>
418 <autotools id="gnome-games">
419 <branch revision="gnome-2-12"/>
420 <dependencies>
421 <dep package="librsvg"/>
422 <dep package="scrollkeeper"/>
423 <dep package="libgnomeui"/>
424 <dep package="gob"/>
425 </dependencies>
426 </autotools>
427 <autotools id="libcroco" supports-non-srcdir-builds="no">
428 <branch/>
429 <dependencies>
430 <dep package="libxml2"/>
431 <dep package="pango"/>
432 </dependencies>
433 </autotools>
434 <autotools id="librsvg" autogenargs="--enable-more-warnings=no"
435 supports-non-srcdir-builds="no">
436 <branch revision="gnome-2-12-branch"/>
437 <dependencies>
438 <dep package="libxml2"/>
439 <dep package="gtk+"/>
440 <dep package="libart_lgpl"/>
441 <dep package="gnome-common"/>
442 <dep package="libgsf"/>
443 <dep package="libcroco"/>
444 <dep package="libgnomeprintui"/>
445 </dependencies>
446 </autotools>
447 <autotools id="eel">
448 <branch revision="gnome-2-12"/>
449 <dependencies>
450 <dep package="librsvg"/>
451 <dep package="libgnomeui"/>
452 <dep package="gail"/>
453 <dep package="gnome-desktop"/>
454 <dep package="gnome-menus"/>
455 </dependencies>
456 </autotools>
457 <autotools id="nautilus">
458 <branch revision="gnome-2-12"/>
459 <dependencies>
460 <dep package="scrollkeeper"/>
461 <dep package="esound"/>
462 <dep package="eel"/>
463 <dep package="librsvg"/>
464 <dep package="libgnomeui"/>
465 <dep package="gnome-desktop"/>
466 </dependencies>
467 </autotools>
468 <autotools id="nautilus-cd-burner">
469 <branch revision="gnome-2-12"/>
470 <dependencies>
471 <dep package="nautilus"/>
472 </dependencies>
473 </autotools>
474 <autotools id="nautilus-open-terminal">
475 <branch/>
476 <dependencies>
477 <dep package="nautilus"/>
478 </dependencies>
479 </autotools>
480 <autotools id="nautilus-media" supports-non-srcdir-builds="no">
481 <branch/>
482 <dependencies>
483 <dep package="nautilus"/>
484 <dep package="gstreamer"/>
485 <dep package="gst-plugins"/>
486 </dependencies>
487 </autotools>
488 <autotools id="nautilus-vcs">
489 <branch/>
490 <dependencies>
491 <dep package="nautilus"/>
492 </dependencies>
493 </autotools>
494 <autotools id="metacity">
495 <branch revision="gnome-2-12"/>
496 <dependencies>
497 <dep package="gtk+"/>
498 <dep package="gconf"/>
499 <dep package="intltool"/>
500 <dep package="libglade"/>
501 </dependencies>
502 </autotools>
503 <autotools id="libgtop">
504 <branch revision="gnome-2-12"/>
505 <dependencies>
506 <dep package="glib"/>
507 </dependencies>
508 </autotools>
509 <autotools id="gnome-system-monitor">
510 <branch revision="gnome-2-12"/>
511 <dependencies>
512 <dep package="libgnomeui"/>
513 <dep package="libwnck"/>
514 <dep package="libgtop"/>
515 </dependencies>
516 </autotools>
517 <autotools id="gnome-control-center" supports-non-srcdir-builds="no">
518 <branch revision="gnome-2-12"/>
519 <dependencies>
520 <dep package="libgnomeui"/>
521 <dep package="esound"/>
522 <dep package="gnome-desktop"/>
523 <dep package="metacity"/>
524 <dep package="nautilus"/>
525 <dep package="libxklavier"/>
526 <dep package="gnome-menus"/>
527 <dep package="gnome-doc-utils"/>
528 </dependencies>
529 </autotools>
530 <autotools id="yelp">
531 <branch revision="gnome-2-12"/>
532 <dependencies>
533 <dep package="scrollkeeper"/>
534 <dep package="libgnomeui"/>
535 <dep package="gnome-vfs"/>
536 <dep package="gnome-doc-utils"/>
537 <dep package="mozilla"/>
538 </dependencies>
539 </autotools>
540 <autotools id="devhelp">
541 <branch/>
542 <dependencies>
543 <dep package="libgnomeui"/>
544 <dep package="gnome-vfs"/>
545 <dep package="mozilla"/>
546 </dependencies>
547 </autotools>
548 <autotools id="gnome-utils">
549 <branch revision="gnome-2-12"/>
550 <dependencies>
551 <dep package="libgnomeui"/>
552 <dep package="gnome-panel"/>
553 </dependencies>
554 </autotools>
555 <autotools id="gconf-editor" supports-non-srcdir-builds="no">
556 <branch revision="gnome-2-12"/>
557 <dependencies>
558 <dep package="libgnomeui"/>
559 <dep package="gconf"/>
560 </dependencies>
561 </autotools>
562 <tarball id="audiofile" version="0.2.6" supports-non-srcdir-builds="no">
563 <source href="http://www.68k.org/~michael/audiofile/audiofile-0.2.6.tar.gz"
564 size="374688" md5sum="9c1049876cd51c0f1b12c2886cce4d42"/>
565 </tarball>
566 <autotools id="esound">
567 <branch/>
568 <dependencies>
569 <dep package="audiofile"/>
570 </dependencies>
571 </autotools>
572 <autotools id="gnome-media">
573 <branch revision="gnome-2-12"/>
574 <dependencies>
575 <dep package="scrollkeeper"/>
576 <dep package="libgnomeui"/>
577 <dep package="esound"/>
578 <dep package="gail"/>
579 <dep package="gstreamer"/>
580 <dep package="gst-plugins"/>
581 <dep package="nautilus-cd-burner"/>
582 </dependencies>
583 </autotools>
584 <autotools id="gdm2">
585 <branch revision="gnome-2-12"/>
586 <dependencies>
587 <dep package="librsvg"/>
588 <dep package="gnome-doc-utils"/>
589 </dependencies>
590 </autotools>
591 <autotools id="vte">
592 <branch/>
593 <dependencies>
594 <dep package="gtk+"/>
595 </dependencies>
596 </autotools>
597 <autotools id="gnome-terminal">
598 <branch revision="gnome-2-12"/>
599 <dependencies>
600 <dep package="libglade"/>
601 <dep package="libgnomeui"/>
602 <dep package="vte"/>
603 <dep package="startup-notification"/>
604 </dependencies>
605 </autotools>
606 <autotools id="gtk-engines">
607 <branch revision="gtk-engines-2-6"/>
608 <dependencies>
609 <dep package="gtk+"/>
610 </dependencies>
611 </autotools>
612 <autotools id="libgnomeprint">
613 <branch/>
614 <dependencies>
615 <dep package="intltool"/>
616 <dep package="libart_lgpl"/>
617 <dep package="glib"/>
618 <dep package="gnome-common"/>
619 <dep package="pango"/>
620 <dep package="libgnomecups"/>
621 </dependencies>
622 </autotools>
623 <autotools id="libgnomeprintui">
624 <branch revision="gnome-2-12"/>
625 <dependencies>
626 <dep package="libgnomeprint"/>
627 <dep package="gtk+"/>
628 <dep package="libgnomecanvas"/>
629 <dep package="gnome-icon-theme"/>
630 </dependencies>
631 </autotools>
632 <autotools id="gedit">
633 <branch revision="gnome-2-12"/>
634 <dependencies>
635 <dep package="scrollkeeper"/>
636 <dep package="libgnomeui"/>
637 <dep package="eel"/>
638 <dep package="libgnomeprintui"/>
639 <dep package="gtksourceview"/>
640 </dependencies>
641 </autotools>
642 <autotools id="gedit-plugins">
643 <branch/>
644 <dependencies>
645 <dep package="gedit"/>
646 <dep package="libgnomeui"/>
647 <dep package="eel"/>
648 <dep package="libgnomeprintui"/>
649 </dependencies>
650 </autotools>
651 <autotools id="memprof">
652 <branch/>
653 <dependencies>
654 <dep package="libgnomeui"/>
655 </dependencies>
656 </autotools>
657 <autotools id="eog">
658 <branch revision="gnome-2-12"/>
659 <dependencies>
660 <dep package="libgnomeui"/>
661 <dep package="libgnomeprint"/>
662 </dependencies>
663 </autotools>
664 <autotools id="libgsf">
665 <branch/>
666 <dependencies>
667 <dep package="glib"/>
668 <dep package="gnome-vfs"/>
669 <dep package="libbonobo"/>
670 </dependencies>
671 </autotools>
672 <autotools id="goffice">
673 <branch/>
674 <dependencies>
675 <dep package="glib"/>
676 <dep package="libgsf"/>
677 <dep package="libxml2"/>
678 <dep package="pango"/>
679 <dep package="libglade"/>
680 <dep package="libgnomeprint"/>
681 <dep package="libgnomeprintui"/>
682 <dep package="libart_lgpl"/>
683 </dependencies>
684 </autotools>
685 <autotools id="gnumeric">
686 <branch/>
687 <dependencies>
688 <dep package="goffice"/>
689 <dep package="libgsf"/>
690 <!-- Needs libgda 1.2, not HEAD <dep package="libgda" /> -->
691 <dep package="pygtk"/>
692 <dep package="libgnomeprintui"/>
693 </dependencies>
694 </autotools>
695 <autotools id="gimp" autogenargs="--disable-print">
696 <branch/>
697 <dependencies>
698 <dep package="gtk+"/>
699 <dep package="libart_lgpl"/>
700 </dependencies>
701 </autotools>
702 <autotools id="glade">
703 <branch/>
704 <dependencies>
705 <dep package="gtk+"/>
706 <dep package="libxml2"/>
707 <dep package="libgnomeui"/>
708 <dep package="libgnomeprintui"/>
709 </dependencies>
710 </autotools>
711 <autotools id="glade2c">
712 <branch/>
713 <dependencies>
714 <dep package="gtk+"/>
715 <dep package="libxml2"/>
716 <dep package="libgnomeui"/>
717 </dependencies>
718 </autotools>
719 <autotools id="sawfish">
720 <branch revision="gnome-2"/>
721 <dependencies>
722 <dep package="rep-gtk"/>
723 </dependencies>
724 </autotools>
725 <autotools id="rep-gtk">
726 <branch/>
727 <dependencies>
728 <dep package="librep"/>
729 <dep package="gtk+"/>
730 </dependencies>
731 </autotools>
732 <autotools id="librep">
733 <branch/>
734 </autotools>
735 <autotools id="rhythmbox">
736 <branch/>
737 <dependencies>
738 <dep package="libgnomeui"/>
739 <dep package="gst-plugins"/>
740 <dep package="nautilus-cd-burner"/>
741 <dep package="totem"/>
742 </dependencies>
743 </autotools>
744 <autotools id="gstreamer" autogenargs="-- --disable-plugin-builddir --disable-tests" supports-non-srcdir-builds="no">
745 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
746 <dependencies>
747 <dep package="glib"/>
748 <dep package="libxml2"/>
749 </dependencies>
750 </autotools>
751 <autotools id="gst-plugins" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
752 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
753 <dependencies>
754 <dep package="gstreamer"/>
755 <dep package="gnome-vfs"/>
756 <dep package="gtk+"/>
757 </dependencies>
758 </autotools>
759 <autotools id="planner">
760 <branch/>
761 <dependencies>
762 <dep package="glib"/>
763 <dep package="libxml2"/>
764 <dep package="libgnomeui"/>
765 <dep package="libgnomeprintui"/>
766 <dep package="libgsf"/>
767 </dependencies>
768 </autotools>
769 <autotools id="file-roller">
770 <branch revision="gnome-2-12"/>
771 <dependencies>
772 <dep package="scrollkeeper"/>
773 <dep package="gnome-doc-utils"/>
774 <dep package="nautilus"/>
775 </dependencies>
776 </autotools>
777 <autotools id="balsa">
778 <branch revision="BALSA_2"/>
779 <dependencies>
780 <dep package="libgnomeui"/>
781 </dependencies>
782 </autotools>
783 <autotools id="pan">
784 <branch/>
785 <dependencies>
786 <dep package="libgnomeui"/>
787 <dep package="gnet"/>
788 </dependencies>
789 </autotools>
790 <autotools id="gcalctool" supports-non-srcdir-builds="no">
791 <branch revision="gnome-2-12"/>
792 <dependencies>
793 <dep package="scrollkeeper"/>
794 <dep package="libgnomeui"/>
795 </dependencies>
796 </autotools>
797 <autotools id="ggv" supports-non-srcdir-builds="no">
798 <branch/>
799 <dependencies>
800 <dep package="scrollkeeper"/>
801 <dep package="libgnomeui"/>
802 </dependencies>
803 </autotools>
804 <autotools id="ekiga">
805 <branch revision="gnome-2-12"/>
806 <dependencies>
807 <dep package="libgnomeui"/>
808 </dependencies>
809 </autotools>
810 <autotools id="gucharmap" supports-non-srcdir-builds="no">
811 <branch revision="gnome-2-12"/>
812 <dependencies>
813 <dep package="libgnomeui"/>
814 <dep package="gnome-doc-utils"/>
815 </dependencies>
816 </autotools>
817 <autotools id="gtksourceview" autogenargs="--enable-compile-warnings=maximum">
818 <branch revision="gnome-2-12"/>
819 <dependencies>
820 <dep package="gtk+"/>
821 <dep package="libxml2"/>
822 <dep package="libgnomeprint"/>
823 <dep package="gnome-vfs"/>
824 </dependencies>
825 </autotools>
826 <autotools id="glimmer">
827 <branch/>
828 <dependencies>
829 <dep package="gtksourceview"/>
830 <dep package="libgnomeprint"/>
831 </dependencies>
832 </autotools>
833 <autotools id="gdl">
834 <branch/>
835 <dependencies>
836 <dep package="libgnomeui"/>
837 <dep package="librsvg"/>
838 </dependencies>
839 </autotools>
840 <autotools id="gnome-build">
841 <branch/>
842 <dependencies>
843 <dep package="gdl"/>
844 <dep package="gnome-vfs"/>
845 <dep package="gtkhtml2"/>
846 </dependencies>
847 </autotools>
848 <autotools id="scaffold">
849 <branch/>
850 <dependencies>
851 <dep package="libgnomeui"/>
852 <dep package="vte"/>
853 <dep package="gdl"/>
854 </dependencies>
855 </autotools>
856 <autotools id="libsigc++2">
857 <branch revision="libsigc-2-0"/>
858 </autotools>
859 <autotools id="glibmm">
860 <branch revision="glibmm-2-8"/>
861 <dependencies>
862 <dep package="glib"/>
863 <dep package="libsigc++2"/>
864 </dependencies>
865 </autotools>
866 <autotools id="gtkmm">
867 <branch revision="gtkmm-2-8"/>
868 <dependencies>
869 <dep package="glibmm"/>
870 <dep package="gtk+"/>
871 </dependencies>
872 </autotools>
873 <autotools id="orbitcpp">
874 <branch/>
875 <dependencies>
876 <dep package="ORBit2"/>
877 </dependencies>
878 </autotools>
879 <autotools id="gnomemm/libgnomemm">
880 <branch/>
881 <dependencies>
882 <dep package="libgnome"/>
883 <dep package="gtkmm"/>
884 </dependencies>
885 </autotools>
886 <autotools id="gnomemm/libglademm">
887 <branch/>
888 <dependencies>
889 <dep package="libglade"/>
890 <dep package="gtkmm"/>
891 </dependencies>
892 </autotools>
893 <autotools id="gnomemm/libbonobomm">
894 <branch/>
895 <dependencies>
896 <dep package="libbonobo"/>
897 <dep package="gtkmm"/>
898 <dep package="orbitcpp"/>
899 </dependencies>
900 </autotools>
901 <autotools id="gnomemm/libbonobouimm">
902 <branch/>
903 <dependencies>
904 <dep package="libbonoboui"/>
905 <dep package="gnomemm/libbonobomm"/>
906 </dependencies>
907 </autotools>
908 <autotools id="gnomemm/libgnomecanvasmm">
909 <branch/>
910 <dependencies>
911 <dep package="libgnomecanvas"/>
912 <dep package="gtkmm"/>
913 </dependencies>
914 </autotools>
915 <autotools id="gnomemm/gconfmm">
916 <branch/>
917 <dependencies>
918 <dep package="gconf"/>
919 <dep package="gtkmm"/>
920 </dependencies>
921 </autotools>
922 <autotools id="gnomemm/libgnomeuimm">
923 <branch/>
924 <dependencies>
925 <dep package="gtkmm"/>
926 <dep package="libgnomeui"/>
927 <dep package="gnomemm/libgnomemm"/>
928 <dep package="gnomemm/gconfmm"/>
929 <dep package="gnomemm/libgnomecanvasmm"/>
930 <dep package="gnomemm/libglademm"/>
931 <dep package="gnomemm/gnome-vfsmm"/>
932 </dependencies>
933 </autotools>
934 <autotools id="gnomemm/gnome-vfsmm">
935 <branch/>
936 <dependencies>
937 <dep package="glibmm"/>
938 <dep package="gnome-vfs"/>
939 </dependencies>
940 </autotools>
941 <autotools id="gnomemm/libpanelappletmm">
942 <branch/>
943 <dependencies>
944 <dep package="gtkmm"/>
945 </dependencies>
946 </autotools>
947 <autotools id="gnomemm/libgnomeprintmm">
948 <branch/>
949 <dependencies>
950 <dep package="gtkmm"/>
951 <dep package="libgnomeprint"/>
952 </dependencies>
953 </autotools>
954 <autotools id="gnomemm/libgnomeprintuimm">
955 <branch/>
956 <dependencies>
957 <dep package="gtkmm"/>
958 <dep package="gnomemm/libgnomeprintmm"/>
959 <dep package="libgnomeprintui"/>
960 </dependencies>
961 </autotools>
962 <autotools id="gnomemm/libgdamm">
963 <branch revision="libgda-1-2"/>
964 <dependencies>
965 <dep package="gtkmm"/>
966 <!-- needs libgda 1.2, not HEAD <dep package="libgda" /> -->
967 </dependencies>
968 </autotools>
969 <autotools id="gnomemm/gtkmm_hello">
970 <branch/>
971 <dependencies>
972 <dep package="gtkmm"/>
973 </dependencies>
974 </autotools>
975 <autotools id="regexxer">
976 <branch/>
977 <dependencies>
978 <dep package="intltool"/>
979 <dep package="gtkmm"/>
980 <dep package="gnomemm/gconfmm"/>
981 <dep package="gnomemm/libglademm"/>
982 </dependencies>
983 </autotools>
984 <autotools id="gnet" autogenargs="--enable-glib2">
985 <branch revision="GNET_1_1"/>
986 <dependencies>
987 <dep package="glib"/>
988 </dependencies>
989 </autotools>
990 <autotools id="gnomeicu">
991 <branch/>
992 <dependencies>
993 <dep package="libgnomeui"/>
994 </dependencies>
995 </autotools>
996 <autotools id="at-spi">
997 <branch revision="AT_SPI_1_6_6"/>
998 <dependencies>
999 <dep package="libbonobo"/>
1000 <dep package="gail"/>
1001 </dependencies>
1002 </autotools>
1003 <autotools id="libgail-gnome">
1004 <branch/>
1005 <dependencies>
1006 <dep package="at-spi"/>
1007 <dep package="libgnomeui"/>
1008 <dep package="gnome-panel"/>
1009 </dependencies>
1010 </autotools>
1011 <autotools id="at-poke">
1012 <branch/>
1013 <dependencies>
1014 <dep package="libgail-gnome"/>
1015 </dependencies>
1016 </autotools>
1017 <autotools id="gnome-mag">
1018 <branch/>
1019 <dependencies>
1020 <dep package="at-spi"/>
1021 </dependencies>
1022 </autotools>
1023 <autotools id="gok">
1024 <branch/>
1025 <dependencies>
1026 <dep package="at-spi"/>
1027 <dep package="libgnomeui"/>
1028 <dep package="libwnck"/>
1029 <dep package="esound"/>
1030 <dep package="scrollkeeper"/>
1031 </dependencies>
1032 </autotools>
1033 <autotools id="gnome-speech">
1034 <branch/>
1035 <dependencies>
1036 <dep package="libbonobo"/>
1037 </dependencies>
1038 </autotools>
1039 <autotools id="gnopernicus">
1040 <branch revision="gnome-2-12"/>
1041 <dependencies>
1042 <dep package="gconf"/>
1043 <dep package="libgnomeui"/>
1044 <dep package="gnome-speech"/>
1045 <dep package="gnome-mag"/>
1046 </dependencies>
1047 </autotools>
1048 <autotools id="dasher" autogenargs="--with-a11y --with-gnome">
1049 <branch revision="gnome-2-12"/>
1050 <dependencies>
1051 <dep package="at-spi"/>
1052 <dep package="libgnomeui"/>
1053 <dep package="gnome-speech"/>
1054 <dep package="gnome-vfs"/>
1055 </dependencies>
1056 </autotools>
1057 <autotools id="gnome-screensaver">
1058 <branch/>
1059 <dependencies>
1060 <dep package="gconf"/>
1061 <dep package="gtk+"/>
1062 <dep package="dbus"/>
1063 </dependencies>
1064 </autotools>
1065 <autotools id="gnome-power-manager">
1066 <branch/>
1067 <dependencies>
1068 <dep package="libgnomeui"/>
1069 <dep package="hal"/>
1070 <dep package="libwnck"/>
1071 <dep package="gtk+"/>
1072 <dep package="gconf"/>
1073 <dep package="intltool"/>
1074 <dep package="libglade"/>
1075 <dep package="libnotify"/>
1076 </dependencies>
1077 </autotools>
1078 <autotools id="gthumb">
1079 <branch/>
1080 <dependencies>
1081 <dep package="libgnomeui"/>
1082 <dep package="gnome-vfs"/>
1083 <dep package="libglade"/>
1084 <dep package="libbonoboui"/>
1085 <dep package="libgnomeprintui"/>
1086 </dependencies>
1087 </autotools>
1088 <autotools id="fast-user-switch-applet">
1089 <branch/>
1090 <dependencies>
1091 <dep package="gtk+"/>
1092 <dep package="gconf"/>
1093 <dep package="libglade"/>
1094 <dep package="gnome-panel"/>
1095 </dependencies>
1096 </autotools>
1097 <autotools id="libnotify">
1098 <branch repo="svn.galago-project.org" module="trunk/libnotify"/>
1099 <dependencies>
1100 <dep package="gtk+"/>
1101 <dep package="dbus"/>
1102 </dependencies>
1103 </autotools>
1104
1105 <metamodule id="meta-gnome-devel-platform">
1106 <dependencies>
1107 <dep package="libgnome"/>
1108 <dep package="libbonobo"/>
1109 <dep package="libbonoboui"/>
1110 <dep package="libgnomeui"/>
1111 </dependencies>
1112 </metamodule>
1113 <metamodule id="meta-gnome-core">
1114 <dependencies>
1115 <dep package="gnome-desktop"/>
1116 <dep package="gnome-panel"/>
1117 <dep package="gnome-session"/>
1118 <dep package="gnome-terminal"/>
1119 <dep package="gnome-applets"/>
1120 </dependencies>
1121 </metamodule>
1122 <metamodule id="meta-nautilus">
1123 <dependencies>
1124 <dep package="nautilus"/>
1125 </dependencies>
1126 </metamodule>
1127 <metamodule id="meta-gnome-desktop">
1128 <dependencies>
1129 <dep package="meta-gnome-core"/>
1130 <dep package="gnome-control-center"/>
1131 <dep package="meta-nautilus"/>
1132 <dep package="yelp"/>
1133 <dep package="bug-buddy"/>
1134 <dep package="gedit"/>
1135 <dep package="gtk-engines"/>
1136 <dep package="eog"/>
1137 <dep package="metacity"/>
1138 <dep package="gconf-editor"/>
1139 <dep package="gnome-utils"/>
1140 <dep package="gnome-system-monitor"/>
1141 <dep package="gstreamer"/>
1142 <dep package="gnome-media"/>
1143 <dep package="gnome-netstatus"/>
1144 <dep package="gcalctool"/>
1145 <dep package="gucharmap"/>
1146 <dep package="nautilus-cd-burner"/>
1147 <dep package="zenity"/>
1148 <dep package="libgail-gnome"/>
1149 <dep package="gnopernicus"/>
1150 <dep package="gok"/>
1151 <dep package="epiphany"/>
1152 <dep package="gnome-games"/>
1153 <dep package="gnome-user-docs"/>
1154 <dep package="file-roller"/>
1155 <dep package="gnome-system-tools"/>
1156 <dep package="gnome-nettool"/>
1157 <dep package="vino"/>
1158 <dep package="gnome-volume-manager"/>
1159 <dep package="totem"/>
1160 <dep package="gnome-menus"/>
1161 <dep package="gnome-backgrounds"/>
1162 <dep package="sound-juicer"/>
1163 <dep package="evolution"/>
1164 <dep package="evolution-webcal"/>
1165 <dep package="evolution-exchange"/>
1166 <dep package="ekiga"/>
1167 <dep package="evince"/>
1168 <dep package="dasher"/>
1169 <dep package="gnome-keyring-manager"/>
1170 </dependencies>
1171 </metamodule>
1172 <metamodule id="meta-gnome-devel-tools">
1173 <dependencies>
1174 <dep package="glade"/>
1175 <dep package="memprof"/>
1176 <dep package="gconf-editor"/>
1177 <dep package="devhelp"/>
1178 <dep package="nautilus-vcs"/>
1179 </dependencies>
1180 </metamodule>
1181 <metamodule id="meta-gnome-python">
1182 <dependencies>
1183 <dep package="pygtk"/>
1184 <dep package="gnome-python"/>
1185 </dependencies>
1186 <after>
1187 <dep package="gnome-python-extras"/>
1188 </after>
1189 </metamodule>
1190 <metamodule id="meta-gnome-c++">
1191 <dependencies>
1192 <dep package="gtkmm"/>
1193 <dep package="gnomemm/libgnomeuimm"/>
1194 <dep package="gnomemm/gnome-vfsmm"/>
1195 <dep package="gnomemm/libpanelappletmm"/>
1196 <dep package="gnomemm/libbonobouimm"/>
1197 <dep package="gnomemm/libgnomeprintuimm"/>
1198 <dep package="libxml++"/>
1199 <dep package="gnomemm/libgdamm"/>
1200 <dep package="bakery"/>
1201 </dependencies>
1202 </metamodule>
1203 <metamodule id="meta-gnome-accessibility">
1204 <dependencies>
1205 <dep package="libgail-gnome"/>
1206 <dep package="at-poke"/>
1207 <dep package="dasher"/>
1208 <dep package="gnome-mag"/>
1209 <dep package="gok"/>
1210 <dep package="gnome-speech"/>
1211 <dep package="gnopernicus"/>
1212 </dependencies>
1213 </metamodule>
1214 <metamodule id="meta-gnome-proposed">
1215 <dependencies>
1216 </dependencies>
1217 </metamodule>
1218 <autotools id="sodipodi">
1219 <branch/>
1220 <dependencies>
1221 <dep package="gtk+"/>
1222 <dep package="libgnomeprintui"/>
1223 <dep package="libart_lgpl"/>
1224 <dep package="libxml2"/>
1225 </dependencies>
1226 </autotools>
1227 <autotools id="gnome-themes">
1228 <branch revision="gnome-2-12"/>
1229 <dependencies>
1230 <dep package="gtk-engines"/>
1231 </dependencies>
1232 </autotools>
1233 <autotools id="gob">
1234 <branch/>
1235 </autotools>
1236 <autotools id="libgnetwork">
1237 <branch/>
1238 <dependencies>
1239 <dep package="glib"/>
1240 <dep package="gconf"/>
1241 <dep package="intltool"/>
1242 </dependencies>
1243 </autotools>
1244 <autotools id="libgircclient">
1245 <branch/>
1246 <dependencies>
1247 <dep package="libgnetwork"/>
1248 </dependencies>
1249 </autotools>
1250 <autotools id="gnomechat">
1251 <branch/>
1252 <dependencies>
1253 <dep package="libgnetwork"/>
1254 <dep package="libgircclient"/>
1255 <dep package="libgnomeui"/>
1256 </dependencies>
1257 </autotools>
1258 <mozillamodule id="mozilla" autogenargs="--enable-default-toolkit=gtk2 --disable-mailnews --disable-ldap --disable-debug --enable-optimize --disable-tests --enable-crypto --enable-xft --with-system-zlib --disable-freetype2 --enable-application=browser" cvsroot="mozilla.org" revision="MOZILLA_1_7_BRANCH">
1259 <dependencies>
1260 <dep package="gtk+"/>
1261 </dependencies>
1262 </mozillamodule>
1263 <autotools id="epiphany">
1264 <branch revision="gnome-2-12"/>
1265 <dependencies>
1266 <dep package="iso-codes"/>
1267 <dep package="libgnomeui"/>
1268 <dep package="pygtk"/>
1269 <dep package="gnome-python"/>
1270 <dep package="gnome-doc-utils"/>
1271 <dep package="libgnomeprintui"/>
1272 <dep package="mozilla"/>
1273 </dependencies>
1274 </autotools>
1275 <autotools id="epiphany-extensions">
1276 <branch revision="gnome-2-12"/>
1277 <dependencies>
1278 <dep package="epiphany"/>
1279 </dependencies>
1280 </autotools>
1281 <autotools id="galeon">
1282 <branch/>
1283 <dependencies>
1284 <dep package="mozilla"/>
1285 <dep package="libgnomeui"/>
1286 </dependencies>
1287 </autotools>
1288 <autotools id="libsoup">
1289 <branch revision="gnome-2-12"/>
1290 <dependencies>
1291 <dep package="glib"/>
1292 <dep package="gnutls"/>
1293 <dep package="libxml2"/>
1294 </dependencies>
1295 </autotools>
1296 <autotools id="gtkhtml">
1297 <branch revision="gnome-2-12"/>
1298 <dependencies>
1299 <dep package="gtk+"/>
1300 <dep package="libgnomeui"/>
1301 <dep package="libbonoboui"/>
1302 <dep package="libglade"/>
1303 <dep package="gail"/>
1304 <dep package="libgnomeprint"/>
1305 <dep package="libgnomeprintui"/>
1306 <dep package="libsoup"/>
1307 </dependencies>
1308 </autotools>
1309 <autotools id="evolution-data-server" supports-non-srcdir-builds="no">
1310 <branch revision="gnome-2-12"/>
1311 <dependencies>
1312 <dep package="libbonobo"/>
1313 <dep package="libgnome"/>
1314 <dep package="libgnomeui"/>
1315 <dep package="libsoup"/>
1316 <dep package="libxml2"/>
1317 <dep package="gconf"/>
1318 <dep package="gnome-vfs"/>
1319 <dep package="mozilla"/>
1320 </dependencies>
1321 </autotools>
1322 <autotools id="evolution">
1323 <branch revision="gnome-2-12"/>
1324 <dependencies>
1325 <dep package="evolution-data-server"/>
1326 <dep package="gtkhtml"/>
1327 <dep package="libgnomeui"/>
1328 <dep package="libbonoboui"/>
1329 </dependencies>
1330 </autotools>
1331 <autotools id="evolution-webcal">
1332 <branch/>
1333 <dependencies>
1334 <dep package="evolution-data-server"/>
1335 <dep package="libsoup"/>
1336 <dep package="libgnomeui"/>
1337 </dependencies>
1338 </autotools>
1339 <autotools id="evolution-exchange">
1340 <branch revision="gnome-2-12"/>
1341 <dependencies>
1342 <dep package="evolution-data-server"/>
1343 <dep package="evolution"/>
1344 <dep package="libsoup"/>
1345 </dependencies>
1346 </autotools>
1347 <tarball id="xchat" version="2.4.5">
1348 <source href="http://xchat.org/files/source/2.4/xchat-2.4.5.tar.bz2"
1349 size="1324626" md5sum="9107a92693e6c62ff2008030e698b92b"/>
1350 <dependencies>
1351 <dep package="gtk+"/>
1352 <dep package="libxml2"/>
1353 </dependencies>
1354 </tarball>
1355 <tarball id="camorama" version="0.17">
1356 <source href="http://camorama.fixedgear.org/downloads/camorama-0.17.tar.bz2"
1357 size="312233" md5sum="2b2784af53a1ba8fa4419aa806967b35"/>
1358 <dependencies>
1359 <dep package="gtk+"/>
1360 </dependencies>
1361 </tarball>
1362 <autotools id="gtk-engines-cleanice">
1363 <branch repo="elysium-project.sf.net"/>
1364 <dependencies>
1365 <dep package="gtk+"/>
1366 </dependencies>
1367 </autotools>
1368 <autotools id="gaim">
1369 <branch repo="gaim.sf.net"/>
1370 <dependencies>
1371 <dep package="libgnomeui"/>
1372 </dependencies>
1373 </autotools>
1374 <autotools id="zenity">
1375 <branch revision="gnome-2-12"/>
1376 <dependencies>
1377 <dep package="gtk+"/>
1378 <dep package="gconf"/>
1379 <dep package="libgnomecanvas"/>
1380 <dep package="gnome-doc-utils"/>
1381 </dependencies>
1382 </autotools>
1383 <autotools id="gpdf">
1384 <branch/>
1385 <dependencies>
1386 <dep package="libgnomeui"/>
1387 <dep package="libbonoboui"/>
1388 <dep package="libgnomeprintui"/>
1389 </dependencies>
1390 </autotools>
1391 <autotools id="gnome-netstatus">
1392 <branch/>
1393 <dependencies>
1394 <dep package="libgnomeui"/>
1395 <dep package="gnome-panel"/>
1396 <dep package="gnome-doc-utils"/>
1397 </dependencies>
1398 </autotools>
1399 <autotools id="gnome-doc-utils">
1400 <branch revision="gnome-2-12"/>
1401 <dependencies>
1402 <dep package="libxslt"/>
1403 <dep package="intltool"/>
1404 <dep package="glib"/>
1405 </dependencies>
1406 </autotools>
1407 <tarball id="libmusicbrainz" version="2.1.1">
1408 <source href="ftp://ftp.musicbrainz.org/pub/musicbrainz/libmusicbrainz-2.1.1.tar.gz"
1409 size="528162" md5sum="4f753d93a85cf413e00f1394b8cbd269"/>
1410 </tarball>
1411 <autotools id="totem" autogenargs="--enable-gstreamer">
1412 <branch revision="gnome-2-12"/>
1413 <dependencies>
1414 <dep package="gnome-desktop"/>
1415 <dep package="nautilus-cd-burner"/>
1416 <dep package="gstreamer"/>
1417 <dep package="gst-plugins"/>
1418 <dep package="libmusicbrainz"/>
1419 <dep package="iso-codes"/>
1420 </dependencies>
1421 </autotools>
1422 <autotools id="gnome-themes-extras">
1423 <branch/>
1424 <dependencies>
1425 <dep package="gnome-themes"/>
1426 </dependencies>
1427 </autotools>
1428 <autotools id="libgda">
1429 <branch module="libgda"/>
1430 <dependencies>
1431 <dep package="glib"/>
1432 </dependencies>
1433 </autotools>
1434 <autotools id="libgnomedb" autogenargs="--enable-gnome=yes">
1435 <branch/>
1436 <dependencies>
1437 <dep package="libgda"/>
1438 <dep package="libgnomeui"/>
1439 <dep package="libbonoboui"/>
1440 </dependencies>
1441 </autotools>
1442 <autotools id="mergeant">
1443 <branch/>
1444 <dependencies>
1445 <dep package="libgnomedb"/>
1446 </dependencies>
1447 </autotools>
1448 <autotools id="gtranslator">
1449 <branch/>
1450 <dependencies>
1451 <dep package="libgnomeui"/>
1452 </dependencies>
1453 </autotools>
1454 <autotools id="gnome-spell">
1455 <branch/>
1456 <dependencies>
1457 <dep package="libgnomeui"/>
1458 </dependencies>
1459 </autotools>
1460 <autotools id="libgnomecups">
1461 <branch/>
1462 <dependencies>
1463 <dep package="glib"/>
1464 </dependencies>
1465 </autotools>
1466 <autotools id="gnome-cups-manager">
1467 <branch/>
1468 <dependencies>
1469 <dep package="libgnomecups"/>
1470 <dep package="libgnomeui"/>
1471 <dep package="libglade"/>
1472 </dependencies>
1473 </autotools>
1474 <autotools id="libxml++">
1475 <branch revision="gnome-2-12"/>
1476 <dependencies>
1477 <dep package="libxml2"/>
1478 <dep package="glibmm"/>
1479 </dependencies>
1480 </autotools>
1481 <autotools id="bakery">
1482 <branch/>
1483 <dependencies>
1484 <dep package="libxml++"/>
1485 <dep package="gtkmm"/>
1486 <dep package="gnomemm/libglademm"/>
1487 <dep package="gnomemm/gconfmm"/>
1488 <dep package="gnomemm/gnome-vfsmm"/>
1489 </dependencies>
1490 </autotools>
1491 <autotools id="gnome-hello">
1492 <branch/>
1493 <dependencies>
1494 <dep package="glib"/>
1495 <dep package="libgnome"/>
1496 <dep package="libgnomeui"/>
1497 </dependencies>
1498 </autotools>
1499 <autotools id="gnome-system-tools">
1500 <branch revision="gnome-2-12"/>
1501 <dependencies>
1502 <dep package="glib"/>
1503 <dep package="libxml2"/>
1504 <dep package="gconf"/>
1505 <dep package="libgnomeui"/>
1506 <dep package="libbonoboui"/>
1507 <dep package="libglade"/>
1508 <dep package="nautilus"/>
1509 <dep package="system-tools-backends"/>
1510 </dependencies>
1511 </autotools>
1512 <autotools id="gnome-user-docs">
1513 <branch/>
1514 <dependencies>
1515 <dep package="scrollkeeper"/>
1516 </dependencies>
1517 </autotools>
1518 <autotools id="loudmouth">
1519 <branch/>
1520 <dependencies>
1521 <dep package="glib"/>
1522 </dependencies>
1523 </autotools>
1524 <autotools id="gossip">
1525 <branch revision="gossip-0-8"/>
1526 <dependencies>
1527 <dep package="loudmouth"/>
1528 <dep package="libgnomeui"/>
1529 </dependencies>
1530 </autotools>
1531 <autotools id="conglomerate">
1532 <branch/>
1533 <dependencies>
1534 <dep package="libxslt"/>
1535 <dep package="gconf"/>
1536 <dep package="libgnomeui"/>
1537 </dependencies>
1538 </autotools>
1539 <autotools id="sound-juicer">
1540 <branch revision="gnome-2-12"/>
1541 <dependencies>
1542 <dep package="gnome-doc-utils"/>
1543 <dep package="libgnomeui"/>
1544 <dep package="gnome-media"/>
1545 <dep package="gstreamer"/>
1546 <dep package="gst-plugins"/>
1547 <dep package="nautilus-cd-burner"/>
1548 </dependencies>
1549 </autotools>
1550 <autotools id="gnome-network">
1551 <branch/>
1552 <dependencies>
1553 <dep package="glib"/>
1554 </dependencies>
1555 </autotools>
1556 <tarball id="guile" version="1.6.7">
1557 <source href="ftp://ftp.gnu.org/gnu/guile/guile-1.6.7.tar.gz"
1558 size="3039294" md5sum="c2ff2a2231f0cbb2e838dd8701a587c5"/>
1559 </tarball>
1560 <tarball id="autogen" version="5.6.5">
1561 <source href="http://internap.dl.sourceforge.net/sourceforge/autogen/autogen-5.6.5.tar.gz"
1562 size="1144260" md5sum="54a6cb0be7e6b526af9aba4a73013885"/>
1563 <dependencies>
1564 <dep package="guile"/>
1565 </dependencies>
1566 </tarball>
1567 <autotools id="anjuta">
1568 <branch/>
1569 <dependencies>
1570 <dep package="libbonoboui"/>
1571 <dep package="libgnomeprintui"/>
1572 <dep package="vte"/>
1573 <dep package="gnome-build"/>
1574 <dep package="autogen"/>
1575 </dependencies>
1576 </autotools>
1577 <autotools id="OpenApplet">
1578 <branch/>
1579 <dependencies>
1580 <dep package="gnome-panel"/>
1581 </dependencies>
1582 </autotools>
1583 <autotools id="gtetrinet">
1584 <branch/>
1585 <dependencies>
1586 <dep package="libgnomeui"/>
1587 </dependencies>
1588 </autotools>
1589 <autotools id="glom">
1590 <branch/>
1591 <dependencies>
1592 <dep package="gnomemm/libgdamm"/>
1593 <dep package="bakery"/>
1594 <dep package="gnomemm/libgnomecanvasmm"/>
1595 <dep package="libgnome"/>
1596 <dep package="iso-codes"/>
1597 <dep package="pygtk"/>
1598 <dep package="gnome-python-extras"/>
1599 </dependencies>
1600 </autotools>
1601 <autotools id="vino">
1602 <branch revision="gnome-2-12"/>
1603 <dependencies>
1604 <dep package="libgnomeui"/>
1605 <dep package="libglade"/>
1606 <dep package="gconf"/>
1607 <dep package="gnutls"/>
1608 </dependencies>
1609 </autotools>
1610 <autotools id="gnome-keyring-manager" autogenargs="--disable-more-warnings">
1611 <branch revision="gnome-2-12"/>
1612 <dependencies>
1613 <dep package="libgnomeui"/>
1614 <dep package="gnome-keyring"/>
1615 <dep package="gconf"/>
1616 </dependencies>
1617 </autotools>
1618 <autotools id="gnome-volume-manager">
1619 <branch revision="gnome-2-12"/>
1620 <dependencies>
1621 <dep package="libgnomeui"/>
1622 <dep package="libglade"/>
1623 <dep package="hal"/>
1624 </dependencies>
1625 </autotools>
1626 <metamodule id="meta-storage">
1627 <dependencies>
1628 <dep package="storage/storage-store"/>
1629 <dep package="storage/vfs"/>
1630 <dep package="storage/applet"/>
1631 </dependencies>
1632 </metamodule>
1633 <autotools id="storage/storage-store">
1634 <branch/>
1635 <dependencies>
1636 <dep package="dbus"/>
1637 </dependencies>
1638 </autotools>
1639 <autotools id="storage/libstorage">
1640 <branch/>
1641 <dependencies>
1642 <dep package="gnome-vfs"/>
1643 <dep package="pygtk"/>
1644 </dependencies>
1645 </autotools>
1646 <autotools id="storage/libstorage-translators">
1647 <branch/>
1648 <dependencies>
1649 <dep package="storage/libstorage"/>
1650 </dependencies>
1651 </autotools>
1652 <autotools id="storage/vfs">
1653 <branch/>
1654 <dependencies>
1655 <dep package="storage/libstorage"/>
1656 <dep package="storage/libstorage-translators"/>
1657 </dependencies>
1658 </autotools>
1659 <autotools id="storage/pet">
1660 <branch/>
1661 </autotools>
1662 <autotools id="storage/libmrs">
1663 <branch/>
1664 <dependencies>
1665 <dep package="storage/pet"/>
1666 </dependencies>
1667 </autotools>
1668 <autotools id="storage/libmrs-converter">
1669 <branch/>
1670 <dependencies>
1671 <dep package="storage/libmrs"/>
1672 </dependencies>
1673 </autotools>
1674 <autotools id="storage/libstorage-nl">
1675 <branch/>
1676 <dependencies>
1677 <dep package="storage/libstorage"/>
1678 <dep package="storage/libmrs"/>
1679 <dep package="storage/libmrs-converter"/>
1680 </dependencies>
1681 </autotools>
1682 <autotools id="storage/applet">
1683 <branch/>
1684 <dependencies>
1685 <dep package="gnome-python"/>
1686 <dep package="storage/libstorage-nl"/>
1687 </dependencies>
1688 </autotools>
1689 <autotools id="gnome-nettool">
1690 <branch/>
1691 <dependencies>
1692 <dep package="libgnomeui"/>
1693 </dependencies>
1694 </autotools>
1695 <autotools id="monkey-bubble">
1696 <branch/>
1697 <dependencies>
1698 <dep package="gstreamer"/>
1699 <dep package="gst-plugins"/>
1700 <dep package="libxml2"/>
1701 <dep package="gconf"/>
1702 <dep package="librsvg"/>
1703 <dep package="libgnomeui"/>
1704 </dependencies>
1705 </autotools>
1706 <autotools id="gnome-schedule">
1707 <branch/>
1708 <dependencies>
1709 <dep package="pygtk"/>
1710 <dep package="yelp"/>
1711 </dependencies>
1712 </autotools>
1713 <autotools id="gnome-backgrounds">
1714 <branch/>
1715 </autotools>
1716 <autotools id="evince">
1717 <branch revision="gnome-2-12"/>
1718 <dependencies>
1719 <dep package="libgnomeui"/>
1720 <dep package="libgnomeprintui"/>
1721 <dep package="poppler-0-4"/>
1722 <dep package="gnome-doc-utils"/>
1723 </dependencies>
1724 </autotools>
1725 <autotools id="nautilus-python" supports-non-srcdir-builds="no">
1726 <branch/>
1727 <dependencies>
1728 <dep package="nautilus"/>
1729 <dep package="pygtk"/>
1730 <dep package="gnome-python"/>
1731 </dependencies>
1732 </autotools>
1733 <autotools id="gst-python" autogenargs="--" supports-non-srcdir-builds="no">
1734 <branch repo="gstreamer.freedesktop.org" revision="BRANCH-GSTREAMER-0_8"/>
1735 <dependencies>
1736 <dep package="gstreamer"/>
1737 <dep package="gst-plugins"/>
1738 </dependencies>
1739 </autotools>
1740 <autotools id="inkscape">
1741 <branch repo="inkscape.sf.net"/>
1742 <dependencies>
1743 <dep package="gtkmm"/>
1744 <dep package="libxslt"/>
1745 </dependencies>
1746 </autotools>
1747</moduleset>
diff --git a/scripts/jhbuild/modulesets/gnome-2.14.modules b/scripts/jhbuild/modulesets/gnome-2.14.modules
new file mode 100644
index 0000000000..7d3b8fc9fb
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gnome-2.14.modules
@@ -0,0 +1,2013 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="gnome.org" default="yes"
5 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
6 password=""/>
7 <repository type="cvs" name="cairo.freedesktop.org"
8 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/cairo"
9 password=""/>
10 <repository type="cvs" name="mozilla.org"
11 cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
12 password="anonymous"/>
13 <repository type="cvs" name="liboil.freedesktop.org"
14 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/liboil"
15 password=""/>
16 <repository type="cvs" name="gstreamer.freedesktop.org"
17 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/gstreamer"
18 password=""/>
19 <repository type="cvs" name="menu.freedesktop.org"
20 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/menus"
21 password=""/>
22 <repository type="cvs" name="mime.freedesktop.org"
23 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/mime"
24 password=""/>
25 <repository type="cvs" name="xklavier.freedesktop.org"
26 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/xklavier"
27 password=""/>
28
29 <repository type="cvs" name="elysium-project.sf.net"
30 cvsroot=":pserver:anonymous@elysium-project.cvs.sourceforge.net:/cvsroot/elysium-project"
31 password=""/>
32 <repository type="cvs" name="gaim.sf.net"
33 cvsroot=":pserver:anonymous@gaim.cvs.sourceforge.net:/cvsroot/gaim"
34 password=""/>
35 <repository type="cvs" name="inkscape.sf.net"
36 cvsroot=":pserver:anonymous@inkscape.cvs.sourceforge.net:/cvsroot/inkscape"
37 password=""/>
38 <repository type="svn" name="svn.galago-project.org"
39 href="http://svn.galago-project.org/"/>
40 <repository type="svn" name="osiris.chipx86.com"
41 href="http://osiris.chipx86.com/svn/osiris-misc/"/>
42 <repository type="svn" name="svn.debian.org"
43 href="svn://svn.debian.org/"/>
44 <repository type="cvs" name="openh323.sf.net"
45 cvsroot=":pserver:anonymous@openh323.cvs.sourceforge.net:/cvsroot/openh323"
46 password="" />
47
48 <tarball id="scrollkeeper" version="0.3.14" supports-non-srcdir-builds="no">
49 <source href="http://easynews.dl.sourceforge.net/sourceforge/scrollkeeper/scrollkeeper-0.3.14.tar.gz"
50 size="679513" md5sum="161eb3f29e30e7b24f84eb93ac696155"/>
51 <dependencies>
52 <dep package="libxml2"/>
53 <dep package="libxslt"/>
54 <dep package="intltool"/>
55 </dependencies>
56 <patches>
57 <patch file="scrollkeeper_clean_xml_validation_context.patch" strip="1"/>
58 <patch file="scrollkeeper_language_fix.patch" strip="1"/>
59 <patch file="scrollkeeper_rw_offset_fix.patch" strip="1"/>
60 </patches>
61 </tarball>
62
63 <autotools id="iso-codes">
64 <branch repo="svn.debian.org" module="pkg-isocodes/trunk/iso-codes" checkoutdir="iso-codes"/>
65 </autotools>
66
67 <include href="freedesktop.modules"/>
68 <include href="gnutls.modules"/>
69
70 <autotools id="cairo-gtk-engine">
71 <branch repo="cairo.freedesktop.org"/>
72 <dependencies>
73 <dep package="gtk+"/>
74 <dep package="cairo-1-0"/>
75 </dependencies>
76 </autotools>
77
78 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
79 <branch repo="mime.freedesktop.org"/>
80 <dependencies>
81 <dep package="intltool"/>
82 <dep package="libxml2"/>
83 <dep package="glib"/>
84 </dependencies>
85 </autotools>
86
87 <autotools id="desktop-file-utils">
88 <branch repo="menu.freedesktop.org"/>
89 <dependencies>
90 <dep package="glib"/>
91 <dep package="intltool"/>
92 </dependencies>
93 </autotools>
94
95 <autotools id="libxklavier" supports-non-srcdir-builds="no">
96 <branch repo="xklavier.freedesktop.org" revision="v_2_x"/>
97 <dependencies>
98 <dep package="libxml2"/>
99 </dependencies>
100 </autotools>
101 <autotools id="libbtctl">
102 <branch/>
103 <dependencies>
104 <dep package="gtk+"/>
105 <dep package="glib"/>
106 </dependencies>
107 </autotools>
108 <autotools id="gnome-bluetooth">
109 <branch/>
110 <dependencies>
111 <dep package="gtk+"/>
112 <dep package="glib"/>
113 <dep package="libbtctl"/>
114 <dep package="libglade"/>
115 <dep package="libgnomeui"/>
116 <dep package="gconf"/>
117 </dependencies>
118 </autotools>
119 <autotools id="phonemgr">
120 <branch/>
121 <dependencies>
122 <dep package="gtk+"/>
123 <dep package="glib"/>
124 <dep package="libbtctl"/>
125 <dep package="gnome-bluetooth"/>
126 <dep package="libglade"/>
127 <dep package="libgnomeui"/>
128 <dep package="libgnome"/>
129 <dep package="gconf"/>
130 </dependencies>
131 </autotools>
132
133 <autotools id="intltool">
134 <branch/>
135 <dependencies>
136 <dep package="gnome-common"/>
137 </dependencies>
138 </autotools>
139 <autotools id="gnome-common">
140 <branch/>
141 </autotools>
142 <autotools id="libxml2">
143 <branch module="gnome-xml" checkoutdir="libxml2"/>
144 </autotools>
145 <autotools id="libxslt">
146 <branch/>
147 <dependencies>
148 <dep package="libxml2"/>
149 </dependencies>
150 </autotools>
151 <autotools id="gtk-doc">
152 <branch/>
153 <dependencies>
154 <dep package="libxslt"/>
155 <dep package="scrollkeeper"/>
156 </dependencies>
157 </autotools>
158 <autotools id="gamin">
159 <branch/>
160 <dependencies>
161 <dep package="glib"/>
162 </dependencies>
163 </autotools>
164 <autotools id="glib">
165 <branch revision="glib-2-10"/>
166 <dependencies>
167 <dep package="gtk-doc"/>
168 </dependencies>
169 </autotools>
170 <autotools id="pango">
171 <branch revision="pango-1-12"/>
172 <dependencies>
173 <dep package="glib"/>
174 <dep package="cairo-1-0"/>
175 <dep package="libXft"/>
176 </dependencies>
177 </autotools>
178 <autotools id="atk">
179 <branch revision="gnome-2-14"/>
180 <dependencies>
181 <dep package="glib"/>
182 </dependencies>
183 </autotools>
184 <autotools id="gtk+">
185 <branch revision="gtk-2-8"/>
186 <dependencies>
187 <dep package="cairo-1-0"/>
188 <dep package="pango"/>
189 <dep package="atk"/>
190 <dep package="shared-mime-info"/>
191 </dependencies>
192 </autotools>
193 <autotools id="gail">
194 <branch/>
195 <dependencies>
196 <dep package="gtk+"/>
197 <dep package="atk"/>
198 <dep package="libgnomecanvas"/>
199 </dependencies>
200 </autotools>
201 <autotools id="gtkhtml2">
202 <branch/>
203 <dependencies>
204 <dep package="gtk+"/>
205 <dep package="libxml2"/>
206 <dep package="gail"/>
207 </dependencies>
208 </autotools>
209 <autotools id="libIDL">
210 <branch/>
211 <dependencies>
212 <dep package="glib"/>
213 </dependencies>
214 </autotools>
215 <autotools id="ORBit2">
216 <branch/>
217 <dependencies>
218 <dep package="libIDL"/>
219 <dep package="gnome-common"/>
220 </dependencies>
221 </autotools>
222 <autotools id="gconf">
223 <branch/>
224 <dependencies>
225 <dep package="ORBit2"/>
226 <dep package="libxml2"/>
227 <dep package="gtk+"/>
228 </dependencies>
229 </autotools>
230 <autotools id="libbonobo">
231 <branch revision="gnome-2-14"/>
232 <dependencies>
233 <dep package="ORBit2"/>
234 <dep package="intltool"/>
235 <dep package="gnome-common"/>
236 <dep package="libxml2"/>
237 </dependencies>
238 </autotools>
239 <autotools id="gnome-mime-data">
240 <branch/>
241 <dependencies>
242 <dep package="gnome-common"/>
243 <dep package="glib"/>
244 </dependencies>
245 </autotools>
246 <autotools id="gnome-icon-theme">
247 <branch revision="gnome-2-14"/>
248 <dependencies>
249 <dep package="hicolor-icon-theme"/>
250 </dependencies>
251 </autotools>
252 <tarball id="howl" version="1.0.0">
253 <source href="http://www.porchdogsoft.com/download/howl-1.0.0.tar.gz"
254 size="542782" md5sum="c389d3ffba0e69a179de2ec650f1fdcc"/>
255 <patches>
256 <patch file="howl-1.0.0-buildfix.patch" strip="1"/>
257 </patches>
258 </tarball>
259 <autotools id="gnome-vfs">
260 <branch revision="gnome-2-14"/>
261 <dependencies>
262 <dep package="libbonobo"/>
263 <dep package="gconf"/>
264 <dep package="desktop-file-utils"/>
265 <dep package="shared-mime-info"/>
266 <dep package="gnome-mime-data"/>
267 <dep package="howl"/>
268 <dep package="hal"/>
269 <dep package="gamin"/>
270 </dependencies>
271 </autotools>
272 <autotools id="gnome-keyring">
273 <branch revision="gnome-2-14"/>
274 <dependencies>
275 <dep package="gtk+"/>
276 </dependencies>
277 </autotools>
278 <autotools id="libart_lgpl">
279 <branch/>
280 </autotools>
281 <autotools id="libgnome">
282 <branch revision="gnome-2-14"/>
283 <dependencies>
284 <dep package="libxml2"/>
285 <dep package="libxslt"/>
286 <dep package="libbonobo"/>
287 <dep package="gnome-vfs"/>
288 <dep package="gconf"/>
289 <dep package="esound"/>
290 </dependencies>
291 </autotools>
292 <autotools id="libgnomecanvas">
293 <branch/>
294 <dependencies>
295 <dep package="gtk+"/>
296 <dep package="libart_lgpl"/>
297 <dep package="libglade"/>
298 <dep package="gnome-common"/>
299 </dependencies>
300 </autotools>
301 <autotools id="libbonoboui">
302 <branch/>
303 <dependencies>
304 <dep package="libgnome"/>
305 <dep package="libbonobo"/>
306 <dep package="libgnomecanvas"/>
307 <dep package="libglade"/>
308 </dependencies>
309 </autotools>
310 <autotools id="libgnomeui">
311 <branch revision="libgnomeui-2-14"/>
312 <dependencies>
313 <dep package="libbonoboui"/>
314 <dep package="libglade"/>
315 <dep package="gnome-icon-theme"/>
316 <dep package="gnome-keyring"/>
317 </dependencies>
318 </autotools>
319 <autotools id="libglade">
320 <branch/>
321 <dependencies>
322 <dep package="gtk+"/>
323 <dep package="libxml2"/>
324 </dependencies>
325 </autotools>
326 <autotools id="pygobject">
327 <branch revision="pygobject-2-10"/>
328 <dependencies>
329 <dep package="glib"/>
330 </dependencies>
331 </autotools>
332 <autotools id="pygtk">
333 <branch revision="pygtk-2-8"/>
334 <dependencies>
335 <dep package="pygobject"/>
336 <dep package="gtk+"/>
337 <dep package="pycairo-1-0"/>
338 <dep package="libglade"/>
339 </dependencies>
340 </autotools>
341 <autotools id="pyorbit">
342 <branch/>
343 <dependencies>
344 <dep package="ORBit2"/>
345 </dependencies>
346 </autotools>
347 <autotools id="gnome-python">
348 <branch revision="gnome-python-2-12"/>
349 <dependencies>
350 <dep package="pygtk"/>
351 <dep package="pyorbit"/>
352 <dep package="libgnomecanvas"/>
353 <dep package="libgnomeui"/>
354 </dependencies>
355 </autotools>
356 <autotools id="gnome-python-desktop">
357 <branch revision="gnome-2-14"/>
358 <dependencies>
359 <dep package="gnome-python"/>
360 <dep package="gnome-panel"/>
361 <dep package="libgnomeprint"/>
362 <dep package="libgnomeprintui"/>
363 <dep package="gtksourceview"/>
364 <dep package="libwnck"/>
365 <dep package="totem"/>
366 <dep package="libgtop"/>
367 <dep package="nautilus-cd-burner"/>
368 <dep package="gnome-media"/>
369 <dep package="metacity"/>
370 </dependencies>
371 </autotools>
372 <autotools id="gnome-python-extras">
373 <branch/>
374 <dependencies>
375 <dep package="pygtk"/>
376 <dep package="gnome-python"/>
377 <dep package="gtkhtml2"/>
378 <dep package="gdl"/>
379 </dependencies>
380 </autotools>
381 <autotools id="bug-buddy">
382 <branch/>
383 <dependencies>
384 <dep package="libgnomeui"/>
385 <dep package="gnome-menus"/>
386 <dep package="gnome-doc-utils"/>
387 </dependencies>
388 </autotools>
389 <autotools id="libwnck">
390 <branch/>
391 <dependencies>
392 <dep package="gtk+"/>
393 <dep package="startup-notification"/>
394 </dependencies>
395 </autotools>
396 <autotools id="gnome-desktop" autogenargs="--with-gnome-distributor=JHBuild">
397 <branch revision="gnome-2-14"/>
398 <dependencies>
399 <dep package="libgnomeui"/>
400 <dep package="startup-notification"/>
401 <dep package="gnome-themes"/>
402 <dep package="scrollkeeper"/>
403 <dep package="gnome-doc-utils"/>
404 </dependencies>
405 </autotools>
406 <autotools id="gnome-menus">
407 <branch revision="gnome-2-14"/>
408 <dependencies>
409 <dep package="intltool"/>
410 <dep package="gnome-common"/>
411 <dep package="glib"/>
412 <dep package="pygtk"/>
413 </dependencies>
414 </autotools>
415 <autotools id="gnome-panel">
416 <branch revision="gnome-2-14"/>
417 <dependencies>
418 <dep package="scrollkeeper"/>
419 <dep package="libgnomeui"/>
420 <dep package="gnome-desktop"/>
421 <dep package="libwnck"/>
422 <dep package="evolution-data-server"/>
423 <dep package="gnome-menus"/>
424 <dep package="gnome-vfs"/>
425 <dep package="libglade"/>
426 <dep package="gnome-doc-utils"/>
427 </dependencies>
428 </autotools>
429 <autotools id="gnome-session">
430 <branch revision="gnome-2-14"/>
431 <dependencies>
432 <dep package="libgnomeui"/>
433 <dep package="libwnck"/>
434 <dep package="esound"/>
435 </dependencies>
436 </autotools>
437 <autotools id="gnome-applets" autogenargs="--enable-gstreamer=0.10">
438 <branch revision="gnome-2-14"/>
439 <dependencies>
440 <dep package="gnome-panel"/>
441 <dep package="libgtop"/>
442 <dep package="gail"/>
443 <dep package="libxklavier"/>
444 <dep package="gstreamer"/>
445 <dep package="gst-plugins-base"/>
446 <dep package="gucharmap"/>
447 <dep package="system-tools-backends-1.4"/>
448 </dependencies>
449 </autotools>
450 <autotools id="gnome-games">
451 <branch revision="gnome-2-14"/>
452 <dependencies>
453 <dep package="librsvg"/>
454 <dep package="scrollkeeper"/>
455 <dep package="libgnomeui"/>
456 <dep package="gob"/>
457 </dependencies>
458 </autotools>
459 <autotools id="libcroco" supports-non-srcdir-builds="no">
460 <branch/>
461 <dependencies>
462 <dep package="libxml2"/>
463 <dep package="pango"/>
464 </dependencies>
465 </autotools>
466 <autotools id="librsvg" supports-non-srcdir-builds="no">
467 <branch revision="gnome-2-14"/>
468 <dependencies>
469 <dep package="libxml2"/>
470 <dep package="gtk+"/>
471 <dep package="libart_lgpl"/>
472 <dep package="gnome-common"/>
473 <dep package="libgsf"/>
474 <dep package="libcroco"/>
475 <dep package="libgnomeprintui"/>
476 </dependencies>
477 </autotools>
478 <autotools id="eel">
479 <branch revision="gnome-2-14"/>
480 <dependencies>
481 <dep package="librsvg"/>
482 <dep package="libgnomeui"/>
483 <dep package="gail"/>
484 <dep package="gnome-desktop"/>
485 <dep package="gnome-menus"/>
486 </dependencies>
487 </autotools>
488 <autotools id="nautilus">
489 <branch revision="gnome-2-14"/>
490 <dependencies>
491 <dep package="scrollkeeper"/>
492 <dep package="esound"/>
493 <dep package="eel"/>
494 <dep package="librsvg"/>
495 <dep package="libgnomeui"/>
496 <dep package="gnome-desktop"/>
497 </dependencies>
498 </autotools>
499 <autotools id="nautilus-actions">
500 <branch/>
501 <dependencies>
502 <dep package="nautilus"/>
503 </dependencies>
504 </autotools>
505 <autotools id="nautilus-cd-burner">
506 <branch revision="gnome-2-14"/>
507 <dependencies>
508 <dep package="nautilus"/>
509 </dependencies>
510 </autotools>
511 <autotools id="nautilus-open-terminal">
512 <branch/>
513 <dependencies>
514 <dep package="nautilus"/>
515 </dependencies>
516 </autotools>
517 <autotools id="nautilus-media" supports-non-srcdir-builds="no">
518 <branch/>
519 <dependencies>
520 <dep package="nautilus"/>
521 <dep package="gstreamer-0-8"/>
522 <dep package="gst-plugins-0-8"/>
523 </dependencies>
524 </autotools>
525 <autotools id="nautilus-vcs">
526 <branch/>
527 <dependencies>
528 <dep package="nautilus"/>
529 </dependencies>
530 </autotools>
531 <autotools id="metacity">
532 <branch revision="gnome-2-14"/>
533 <dependencies>
534 <dep package="gtk+"/>
535 <dep package="gconf"/>
536 <dep package="intltool"/>
537 <dep package="libglade"/>
538 </dependencies>
539 </autotools>
540 <autotools id="libgtop">
541 <branch/>
542 <dependencies>
543 <dep package="glib"/>
544 </dependencies>
545 </autotools>
546 <autotools id="gnome-system-monitor">
547 <branch revision="gnome-2-14"/>
548 <dependencies>
549 <dep package="libgnomeui"/>
550 <dep package="libwnck"/>
551 <dep package="libgtop"/>
552 </dependencies>
553 </autotools>
554 <autotools id="gnome-control-center" autogenargs="--enable-gstreamer=0.10"
555 supports-non-srcdir-builds="no">
556 <branch revision="gnome-2-14"/>
557 <dependencies>
558 <dep package="libgnomeui"/>
559 <dep package="esound"/>
560 <dep package="gnome-desktop"/>
561 <dep package="metacity"/>
562 <dep package="nautilus"/>
563 <dep package="libxklavier"/>
564 <dep package="gnome-menus"/>
565 <dep package="gnome-doc-utils"/>
566 <dep package="gstreamer"/>
567 </dependencies>
568 </autotools>
569 <autotools id="yelp">
570 <branch revision="gnome-2-14"/>
571 <dependencies>
572 <dep package="scrollkeeper"/>
573 <dep package="libgnomeui"/>
574 <dep package="gnome-vfs"/>
575 <dep package="gnome-doc-utils"/>
576 <dep package="startup-notification"/>
577 <dep package="libgnomeprintui"/>
578 <dep package="mozilla"/>
579 </dependencies>
580 </autotools>
581 <autotools id="devhelp">
582 <branch/>
583 <dependencies>
584 <dep package="libgnomeui"/>
585 <dep package="gnome-vfs"/>
586 <dep package="mozilla"/>
587 </dependencies>
588 </autotools>
589 <autotools id="gnome-utils">
590 <branch revision="gnome-2-14"/>
591 <dependencies>
592 <dep package="libgnomeui"/>
593 <dep package="gnome-panel"/>
594 <dep package="gnome-doc-utils"/>
595 </dependencies>
596 </autotools>
597 <autotools id="gconf-editor" supports-non-srcdir-builds="no">
598 <branch revision="gnome-2-14" />
599 <dependencies>
600 <dep package="libgnomeui"/>
601 <dep package="gconf"/>
602 </dependencies>
603 </autotools>
604 <tarball id="audiofile" version="0.2.6" supports-non-srcdir-builds="no">
605 <source href="http://www.68k.org/~michael/audiofile/audiofile-0.2.6.tar.gz"
606 size="374688" md5sum="9c1049876cd51c0f1b12c2886cce4d42"/>
607 </tarball>
608 <autotools id="esound">
609 <branch/>
610 <dependencies>
611 <dep package="audiofile"/>
612 </dependencies>
613 </autotools>
614 <autotools id="gnome-media">
615 <branch/>
616 <dependencies>
617 <dep package="scrollkeeper"/>
618 <dep package="libgnomeui"/>
619 <dep package="esound"/>
620 <dep package="gail"/>
621 <dep package="gstreamer"/>
622 <dep package="gst-plugins-base"/>
623 <dep package="gst-plugins-good"/>
624 <dep package="nautilus-cd-burner"/>
625 </dependencies>
626 </autotools>
627 <autotools id="gdm2">
628 <branch revision="gnome-2-14"/>
629 <dependencies>
630 <dep package="librsvg"/>
631 <dep package="gnome-doc-utils"/>
632 </dependencies>
633 </autotools>
634 <autotools id="vte">
635 <branch revision="vte-0-12"/>
636 <dependencies>
637 <dep package="gtk+"/>
638 </dependencies>
639 </autotools>
640 <autotools id="gnome-terminal">
641 <branch revision="gnome-2-14"/>
642 <dependencies>
643 <dep package="libglade"/>
644 <dep package="libgnomeui"/>
645 <dep package="vte"/>
646 <dep package="startup-notification"/>
647 </dependencies>
648 </autotools>
649 <autotools id="gtk-engines">
650 <branch revision="gtk-engines-2-6"/>
651 <dependencies>
652 <dep package="gtk+"/>
653 </dependencies>
654 </autotools>
655 <autotools id="libgnomeprint">
656 <branch/>
657 <dependencies>
658 <dep package="intltool"/>
659 <dep package="libart_lgpl"/>
660 <dep package="glib"/>
661 <dep package="gnome-common"/>
662 <dep package="pango"/>
663 <dep package="libgnomecups"/>
664 </dependencies>
665 </autotools>
666 <autotools id="libgnomeprintui">
667 <branch/>
668 <dependencies>
669 <dep package="libgnomeprint"/>
670 <dep package="gtk+"/>
671 <dep package="libgnomecanvas"/>
672 <dep package="gnome-icon-theme"/>
673 </dependencies>
674 </autotools>
675 <autotools id="gedit">
676 <branch revision="gnome-2-14"/>
677 <dependencies>
678 <dep package="scrollkeeper"/>
679 <dep package="libgnomeui"/>
680 <dep package="gnome-doc-utils"/>
681 <dep package="libgnomeprintui"/>
682 <dep package="gtksourceview"/>
683 <dep package="gnome-python-desktop"/>
684 </dependencies>
685 </autotools>
686 <autotools id="memprof">
687 <branch/>
688 <dependencies>
689 <dep package="libgnomeui"/>
690 </dependencies>
691 </autotools>
692 <autotools id="eog">
693 <branch revision="gnome-2-14"/>
694 <dependencies>
695 <dep package="libgnomeui"/>
696 <dep package="libgnomeprint"/>
697 </dependencies>
698 </autotools>
699 <autotools id="libgsf">
700 <branch/>
701 <dependencies>
702 <dep package="glib"/>
703 <dep package="gnome-vfs"/>
704 <dep package="libbonobo"/>
705 </dependencies>
706 </autotools>
707 <autotools id="goffice">
708 <branch/>
709 <dependencies>
710 <dep package="glib"/>
711 <dep package="libgsf"/>
712 <dep package="libxml2"/>
713 <dep package="pango"/>
714 <dep package="libglade"/>
715 <dep package="libgnomeprint"/>
716 <dep package="libgnomeprintui"/>
717 <dep package="libart_lgpl"/>
718 </dependencies>
719 </autotools>
720 <autotools id="gnumeric">
721 <branch/>
722 <dependencies>
723 <dep package="goffice"/>
724 <dep package="libgsf"/>
725 <dep package="pygtk"/>
726 <dep package="libgnomeprintui"/>
727 </dependencies>
728 </autotools>
729 <autotools id="gimp" autogenargs="--disable-print">
730 <branch/>
731 <dependencies>
732 <dep package="gtk+"/>
733 <dep package="libart_lgpl"/>
734 </dependencies>
735 </autotools>
736 <autotools id="glade">
737 <branch/>
738 <dependencies>
739 <dep package="gtk+"/>
740 <dep package="libxml2"/>
741 <dep package="libgnomeui"/>
742 <dep package="libgnomeprintui"/>
743 </dependencies>
744 </autotools>
745 <autotools id="glade2c">
746 <branch/>
747 <dependencies>
748 <dep package="gtk+"/>
749 <dep package="libxml2"/>
750 <dep package="libgnomeui"/>
751 </dependencies>
752 </autotools>
753 <autotools id="sawfish">
754 <branch revision="gnome-2"/>
755 <dependencies>
756 <dep package="rep-gtk"/>
757 </dependencies>
758 </autotools>
759 <autotools id="rep-gtk">
760 <branch/>
761 <dependencies>
762 <dep package="librep"/>
763 <dep package="gtk+"/>
764 </dependencies>
765 </autotools>
766 <autotools id="librep">
767 <branch/>
768 </autotools>
769 <autotools id="rhythmbox">
770 <branch/>
771 <dependencies>
772 <dep package="libgnomeui"/>
773 <dep package="gst-plugins-base"/>
774 <dep package="nautilus-cd-burner"/>
775 <dep package="totem"/>
776 <dep package="gnome-doc-utils"/>
777 </dependencies>
778 </autotools>
779 <autotools id="gstreamer-0-8" autogenargs="-- --disable-plugin-builddir --disable-tests" supports-non-srcdir-builds="no">
780 <branch repo="gstreamer.freedesktop.org" module="gstreamer"
781 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gstreamer-0-8"/>
782 <dependencies>
783 <dep package="glib"/>
784 <dep package="libxml2"/>
785 </dependencies>
786 </autotools>
787
788 <autotools id="gst-plugins-0-8" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
789 <branch repo="gstreamer.freedesktop.org" module="gst-plugins"
790 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gst-plugins-0-8"/>
791 <dependencies>
792 <dep package="gstreamer-0-8"/>
793 <dep package="gnome-vfs"/>
794 <dep package="gtk+"/>
795 </dependencies>
796 </autotools>
797
798 <autotools id="gst-python-0-8" autogenargs="--" supports-non-srcdir-builds="no">
799 <branch repo="gstreamer.freedesktop.org" module="gst-python"
800 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gst-python-0-8"/>
801 <dependencies>
802 <dep package="gstreamer-0-8"/>
803 <dep package="gst-plugins-0-8"/>
804 </dependencies>
805 </autotools>
806
807 <autotools id="gstreamer" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
808 <branch repo="gstreamer.freedesktop.org" module="gstreamer"/>
809 <dependencies>
810 <dep package="glib"/>
811 <dep package="libxml2"/>
812 </dependencies>
813 </autotools>
814
815 <autotools id="liboil">
816 <branch repo="liboil.freedesktop.org" revision="liboil_0_3_6"/>
817 </autotools>
818
819 <autotools id="gst-plugins-base" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
820 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-base"/>
821 <dependencies>
822 <dep package="gstreamer"/>
823 <dep package="gnome-vfs"/>
824 <dep package="gtk+"/>
825 <dep package="liboil"/>
826 </dependencies>
827 </autotools>
828
829 <autotools id="gst-plugins-good" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
830 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-good"/>
831 <dependencies>
832 <dep package="gstreamer"/>
833 <dep package="gst-plugins-base"/>
834 </dependencies>
835 </autotools>
836
837 <autotools id="gst-plugins-ugly" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
838 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-ugly"/>
839 <dependencies>
840 <dep package="gstreamer"/>
841 <dep package="gst-plugins-base"/>
842 </dependencies>
843 </autotools>
844
845 <autotools id="gst-plugins-bad" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
846 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-bad"/>
847 <dependencies>
848 <dep package="gstreamer"/>
849 <dep package="gst-plugins-base"/>
850 </dependencies>
851 </autotools>
852
853 <autotools id="gst-ffmpeg" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
854 <branch repo="gstreamer.freedesktop.org" module="gst-ffmpeg"/>
855 <dependencies>
856 <dep package="gstreamer"/>
857 <dep package="gst-plugins-base"/>
858 </dependencies>
859 </autotools>
860
861 <autotools id="gst-python" autogenargs="--" supports-non-srcdir-builds="no">
862 <branch repo="gstreamer.freedesktop.org" module="gst-python"/>
863 <dependencies>
864 <dep package="gstreamer"/>
865 <dep package="gst-plugins-base"/>
866 </dependencies>
867 </autotools>
868
869 <autotools id="planner">
870 <branch/>
871 <dependencies>
872 <dep package="glib"/>
873 <dep package="libxml2"/>
874 <dep package="libgnomeui"/>
875 <dep package="libgnomeprintui"/>
876 <dep package="libgsf"/>
877 </dependencies>
878 </autotools>
879 <autotools id="file-roller">
880 <branch revision="gnome-2-14" />
881 <dependencies>
882 <dep package="scrollkeeper"/>
883 <dep package="gnome-doc-utils"/>
884 <dep package="nautilus"/>
885 </dependencies>
886 </autotools>
887 <autotools id="balsa">
888 <branch revision="BALSA_2"/>
889 <dependencies>
890 <dep package="libgnomeui"/>
891 </dependencies>
892 </autotools>
893 <autotools id="pan">
894 <branch/>
895 <dependencies>
896 <dep package="libgnomeui"/>
897 <dep package="gnet"/>
898 </dependencies>
899 </autotools>
900 <autotools id="pyspi">
901 <branch/>
902 <dependencies>
903 <dep package="at-spi"/>
904 </dependencies>
905 </autotools>
906 <autotools id="dogtail">
907 <branch/>
908 <dependencies>
909 <dep package="pyspi"/>
910 </dependencies>
911 <after>
912 <dep package="gnome-python-desktop"/>
913 </after>
914 </autotools>
915 <autotools id="gcalctool" supports-non-srcdir-builds="no">
916 <branch revision="gnome-2-14"/>
917 <dependencies>
918 <dep package="scrollkeeper"/>
919 <dep package="libgnomeui"/>
920 </dependencies>
921 </autotools>
922 <autotools id="ggv" supports-non-srcdir-builds="no">
923 <branch/>
924 <dependencies>
925 <dep package="scrollkeeper"/>
926 <dep package="libgnomeui"/>
927 </dependencies>
928 </autotools>
929 <autotools id="ekiga" autogenargs="--with-pwlib-dir=`ptlib-config --prefix` --with-opal-dir=`ptlib-config --prefix`">
930 <branch revision="gnome-2-14"/>
931 <dependencies>
932 <dep package="libgnomeui"/>
933 <dep package="evolution-data-server"/>
934 <dep package="opal" />
935 <dep package="avahi" />
936 </dependencies>
937 </autotools>
938 <autotools id="pwlib" autogen-sh="configure">
939 <branch repo="openh323.sf.net" module="ptlib_unix" checkoutdir="pwlib"
940 override-checkoutdir="no" update-new-dirs="no" />
941 </autotools>
942 <autotools id="opal" autogen-sh="configure">
943 <branch repo="openh323.sf.net"/>
944 <dependencies>
945 <dep package="pwlib"/>
946 </dependencies>
947 </autotools>
948 <autotools id="gucharmap" supports-non-srcdir-builds="no">
949 <branch revision="gnome-2-14"/>
950 <dependencies>
951 <dep package="libgnomeui"/>
952 <dep package="gnome-doc-utils"/>
953 </dependencies>
954 </autotools>
955 <autotools id="gtksourceview" autogenargs="--enable-compile-warnings=maximum">
956 <branch/>
957 <dependencies>
958 <dep package="gtk+"/>
959 <dep package="libxml2"/>
960 <dep package="libgnomeprint"/>
961 <dep package="gnome-vfs"/>
962 </dependencies>
963 </autotools>
964 <autotools id="glimmer">
965 <branch/>
966 <dependencies>
967 <dep package="gtksourceview"/>
968 <dep package="libgnomeprint"/>
969 </dependencies>
970 </autotools>
971 <autotools id="gdl">
972 <branch/>
973 <dependencies>
974 <dep package="libgnomeui"/>
975 <dep package="librsvg"/>
976 </dependencies>
977 </autotools>
978 <autotools id="gnome-build">
979 <branch/>
980 <dependencies>
981 <dep package="gdl"/>
982 <dep package="gnome-vfs"/>
983 <dep package="gtkhtml2"/>
984 </dependencies>
985 </autotools>
986 <autotools id="scaffold">
987 <branch/>
988 <dependencies>
989 <dep package="libgnomeui"/>
990 <dep package="vte"/>
991 <dep package="gdl"/>
992 </dependencies>
993 </autotools>
994 <autotools id="libsigc++2">
995 <branch revision="libsigc-2-0"/>
996 </autotools>
997 <autotools id="glibmm">
998 <branch revision="glibmm-2-8"/>
999 <dependencies>
1000 <dep package="glib"/>
1001 <dep package="libsigc++2"/>
1002 </dependencies>
1003 </autotools>
1004 <autotools id="gtkmm">
1005 <branch revision="gtkmm-2-8"/>
1006 <dependencies>
1007 <dep package="glibmm"/>
1008 <dep package="gtk+"/>
1009 </dependencies>
1010 </autotools>
1011 <autotools id="orbitcpp">
1012 <branch/>
1013 <dependencies>
1014 <dep package="ORBit2"/>
1015 </dependencies>
1016 </autotools>
1017 <autotools id="gnomemm/libgnomemm">
1018 <branch revision="gnome-2-14"/>
1019 <dependencies>
1020 <dep package="libgnome"/>
1021 <dep package="gtkmm"/>
1022 </dependencies>
1023 </autotools>
1024 <autotools id="gnomemm/libglademm">
1025 <branch/>
1026 <dependencies>
1027 <dep package="libglade"/>
1028 <dep package="gtkmm"/>
1029 </dependencies>
1030 </autotools>
1031 <autotools id="gnomemm/libbonobomm">
1032 <branch/>
1033 <dependencies>
1034 <dep package="libbonobo"/>
1035 <dep package="gtkmm"/>
1036 <dep package="orbitcpp"/>
1037 </dependencies>
1038 </autotools>
1039 <autotools id="gnomemm/libbonobouimm">
1040 <branch/>
1041 <dependencies>
1042 <dep package="libbonoboui"/>
1043 <dep package="gnomemm/libbonobomm"/>
1044 </dependencies>
1045 </autotools>
1046 <autotools id="gnomemm/libgnomecanvasmm">
1047 <branch/>
1048 <dependencies>
1049 <dep package="libgnomecanvas"/>
1050 <dep package="gtkmm"/>
1051 </dependencies>
1052 </autotools>
1053 <autotools id="gnomemm/gconfmm">
1054 <branch/>
1055 <dependencies>
1056 <dep package="gconf"/>
1057 <dep package="gtkmm"/>
1058 </dependencies>
1059 </autotools>
1060 <autotools id="gnomemm/libgnomeuimm">
1061 <branch/>
1062 <dependencies>
1063 <dep package="gtkmm"/>
1064 <dep package="libgnomeui"/>
1065 <dep package="gnomemm/libgnomemm"/>
1066 <dep package="gnomemm/gconfmm"/>
1067 <dep package="gnomemm/libgnomecanvasmm"/>
1068 <dep package="gnomemm/libglademm"/>
1069 <dep package="gnomemm/gnome-vfsmm"/>
1070 </dependencies>
1071 </autotools>
1072 <autotools id="gnomemm/gnome-vfsmm">
1073 <branch/>
1074 <dependencies>
1075 <dep package="glibmm"/>
1076 <dep package="gnome-vfs"/>
1077 </dependencies>
1078 </autotools>
1079 <autotools id="gnomemm/libpanelappletmm">
1080 <branch/>
1081 <dependencies>
1082 <dep package="gtkmm"/>
1083 </dependencies>
1084 </autotools>
1085 <autotools id="gnomemm/libgnomeprintmm">
1086 <branch/>
1087 <dependencies>
1088 <dep package="gtkmm"/>
1089 <dep package="libgnomeprint"/>
1090 </dependencies>
1091 </autotools>
1092 <autotools id="gnomemm/libgnomeprintuimm">
1093 <branch/>
1094 <dependencies>
1095 <dep package="gtkmm"/>
1096 <dep package="gnomemm/libgnomeprintmm"/>
1097 <dep package="libgnomeprintui"/>
1098 </dependencies>
1099 </autotools>
1100 <autotools id="gnomemm/libgdamm">
1101 <branch revision="libgda-1-2"/>
1102 <dependencies>
1103 <dep package="gtkmm"/>
1104 <dep package="libgda-1-2"/>
1105 </dependencies>
1106 </autotools>
1107 <autotools id="gnomemm/gtkmm_hello">
1108 <branch/>
1109 <dependencies>
1110 <dep package="gtkmm"/>
1111 </dependencies>
1112 </autotools>
1113 <autotools id="regexxer">
1114 <branch/>
1115 <dependencies>
1116 <dep package="intltool"/>
1117 <dep package="gtkmm"/>
1118 <dep package="gnomemm/gconfmm"/>
1119 <dep package="gnomemm/libglademm"/>
1120 </dependencies>
1121 </autotools>
1122 <autotools id="gnet" autogenargs="--enable-glib2">
1123 <branch revision="GNET_1_1"/>
1124 <dependencies>
1125 <dep package="glib"/>
1126 </dependencies>
1127 </autotools>
1128 <autotools id="gnomeicu">
1129 <branch/>
1130 <dependencies>
1131 <dep package="libgnomeui"/>
1132 </dependencies>
1133 </autotools>
1134 <autotools id="at-spi">
1135 <branch revision="gnome-2-14"/>
1136 <dependencies>
1137 <dep package="libbonobo"/>
1138 <dep package="gail"/>
1139 </dependencies>
1140 </autotools>
1141 <autotools id="libgail-gnome">
1142 <branch/>
1143 <dependencies>
1144 <dep package="at-spi"/>
1145 <dep package="libgnomeui"/>
1146 <dep package="gnome-panel"/>
1147 </dependencies>
1148 </autotools>
1149 <autotools id="at-poke">
1150 <branch/>
1151 <dependencies>
1152 <dep package="libgail-gnome"/>
1153 </dependencies>
1154 </autotools>
1155 <autotools id="gnome-mag">
1156 <branch/>
1157 <dependencies>
1158 <dep package="at-spi"/>
1159 </dependencies>
1160 </autotools>
1161 <autotools id="gok">
1162 <branch revision="gnome-2-14"/>
1163 <dependencies>
1164 <dep package="at-spi"/>
1165 <dep package="libgnomeui"/>
1166 <dep package="libwnck"/>
1167 <dep package="esound"/>
1168 <dep package="scrollkeeper"/>
1169 <dep package="gnome-speech"/>
1170 </dependencies>
1171 </autotools>
1172 <autotools id="gnome-speech">
1173 <branch revision="gnome-2-14"/>
1174 <dependencies>
1175 <dep package="libbonobo"/>
1176 </dependencies>
1177 </autotools>
1178 <autotools id="gnopernicus">
1179 <branch revision="gnome-2-14"/>
1180 <dependencies>
1181 <dep package="gconf"/>
1182 <dep package="libgnomeui"/>
1183 <dep package="gnome-speech"/>
1184 <dep package="gnome-mag"/>
1185 </dependencies>
1186 </autotools>
1187 <autotools id="dasher" autogenargs="--with-a11y --with-gnome">
1188 <branch revision="gnome-2-14"/>
1189 <dependencies>
1190 <dep package="at-spi"/>
1191 <dep package="libgnomeui"/>
1192 <dep package="gnome-speech"/>
1193 <dep package="gnome-vfs"/>
1194 </dependencies>
1195 </autotools>
1196 <autotools id="gnome-screensaver">
1197 <branch revision="gnome-2-14"/>
1198 <dependencies>
1199 <dep package="gconf"/>
1200 <dep package="gtk+"/>
1201 <dep package="dbus"/>
1202 <dep package="gnome-menus"/>
1203 <dep package="libgnomeui"/>
1204 </dependencies>
1205 </autotools>
1206 <autotools id="gnome-power-manager">
1207 <branch revision="gnome-2-14"/>
1208 <dependencies>
1209 <dep package="libgnomeui"/>
1210 <dep package="hal"/>
1211 <dep package="libwnck"/>
1212 <dep package="gtk+"/>
1213 <dep package="gconf"/>
1214 <dep package="intltool"/>
1215 <dep package="libglade"/>
1216 <dep package="libnotify"/>
1217 </dependencies>
1218 </autotools>
1219 <autotools id="gthumb">
1220 <branch/>
1221 <dependencies>
1222 <dep package="libgnomeui"/>
1223 <dep package="gnome-vfs"/>
1224 <dep package="libglade"/>
1225 <dep package="libbonoboui"/>
1226 <dep package="libgnomeprintui"/>
1227 </dependencies>
1228 </autotools>
1229 <autotools id="fast-user-switch-applet">
1230 <branch revision="gnome-2-14"/>
1231 <dependencies>
1232 <dep package="gtk+"/>
1233 <dep package="gconf"/>
1234 <dep package="libglade"/>
1235 <dep package="gnome-panel"/>
1236 </dependencies>
1237 </autotools>
1238 <autotools id="gnome-mount" autogenargs="--enable-nautilus-extension">
1239 <branch/>
1240 <dependencies>
1241 <dep package="gnome-keyring"/>
1242 <dep package="libgnomeui"/>
1243 <dep package="dbus"/>
1244 <dep package="hal"/>
1245 <dep package="gtk+"/>
1246 <dep package="intltool"/>
1247 <dep package="libglade"/>
1248 <dep package="eel"/>
1249 <dep package="nautilus"/>
1250 </dependencies>
1251 </autotools>
1252 <autotools id="libnotify">
1253 <branch repo="svn.galago-project.org" module="trunk/libnotify"/>
1254 <dependencies>
1255 <dep package="gtk+"/>
1256 <dep package="dbus"/>
1257 </dependencies>
1258 </autotools>
1259 <autotools id="libsexy">
1260 <branch repo="osiris.chipx86.com" module="trunk/libsexy"/>
1261 <dependencies>
1262 <dep package="gtk+"/>
1263 <dep package="libxml2"/>
1264 <dep package="iso-codes"/>
1265 </dependencies>
1266 </autotools>
1267 <autotools id="notification-daemon">
1268 <branch repo="svn.galago-project.org" module="trunk/notification-daemon"/>
1269 <dependencies>
1270 <dep package="gtk+"/>
1271 <dep package="dbus"/>
1272 <dep package="libsexy"/>
1273 </dependencies>
1274 </autotools>
1275
1276 <metamodule id="meta-gnome-devel-platform">
1277 <dependencies>
1278 <dep package="libgnome"/>
1279 <dep package="libbonobo"/>
1280 <dep package="libbonoboui"/>
1281 <dep package="libgnomeui"/>
1282 </dependencies>
1283 </metamodule>
1284 <metamodule id="meta-gnome-core">
1285 <dependencies>
1286 <dep package="gnome-desktop"/>
1287 <dep package="gnome-panel"/>
1288 <dep package="gnome-session"/>
1289 <dep package="gnome-terminal"/>
1290 <dep package="gnome-applets"/>
1291 </dependencies>
1292 </metamodule>
1293 <metamodule id="meta-nautilus">
1294 <dependencies>
1295 <dep package="nautilus"/>
1296 </dependencies>
1297 </metamodule>
1298 <metamodule id="meta-gnome-desktop">
1299 <dependencies>
1300 <dep package="meta-gnome-core"/>
1301 <dep package="gnome-control-center"/>
1302 <dep package="meta-nautilus"/>
1303 <dep package="yelp"/>
1304 <dep package="bug-buddy"/>
1305 <dep package="gedit"/>
1306 <dep package="gtk-engines"/>
1307 <dep package="eog"/>
1308 <dep package="metacity"/>
1309 <dep package="gconf-editor"/>
1310 <dep package="gnome-utils"/>
1311 <dep package="gnome-system-monitor"/>
1312 <dep package="gstreamer"/>
1313 <dep package="gnome-media"/>
1314 <dep package="gnome-netstatus"/>
1315 <dep package="gcalctool"/>
1316 <dep package="gucharmap"/>
1317 <dep package="nautilus-cd-burner"/>
1318 <dep package="zenity"/>
1319 <dep package="libgail-gnome"/>
1320 <dep package="gnopernicus"/>
1321 <dep package="gok"/>
1322 <dep package="epiphany"/>
1323 <dep package="gnome-games"/>
1324 <dep package="gnome-user-docs"/>
1325 <dep package="file-roller"/>
1326 <dep package="gnome-system-tools"/>
1327 <dep package="gnome-nettool"/>
1328 <dep package="vino"/>
1329 <dep package="gnome-volume-manager"/>
1330 <dep package="totem"/>
1331 <dep package="gnome-menus"/>
1332 <dep package="gnome-backgrounds"/>
1333 <dep package="sound-juicer"/>
1334 <dep package="evolution"/>
1335 <dep package="evolution-webcal"/>
1336 <dep package="evolution-exchange"/>
1337 <dep package="ekiga"/>
1338 <dep package="evince"/>
1339 <dep package="dasher"/>
1340 <dep package="gnome-keyring-manager"/>
1341 <dep package="deskbar-applet"/>
1342 <dep package="fast-user-switch-applet"/>
1343 <dep package="gnome-screensaver"/>
1344 <dep package="meta-gnome-admin"/>
1345 </dependencies>
1346 </metamodule>
1347 <metamodule id="meta-gnome-admin">
1348 <dependencies>
1349 <dep package="pessulus"/>
1350 <dep package="sabayon"/>
1351 </dependencies>
1352 </metamodule>
1353 <metamodule id="meta-gnome-devel-tools">
1354 <dependencies>
1355 <dep package="glade"/>
1356 <dep package="memprof"/>
1357 <dep package="gconf-editor"/>
1358 <dep package="devhelp"/>
1359 <dep package="nautilus-vcs"/>
1360 </dependencies>
1361 </metamodule>
1362 <metamodule id="meta-gnome-python">
1363 <dependencies>
1364 <dep package="pygtk"/>
1365 <dep package="gnome-python"/>
1366 <dep package="gnome-python-desktop"/>
1367 </dependencies>
1368 <after>
1369 <dep package="gnome-python-extras"/>
1370 </after>
1371 </metamodule>
1372 <metamodule id="meta-gnome-c++">
1373 <dependencies>
1374 <dep package="gtkmm"/>
1375 <dep package="gnomemm/libgnomeuimm"/>
1376 <dep package="gnomemm/gnome-vfsmm"/>
1377 <dep package="gnomemm/libpanelappletmm"/>
1378 <dep package="gnomemm/libbonobouimm"/>
1379 <dep package="gnomemm/libgnomeprintuimm"/>
1380 <dep package="libxml++"/>
1381 <dep package="gnomemm/libgdamm"/>
1382 <dep package="bakery"/>
1383 </dependencies>
1384 </metamodule>
1385 <metamodule id="meta-gnome-accessibility">
1386 <dependencies>
1387 <dep package="libgail-gnome"/>
1388 <dep package="at-poke"/>
1389 <dep package="dasher"/>
1390 <dep package="gnome-mag"/>
1391 <dep package="gok"/>
1392 <dep package="gnome-speech"/>
1393 <dep package="gnopernicus"/>
1394 </dependencies>
1395 </metamodule>
1396 <metamodule id="meta-gnome-proposed">
1397 <dependencies>
1398 <dep package="libnotify"/>
1399 <dep package="notification-daemon"/>
1400 <dep package="gnome-power-manager"/>
1401 </dependencies>
1402 </metamodule>
1403 <autotools id="sodipodi">
1404 <branch/>
1405 <dependencies>
1406 <dep package="gtk+"/>
1407 <dep package="libgnomeprintui"/>
1408 <dep package="libart_lgpl"/>
1409 <dep package="libxml2"/>
1410 </dependencies>
1411 </autotools>
1412 <autotools id="gnome-themes">
1413 <branch revision="gnome-2-14"/>
1414 <dependencies>
1415 <dep package="gtk-engines"/>
1416 </dependencies>
1417 </autotools>
1418 <autotools id="gob">
1419 <branch/>
1420 <dependencies>
1421 <dep package="glib"/>
1422 </dependencies>
1423 </autotools>
1424 <autotools id="libgnetwork">
1425 <branch/>
1426 <dependencies>
1427 <dep package="glib"/>
1428 <dep package="gconf"/>
1429 <dep package="intltool"/>
1430 </dependencies>
1431 </autotools>
1432 <autotools id="libgircclient">
1433 <branch/>
1434 <dependencies>
1435 <dep package="libgnetwork"/>
1436 </dependencies>
1437 </autotools>
1438 <autotools id="gnomechat">
1439 <branch/>
1440 <dependencies>
1441 <dep package="libgnetwork"/>
1442 <dep package="libgircclient"/>
1443 <dep package="libgnomeui"/>
1444 </dependencies>
1445 </autotools>
1446 <mozillamodule id="mozilla" autogenargs="--enable-default-toolkit=gtk2 --disable-mailnews --disable-ldap --disable-debug --enable-optimize --disable-tests --enable-crypto --enable-xft --with-system-zlib --disable-freetype2 --enable-application=browser" cvsroot="mozilla.org" revision="MOZILLA_1_7_BRANCH">
1447 <dependencies>
1448 <dep package="gtk+"/>
1449 </dependencies>
1450 </mozillamodule>
1451 <autotools id="epiphany">
1452 <branch revision="gnome-2-14"/>
1453 <dependencies>
1454 <dep package="iso-codes"/>
1455 <dep package="libgnomeui"/>
1456 <dep package="pygtk"/>
1457 <dep package="gnome-python"/>
1458 <dep package="gnome-doc-utils"/>
1459 <dep package="libgnomeprintui"/>
1460 <dep package="mozilla"/>
1461 </dependencies>
1462 </autotools>
1463 <autotools id="epiphany-extensions">
1464 <branch revision="gnome-2-14"/>
1465 <dependencies>
1466 <dep package="epiphany"/>
1467 </dependencies>
1468 </autotools>
1469 <autotools id="galeon">
1470 <branch/>
1471 <dependencies>
1472 <dep package="mozilla"/>
1473 <dep package="libgnomeui"/>
1474 </dependencies>
1475 </autotools>
1476 <autotools id="libsoup">
1477 <branch/>
1478 <dependencies>
1479 <dep package="glib"/>
1480 <dep package="gnutls"/>
1481 <dep package="libxml2"/>
1482 </dependencies>
1483 </autotools>
1484 <autotools id="gtkhtml">
1485 <branch revision="gnome-2-14"/>
1486 <dependencies>
1487 <dep package="gtk+"/>
1488 <dep package="libgnomeui"/>
1489 <dep package="libbonoboui"/>
1490 <dep package="libglade"/>
1491 <dep package="gail"/>
1492 <dep package="libgnomeprint"/>
1493 <dep package="libgnomeprintui"/>
1494 <dep package="libsoup"/>
1495 </dependencies>
1496 </autotools>
1497 <autotools id="evolution-data-server" supports-non-srcdir-builds="no">
1498 <branch revision="gnome-2-14"/>
1499 <dependencies>
1500 <dep package="libbonobo"/>
1501 <dep package="libgnome"/>
1502 <dep package="libgnomeui"/>
1503 <dep package="libsoup"/>
1504 <dep package="libxml2"/>
1505 <dep package="gconf"/>
1506 <dep package="gnome-vfs"/>
1507 <dep package="mozilla"/>
1508 </dependencies>
1509 </autotools>
1510 <autotools id="evolution">
1511 <branch revision="gnome-2-14"/>
1512 <dependencies>
1513 <dep package="evolution-data-server"/>
1514 <dep package="gtkhtml"/>
1515 <dep package="libgnomeui"/>
1516 <dep package="libbonoboui"/>
1517 </dependencies>
1518 <after>
1519 <dep package="libnotify"/>
1520 </after>
1521 </autotools>
1522 <autotools id="evolution-webcal">
1523 <branch/>
1524 <dependencies>
1525 <dep package="evolution-data-server"/>
1526 <dep package="libsoup"/>
1527 <dep package="libgnomeui"/>
1528 </dependencies>
1529 </autotools>
1530 <autotools id="evolution-exchange">
1531 <branch revision="gnome-2-14"/>
1532 <dependencies>
1533 <dep package="evolution-data-server"/>
1534 <dep package="evolution"/>
1535 <dep package="libsoup"/>
1536 </dependencies>
1537 </autotools>
1538 <tarball id="xchat" version="2.4.5">
1539 <source href="http://xchat.org/files/source/2.4/xchat-2.4.5.tar.bz2"
1540 size="1324626" md5sum="9107a92693e6c62ff2008030e698b92b"/>
1541 <dependencies>
1542 <dep package="gtk+"/>
1543 <dep package="libxml2"/>
1544 </dependencies>
1545 </tarball>
1546 <tarball id="camorama" version="0.17">
1547 <source href="http://camorama.fixedgear.org/downloads/camorama-0.17.tar.bz2"
1548 size="312233" md5sum="2b2784af53a1ba8fa4419aa806967b35"/>
1549 <dependencies>
1550 <dep package="gtk+"/>
1551 </dependencies>
1552 </tarball>
1553 <autotools id="gtk-engines-cleanice">
1554 <branch repo="elysium-project.sf.net"/>
1555 <dependencies>
1556 <dep package="gtk+"/>
1557 </dependencies>
1558 </autotools>
1559 <autotools id="gaim">
1560 <branch repo="gaim.sf.net"/>
1561 <dependencies>
1562 <dep package="libgnomeui"/>
1563 </dependencies>
1564 </autotools>
1565 <autotools id="zenity">
1566 <branch revision="gnome-2-14"/>
1567 <dependencies>
1568 <dep package="gtk+"/>
1569 <dep package="gconf"/>
1570 <dep package="libgnomecanvas"/>
1571 <dep package="gnome-doc-utils"/>
1572 </dependencies>
1573 </autotools>
1574 <autotools id="gpdf">
1575 <branch/>
1576 <dependencies>
1577 <dep package="libgnomeui"/>
1578 <dep package="libbonoboui"/>
1579 <dep package="libgnomeprintui"/>
1580 </dependencies>
1581 </autotools>
1582 <autotools id="gnome-netstatus">
1583 <branch/>
1584 <dependencies>
1585 <dep package="libgnomeui"/>
1586 <dep package="gnome-panel"/>
1587 <dep package="gnome-doc-utils"/>
1588 </dependencies>
1589 </autotools>
1590 <autotools id="gnome-doc-utils">
1591 <branch revision="gnome-2-14"/>
1592 <dependencies>
1593 <dep package="libxslt"/>
1594 <dep package="intltool"/>
1595 <dep package="glib"/>
1596 </dependencies>
1597 </autotools>
1598 <tarball id="libmusicbrainz" version="2.1.2">
1599 <source href="ftp://ftp.musicbrainz.org/pub/musicbrainz/libmusicbrainz-2.1.2.tar.gz"
1600 size="504432" md5sum="88d35af903665fecbdee77eb6d5e6cdd"/>
1601 </tarball>
1602 <autotools id="totem" autogenargs="--enable-gstreamer=0.10">
1603 <branch revision="gnome-2-14"/>
1604 <dependencies>
1605 <dep package="gnome-desktop"/>
1606 <dep package="nautilus-cd-burner"/>
1607 <dep package="gstreamer"/>
1608 <dep package="gst-plugins-base"/>
1609 <dep package="gst-plugins-good"/>
1610 <dep package="libmusicbrainz"/>
1611 <dep package="iso-codes"/>
1612 </dependencies>
1613 </autotools>
1614 <autotools id="gnome-themes-extras">
1615 <branch/>
1616 <dependencies>
1617 <dep package="gnome-themes"/>
1618 </dependencies>
1619 </autotools>
1620
1621 <autotools id="libgda">
1622 <branch module="libgda"/>
1623 <dependencies>
1624 <dep package="glib"/>
1625 </dependencies>
1626 </autotools>
1627 <autotools id="libgda-1-2">
1628 <branch module="libgda" revision="release-1-2-branch"
1629 checkoutdir="libgda-1-2"/>
1630 <dependencies>
1631 <dep package="glib"/>
1632 </dependencies>
1633 </autotools>
1634
1635 <autotools id="libgnomedb" autogenargs="--enable-gnome=yes">
1636 <branch/>
1637 <dependencies>
1638 <dep package="libgda"/>
1639 <dep package="libgnomeui"/>
1640 <dep package="libbonoboui"/>
1641 </dependencies>
1642 </autotools>
1643 <autotools id="mergeant">
1644 <branch/>
1645 <dependencies>
1646 <dep package="libgnomedb"/>
1647 </dependencies>
1648 </autotools>
1649 <autotools id="gtranslator">
1650 <branch/>
1651 <dependencies>
1652 <dep package="libgnomeui"/>
1653 </dependencies>
1654 </autotools>
1655 <autotools id="gnome-spell">
1656 <branch/>
1657 <dependencies>
1658 <dep package="libgnomeui"/>
1659 </dependencies>
1660 </autotools>
1661 <autotools id="libgnomecups">
1662 <branch/>
1663 <dependencies>
1664 <dep package="glib"/>
1665 </dependencies>
1666 </autotools>
1667 <autotools id="gnome-cups-manager">
1668 <branch/>
1669 <dependencies>
1670 <dep package="libgnomecups"/>
1671 <dep package="libgnomeui"/>
1672 <dep package="libglade"/>
1673 </dependencies>
1674 </autotools>
1675 <autotools id="libxml++">
1676 <branch/>
1677 <dependencies>
1678 <dep package="libxml2"/>
1679 <dep package="glibmm"/>
1680 </dependencies>
1681 </autotools>
1682 <autotools id="bakery">
1683 <branch/>
1684 <dependencies>
1685 <dep package="libxml++"/>
1686 <dep package="gtkmm"/>
1687 <dep package="gnomemm/libglademm"/>
1688 <dep package="gnomemm/gconfmm"/>
1689 <dep package="gnomemm/gnome-vfsmm"/>
1690 </dependencies>
1691 </autotools>
1692 <autotools id="gnome-hello">
1693 <branch/>
1694 <dependencies>
1695 <dep package="glib"/>
1696 <dep package="libgnome"/>
1697 <dep package="libgnomeui"/>
1698 </dependencies>
1699 </autotools>
1700 <autotools id="gnome-system-tools">
1701 <branch revision="gnome-2-14" />
1702 <dependencies>
1703 <dep package="glib"/>
1704 <dep package="libxml2"/>
1705 <dep package="gconf"/>
1706 <dep package="libgnomeui"/>
1707 <dep package="libbonoboui"/>
1708 <dep package="libglade"/>
1709 <dep package="nautilus"/>
1710 <dep package="system-tools-backends-1.4"/>
1711 <dep package="gnome-doc-utils"/>
1712 </dependencies>
1713 </autotools>
1714 <autotools id="gnome-user-docs">
1715 <branch revision="gnome-2-14"/>
1716 <dependencies>
1717 <dep package="scrollkeeper"/>
1718 <dep package="gnome-doc-utils"/>
1719 </dependencies>
1720 </autotools>
1721 <autotools id="loudmouth">
1722 <branch/>
1723 <dependencies>
1724 <dep package="glib"/>
1725 </dependencies>
1726 </autotools>
1727 <autotools id="gossip">
1728 <branch/>
1729 <dependencies>
1730 <dep package="loudmouth"/>
1731 <dep package="libgnomeui"/>
1732 </dependencies>
1733 </autotools>
1734 <autotools id="conglomerate">
1735 <branch/>
1736 <dependencies>
1737 <dep package="libxslt"/>
1738 <dep package="gconf"/>
1739 <dep package="libgnomeui"/>
1740 </dependencies>
1741 </autotools>
1742 <autotools id="sound-juicer">
1743 <branch revision="gnome-2-14"/>
1744 <dependencies>
1745 <dep package="gnome-doc-utils"/>
1746 <dep package="libgnomeui"/>
1747 <dep package="gnome-media"/>
1748 <dep package="gstreamer"/>
1749 <dep package="gst-plugins-base"/>
1750 <dep package="gst-plugins-good"/>
1751 <dep package="nautilus-cd-burner"/>
1752 </dependencies>
1753 </autotools>
1754 <autotools id="gnome-network">
1755 <branch/>
1756 <dependencies>
1757 <dep package="glib"/>
1758 </dependencies>
1759 </autotools>
1760 <tarball id="guile" version="1.6.7">
1761 <source href="ftp://ftp.gnu.org/gnu/guile/guile-1.6.7.tar.gz"
1762 size="3039294" md5sum="c2ff2a2231f0cbb2e838dd8701a587c5"/>
1763 </tarball>
1764 <tarball id="autogen" version="5.6.5">
1765 <source href="http://internap.dl.sourceforge.net/sourceforge/autogen/autogen-5.6.5.tar.gz"
1766 size="1144260" md5sum="54a6cb0be7e6b526af9aba4a73013885"/>
1767 <dependencies>
1768 <dep package="guile"/>
1769 </dependencies>
1770 </tarball>
1771 <autotools id="anjuta">
1772 <branch/>
1773 <dependencies>
1774 <dep package="libbonoboui"/>
1775 <dep package="libgnomeprintui"/>
1776 <dep package="vte"/>
1777 <dep package="gnome-build"/>
1778 <dep package="autogen"/>
1779 </dependencies>
1780 </autotools>
1781 <autotools id="OpenApplet">
1782 <branch/>
1783 <dependencies>
1784 <dep package="gnome-panel"/>
1785 </dependencies>
1786 </autotools>
1787 <autotools id="gtetrinet">
1788 <branch/>
1789 <dependencies>
1790 <dep package="libgnomeui"/>
1791 </dependencies>
1792 </autotools>
1793 <autotools id="glom">
1794 <branch/>
1795 <dependencies>
1796 <dep package="gnomemm/libgdamm"/>
1797 <dep package="bakery"/>
1798 <dep package="gnomemm/libgnomecanvasmm"/>
1799 <dep package="libgnome"/>
1800 <dep package="iso-codes"/>
1801 <dep package="pygtk"/>
1802 <dep package="gnome-python-extras"/>
1803 <dep package="gnome-doc-utils"/>
1804 </dependencies>
1805 </autotools>
1806 <autotools id="vino">
1807 <branch/>
1808 <dependencies>
1809 <dep package="libgnomeui"/>
1810 <dep package="libglade"/>
1811 <dep package="gconf"/>
1812 <dep package="gnutls"/>
1813 </dependencies>
1814 </autotools>
1815 <autotools id="gnome-keyring-manager" autogenargs="--disable-more-warnings">
1816 <branch/>
1817 <dependencies>
1818 <dep package="libgnomeui"/>
1819 <dep package="gnome-keyring"/>
1820 <dep package="gconf"/>
1821 </dependencies>
1822 </autotools>
1823 <autotools id="gnome-volume-manager">
1824 <branch/>
1825 <dependencies>
1826 <dep package="libgnomeui"/>
1827 <dep package="libglade"/>
1828 <dep package="hal"/>
1829 </dependencies>
1830 </autotools>
1831 <metamodule id="meta-storage">
1832 <dependencies>
1833 <dep package="storage/storage-store"/>
1834 <dep package="storage/vfs"/>
1835 <dep package="storage/applet"/>
1836 </dependencies>
1837 </metamodule>
1838 <autotools id="storage/storage-store">
1839 <branch/>
1840 <dependencies>
1841 <dep package="dbus"/>
1842 </dependencies>
1843 </autotools>
1844 <autotools id="storage/libstorage">
1845 <branch/>
1846 <dependencies>
1847 <dep package="gnome-vfs"/>
1848 <dep package="pygtk"/>
1849 </dependencies>
1850 </autotools>
1851 <autotools id="storage/libstorage-translators">
1852 <branch/>
1853 <dependencies>
1854 <dep package="storage/libstorage"/>
1855 </dependencies>
1856 </autotools>
1857 <autotools id="storage/vfs">
1858 <branch/>
1859 <dependencies>
1860 <dep package="storage/libstorage"/>
1861 <dep package="storage/libstorage-translators"/>
1862 </dependencies>
1863 </autotools>
1864 <autotools id="storage/pet">
1865 <branch/>
1866 </autotools>
1867 <autotools id="storage/libmrs">
1868 <branch/>
1869 <dependencies>
1870 <dep package="storage/pet"/>
1871 </dependencies>
1872 </autotools>
1873 <autotools id="storage/libmrs-converter">
1874 <branch/>
1875 <dependencies>
1876 <dep package="storage/libmrs"/>
1877 </dependencies>
1878 </autotools>
1879 <autotools id="storage/libstorage-nl">
1880 <branch/>
1881 <dependencies>
1882 <dep package="storage/libstorage"/>
1883 <dep package="storage/libmrs"/>
1884 <dep package="storage/libmrs-converter"/>
1885 </dependencies>
1886 </autotools>
1887 <autotools id="storage/applet">
1888 <branch/>
1889 <dependencies>
1890 <dep package="gnome-python"/>
1891 <dep package="storage/libstorage-nl"/>
1892 </dependencies>
1893 </autotools>
1894 <autotools id="gnome-nettool">
1895 <branch revision="gnome-2-14"/>
1896 <dependencies>
1897 <dep package="libgnomeui"/>
1898 </dependencies>
1899 </autotools>
1900 <autotools id="monkey-bubble">
1901 <branch/>
1902 <dependencies>
1903 <dep package="gstreamer-0-8"/>
1904 <dep package="gst-plugins-0-8"/>
1905 <dep package="libxml2"/>
1906 <dep package="gconf"/>
1907 <dep package="librsvg"/>
1908 <dep package="libgnomeui"/>
1909 </dependencies>
1910 </autotools>
1911 <autotools id="gnome-schedule">
1912 <branch/>
1913 <dependencies>
1914 <dep package="pygtk"/>
1915 <dep package="yelp"/>
1916 </dependencies>
1917 </autotools>
1918 <autotools id="gnome-backgrounds">
1919 <branch/>
1920 <dependencies>
1921 <dep package="glib"/>
1922 </dependencies>
1923 </autotools>
1924 <autotools id="evince">
1925 <branch revision="gnome-2-14"/>
1926 <dependencies>
1927 <dep package="libgnomeui"/>
1928 <dep package="libgnomeprintui"/>
1929 <dep package="poppler"/>
1930 <dep package="gnome-doc-utils"/>
1931 </dependencies>
1932 </autotools>
1933 <autotools id="nautilus-python" supports-non-srcdir-builds="no">
1934 <branch/>
1935 <dependencies>
1936 <dep package="nautilus"/>
1937 <dep package="pygtk"/>
1938 <dep package="gnome-python"/>
1939 </dependencies>
1940 </autotools>
1941 <autotools id="inkscape">
1942 <branch repo="inkscape.sf.net"/>
1943 <dependencies>
1944 <dep package="gtkmm"/>
1945 <dep package="libxslt"/>
1946 </dependencies>
1947 </autotools>
1948 <autotools id="NetworkManager">
1949 <branch repo="gnome.org"/>
1950 <dependencies>
1951 <dep package="dbus"/>
1952 </dependencies>
1953 </autotools>
1954 <autotools id="atomix">
1955 <branch/>
1956 <dependencies>
1957 <dep package="gtk+"/>
1958 <dep package="libgnome"/>
1959 <dep package="libgnomeui"/>
1960 <dep package="libxml2"/>
1961 <dep package="libgnomecanvas"/>
1962 <dep package="libbonoboui"/>
1963 </dependencies>
1964 </autotools>
1965 <autotools id="deskbar-applet">
1966 <branch revision="gnome-2-14"/>
1967 <dependencies>
1968 <dep package="gtk+"/>
1969 <dep package="gnome-desktop"/>
1970 <dep package="pygtk"/>
1971 <dep package="gnome-python"/>
1972 <dep package="gnome-python-desktop"/>
1973 </dependencies>
1974 </autotools>
1975 <autotools id="pessulus">
1976 <branch revision="gnome-2-14"/>
1977 <dependencies>
1978 <dep package="pygtk"/>
1979 <dep package="gnome-python"/>
1980 </dependencies>
1981 </autotools>
1982 <autotools id="sabayon">
1983 <branch/>
1984 <dependencies>
1985 <dep package="gtk+"/>
1986 <dep package="pygtk"/>
1987 </dependencies>
1988 </autotools>
1989 <autotools id="muine">
1990 <branch/>
1991 <dependencies>
1992 <dep package="gtk+"/>
1993 <dep package="gstreamer"/>
1994 </dependencies>
1995 </autotools>
1996 <autotools id="gnonlin">
1997 <branch repo="gstreamer.freedesktop.org" module="gnonlin"/>
1998 <dependencies>
1999 <dep package="gstreamer"/>
2000 <dep package="gst-plugins-base"/>
2001 </dependencies>
2002 </autotools>
2003 <autotools id="pitivi">
2004 <branch/>
2005 <dependencies>
2006 <dep package="pygtk"/>
2007 <dep package="gnome-python"/>
2008 <dep package="gstreamer"/>
2009 <dep package="gst-python"/>
2010 <dep package="gnonlin"/>
2011 </dependencies>
2012 </autotools>
2013</moduleset>
diff --git a/scripts/jhbuild/modulesets/gnome-2.16.modules b/scripts/jhbuild/modulesets/gnome-2.16.modules
new file mode 100644
index 0000000000..5459c26908
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gnome-2.16.modules
@@ -0,0 +1,2087 @@
1<?xml version="1.0"?><!--*- mode: nxml; indent-tabs-mode: nil -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="gnome.org" default="yes"
5 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
6 password=""/>
7 <repository type="cvs" name="cairo.freedesktop.org"
8 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/cairo"
9 password=""/>
10 <repository type="cvs" name="mozilla.org"
11 cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot"
12 password="anonymous"/>
13 <repository type="cvs" name="liboil.freedesktop.org"
14 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/liboil"
15 password=""/>
16 <repository type="cvs" name="gstreamer.freedesktop.org"
17 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/gstreamer"
18 password=""/>
19 <repository type="cvs" name="menu.freedesktop.org"
20 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/menus"
21 password=""/>
22 <repository type="cvs" name="mime.freedesktop.org"
23 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/mime"
24 password=""/>
25 <repository type="cvs" name="xklavier.freedesktop.org"
26 cvsroot=":pserver:anoncvs@anoncvs.freedesktop.org:/cvs/xklavier"
27 password=""/>
28 <repository type="cvs" name="elysium-project.sf.net"
29 cvsroot=":pserver:anonymous@elysium-project.cvs.sourceforge.net:/cvsroot/elysium-project"
30 password=""/>
31 <repository type="svn" name="gaim.sf.net"
32 href="https://svn.sourceforge.net/svnroot/gaim/"/>
33 <repository type="cvs" name="inkscape.sf.net"
34 cvsroot=":pserver:anonymous@inkscape.cvs.sourceforge.net:/cvsroot/inkscape"
35 password=""/>
36 <repository type="svn" name="svn.galago-project.org"
37 href="http://svn.galago-project.org/"/>
38 <repository type="svn" name="osiris.chipx86.com"
39 href="http://osiris.chipx86.com/svn/osiris-misc/"/>
40 <repository type="svn" name="svn.debian.org"
41 href="svn://svn.debian.org/"/>
42 <repository type="cvs" name="openh323.sf.net"
43 cvsroot=":pserver:anonymous@openh323.cvs.sourceforge.net:/cvsroot/openh323"
44 password="" />
45 <repository type="svn" name="svn.navi.cx"
46 href="http://svn.navi.cx/" />
47 <repository type="cvs" name="anoncvs.abisource.com"
48 cvsroot=":pserver:anoncvs@anoncvs.abisource.com:/cvsroot"
49 password="anoncvs" />
50
51
52 <tarball id="scrollkeeper" version="0.3.14" supports-non-srcdir-builds="no">
53 <source href="http://easynews.dl.sourceforge.net/sourceforge/scrollkeeper/scrollkeeper-0.3.14.tar.gz"
54 size="679513" md5sum="161eb3f29e30e7b24f84eb93ac696155"/>
55 <dependencies>
56 <dep package="libxml2"/>
57 <dep package="libxslt"/>
58 <dep package="intltool"/>
59 </dependencies>
60 <patches>
61 <patch file="scrollkeeper_clean_xml_validation_context.patch" strip="1"/>
62 <patch file="scrollkeeper_language_fix.patch" strip="1"/>
63 <patch file="scrollkeeper_rw_offset_fix.patch" strip="1"/>
64 </patches>
65 </tarball>
66
67 <autotools id="iso-codes">
68 <branch repo="svn.debian.org" module="pkg-isocodes/trunk/iso-codes" checkoutdir="iso-codes"/>
69 </autotools>
70
71 <include href="freedesktop.modules"/>
72 <include href="gnutls.modules"/>
73
74 <autotools id="cairo-gtk-engine">
75 <branch repo="cairo.freedesktop.org"/>
76 <dependencies>
77 <dep package="gtk+"/>
78 <dep package="cairo-1-0"/>
79 </dependencies>
80 </autotools>
81
82 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
83 <branch repo="mime.freedesktop.org"/>
84 <dependencies>
85 <dep package="intltool"/>
86 <dep package="libxml2"/>
87 <dep package="glib"/>
88 </dependencies>
89 </autotools>
90
91 <autotools id="desktop-file-utils">
92 <branch repo="menu.freedesktop.org"/>
93 <dependencies>
94 <dep package="glib"/>
95 <dep package="intltool"/>
96 </dependencies>
97 </autotools>
98
99 <autotools id="libxklavier" supports-non-srcdir-builds="no">
100 <branch repo="xklavier.freedesktop.org"/>
101 <dependencies>
102 <dep package="libxml2"/>
103 <dep package="gtk-doc"/>
104 <dep package="glib"/>
105 </dependencies>
106 </autotools>
107 <autotools id="libbtctl">
108 <branch/>
109 <dependencies>
110 <dep package="gtk+"/>
111 <dep package="glib"/>
112 </dependencies>
113 </autotools>
114 <autotools id="gnome-bluetooth">
115 <branch/>
116 <dependencies>
117 <dep package="gtk+"/>
118 <dep package="glib"/>
119 <dep package="libbtctl"/>
120 <dep package="libglade"/>
121 <dep package="libgnomeui"/>
122 <dep package="gconf"/>
123 </dependencies>
124 </autotools>
125 <autotools id="phonemgr">
126 <branch/>
127 <dependencies>
128 <dep package="gtk+"/>
129 <dep package="glib"/>
130 <dep package="libbtctl"/>
131 <dep package="gnome-bluetooth"/>
132 <dep package="libglade"/>
133 <dep package="libgnomeui"/>
134 <dep package="libgnome"/>
135 <dep package="gconf"/>
136 </dependencies>
137 </autotools>
138
139 <autotools id="intltool">
140 <branch/>
141 <dependencies>
142 <dep package="gnome-common"/>
143 </dependencies>
144 </autotools>
145 <autotools id="gnome-common">
146 <branch/>
147 </autotools>
148 <autotools id="libxml2">
149 <branch module="gnome-xml" checkoutdir="libxml2"/>
150 </autotools>
151 <autotools id="libxslt">
152 <branch/>
153 <dependencies>
154 <dep package="libxml2"/>
155 <dep package="libgcrypt"/>
156 </dependencies>
157 </autotools>
158 <autotools id="gtk-doc">
159 <branch/>
160 <dependencies>
161 <dep package="libxslt"/>
162 <dep package="scrollkeeper"/>
163 </dependencies>
164 </autotools>
165 <autotools id="gamin">
166 <branch/>
167 <dependencies>
168 <dep package="glib"/>
169 </dependencies>
170 </autotools>
171 <autotools id="glib">
172 <branch/>
173 <dependencies>
174 <dep package="gtk-doc"/>
175 </dependencies>
176 </autotools>
177 <autotools id="pango">
178 <branch/>
179 <dependencies>
180 <dep package="gnome-common"/>
181 <dep package="glib"/>
182 <dep package="cairo"/>
183 <dep package="libXft"/>
184 </dependencies>
185 </autotools>
186 <autotools id="atk">
187 <branch/>
188 <dependencies>
189 <dep package="glib"/>
190 </dependencies>
191 </autotools>
192 <autotools id="gtk+">
193 <branch/>
194 <dependencies>
195 <dep package="cairo"/>
196 <dep package="pango"/>
197 <dep package="atk"/>
198 <dep package="shared-mime-info"/>
199 </dependencies>
200 </autotools>
201 <autotools id="gail">
202 <branch/>
203 <dependencies>
204 <dep package="gtk+"/>
205 <dep package="atk"/>
206 <dep package="libgnomecanvas"/>
207 </dependencies>
208 </autotools>
209 <autotools id="gtkhtml2">
210 <branch/>
211 <dependencies>
212 <dep package="gtk+"/>
213 <dep package="libxml2"/>
214 <dep package="gail"/>
215 </dependencies>
216 </autotools>
217 <autotools id="libIDL">
218 <branch/>
219 <dependencies>
220 <dep package="glib"/>
221 </dependencies>
222 </autotools>
223 <autotools id="ORBit2">
224 <branch/>
225 <dependencies>
226 <dep package="libIDL"/>
227 <dep package="gnome-common"/>
228 </dependencies>
229 </autotools>
230 <autotools id="gconf">
231 <branch/>
232 <dependencies>
233 <dep package="ORBit2"/>
234 <dep package="libxml2"/>
235 <dep package="gtk+"/>
236 </dependencies>
237 </autotools>
238 <autotools id="libbonobo">
239 <branch/>
240 <dependencies>
241 <dep package="ORBit2"/>
242 <dep package="intltool"/>
243 <dep package="gnome-common"/>
244 <dep package="libxml2"/>
245 </dependencies>
246 </autotools>
247 <autotools id="gnome-mime-data">
248 <branch/>
249 <dependencies>
250 <dep package="gnome-common"/>
251 <dep package="glib"/>
252 </dependencies>
253 </autotools>
254 <autotools id="gnome-icon-theme">
255 <branch/>
256 <dependencies>
257 <dep package="hicolor-icon-theme"/>
258 <dep package="icon-naming-utils"/>
259 </dependencies>
260 </autotools>
261 <autotools id="gnome-vfs">
262 <branch/>
263 <dependencies>
264 <dep package="gconf"/>
265 <dep package="desktop-file-utils"/>
266 <dep package="shared-mime-info"/>
267 <dep package="gnome-mime-data"/>
268 <dep package="avahi"/>
269 <dep package="hal"/>
270 <dep package="gamin"/>
271 </dependencies>
272 </autotools>
273 <autotools id="gnome-vfs-monikers">
274 <branch/>
275 <dependencies>
276 <dep package="libbonobo"/>
277 <dep package="gnome-vfs"/>
278 </dependencies>
279 </autotools>
280 <autotools id="gnome-keyring">
281 <branch/>
282 <dependencies>
283 <dep package="gtk+"/>
284 </dependencies>
285 </autotools>
286 <autotools id="libart_lgpl">
287 <branch/>
288 </autotools>
289 <autotools id="libgnome">
290 <branch/>
291 <dependencies>
292 <dep package="libxml2"/>
293 <dep package="libxslt"/>
294 <dep package="libbonobo"/>
295 <dep package="gnome-vfs"/>
296 <dep package="gconf"/>
297 <dep package="esound"/>
298 </dependencies>
299 </autotools>
300 <autotools id="libgnomecanvas">
301 <branch/>
302 <dependencies>
303 <dep package="gtk+"/>
304 <dep package="libart_lgpl"/>
305 <dep package="libglade"/>
306 <dep package="gnome-common"/>
307 </dependencies>
308 </autotools>
309 <autotools id="libbonoboui">
310 <branch/>
311 <dependencies>
312 <dep package="libgnome"/>
313 <dep package="libbonobo"/>
314 <dep package="libgnomecanvas"/>
315 <dep package="libglade"/>
316 </dependencies>
317 </autotools>
318 <autotools id="libgnomeui">
319 <branch/>
320 <dependencies>
321 <dep package="libbonoboui"/>
322 <dep package="libglade"/>
323 <dep package="gnome-icon-theme"/>
324 <dep package="gnome-keyring"/>
325 </dependencies>
326 </autotools>
327 <autotools id="libglade">
328 <branch/>
329 <dependencies>
330 <dep package="gtk+"/>
331 <dep package="libxml2"/>
332 </dependencies>
333 </autotools>
334 <autotools id="pygobject">
335 <branch/>
336 <dependencies>
337 <dep package="glib"/>
338 </dependencies>
339 </autotools>
340 <autotools id="pygtk">
341 <branch/>
342 <dependencies>
343 <dep package="pygobject"/>
344 <dep package="gtk+"/>
345 <dep package="pycairo"/>
346 <dep package="libglade"/>
347 </dependencies>
348 </autotools>
349 <autotools id="pyorbit">
350 <branch/>
351 <dependencies>
352 <dep package="ORBit2"/>
353 </dependencies>
354 </autotools>
355 <autotools id="gnome-python">
356 <branch/>
357 <dependencies>
358 <dep package="pygtk"/>
359 <dep package="pyorbit"/>
360 <dep package="libgnomecanvas"/>
361 <dep package="libgnomeui"/>
362 </dependencies>
363 </autotools>
364 <autotools id="gnome-python-desktop">
365 <branch/>
366 <dependencies>
367 <dep package="gnome-python"/>
368 <dep package="gnome-panel"/>
369 <dep package="libgnomeprint"/>
370 <dep package="libgnomeprintui"/>
371 <dep package="gtksourceview"/>
372 <dep package="libwnck"/>
373 <dep package="totem"/>
374 <dep package="libgtop"/>
375 <dep package="nautilus-cd-burner"/>
376 <dep package="gnome-media"/>
377 <dep package="metacity"/>
378 </dependencies>
379 </autotools>
380 <autotools id="gnome-python-extras">
381 <branch/>
382 <dependencies>
383 <dep package="pygtk"/>
384 <dep package="gnome-python"/>
385 <dep package="gtkhtml2"/>
386 <dep package="gdl"/>
387 </dependencies>
388 </autotools>
389 <autotools id="bug-buddy">
390 <branch/>
391 <dependencies>
392 <dep package="libgnomeui"/>
393 <dep package="gnome-menus"/>
394 <dep package="gnome-doc-utils"/>
395 <dep package="evolution-data-server"/>
396 <dep package="libsoup"/>
397 </dependencies>
398 <suggests>
399 <dep package="NetworkManager"/>
400 </suggests>
401 </autotools>
402 <autotools id="libwnck">
403 <branch/>
404 <dependencies>
405 <dep package="gtk+"/>
406 <dep package="startup-notification"/>
407 </dependencies>
408 </autotools>
409 <autotools id="gnome-desktop" autogenargs="--with-gnome-distributor=JHBuild">
410 <branch/>
411 <dependencies>
412 <dep package="libgnomeui"/>
413 <dep package="startup-notification"/>
414 <dep package="gnome-themes"/>
415 <dep package="scrollkeeper"/>
416 <dep package="gnome-doc-utils"/>
417 </dependencies>
418 </autotools>
419 <autotools id="gnome-menus">
420 <branch/>
421 <dependencies>
422 <dep package="intltool"/>
423 <dep package="gnome-common"/>
424 <dep package="glib"/>
425 <dep package="pygtk"/>
426 </dependencies>
427 </autotools>
428 <autotools id="gnome-panel">
429 <branch/>
430 <dependencies>
431 <dep package="scrollkeeper"/>
432 <dep package="libgnomeui"/>
433 <dep package="gnome-desktop"/>
434 <dep package="libwnck"/>
435 <dep package="evolution-data-server"/>
436 <dep package="gnome-menus"/>
437 <dep package="gnome-vfs"/>
438 <dep package="libglade"/>
439 <dep package="gnome-doc-utils"/>
440 <dep package="dbus-glib"/>
441 </dependencies>
442 </autotools>
443 <autotools id="gnome-session">
444 <branch/>
445 <dependencies>
446 <dep package="libgnomeui"/>
447 <dep package="libwnck"/>
448 <dep package="esound"/>
449 <dep package="gnome-control-center"/>
450 <dep package="gnome-keyring"/>
451 </dependencies>
452 </autotools>
453 <autotools id="gnome-applets" autogenargs="--enable-gstreamer=0.10">
454 <branch/>
455 <dependencies>
456 <dep package="gnome-panel"/>
457 <dep package="libgtop"/>
458 <dep package="gail"/>
459 <dep package="libxklavier"/>
460 <dep package="gstreamer"/>
461 <dep package="gst-plugins-base"/>
462 <dep package="gucharmap"/>
463 <dep package="system-tools-backends-1.4"/>
464 <dep package="pygtk"/>
465 </dependencies>
466 </autotools>
467 <autotools id="gnome-games">
468 <branch/>
469 <dependencies>
470 <dep package="librsvg"/>
471 <dep package="scrollkeeper"/>
472 <dep package="libgnomeui"/>
473 <dep package="gob"/>
474 </dependencies>
475 </autotools>
476 <autotools id="libcroco" supports-non-srcdir-builds="no">
477 <branch/>
478 <dependencies>
479 <dep package="libxml2"/>
480 <dep package="pango"/>
481 </dependencies>
482 </autotools>
483 <autotools id="librsvg" supports-non-srcdir-builds="no">
484 <branch/>
485 <dependencies>
486 <dep package="libxml2"/>
487 <dep package="gtk+"/>
488 <dep package="libart_lgpl"/>
489 <dep package="gnome-common"/>
490 <dep package="libgsf"/>
491 <dep package="libcroco"/>
492 <dep package="libgnomeprintui"/>
493 </dependencies>
494 </autotools>
495 <autotools id="eel">
496 <branch/>
497 <dependencies>
498 <dep package="librsvg"/>
499 <dep package="libgnomeui"/>
500 <dep package="gail"/>
501 <dep package="gnome-desktop"/>
502 <dep package="gnome-menus"/>
503 </dependencies>
504 </autotools>
505 <autotools id="nautilus">
506 <branch/>
507 <dependencies>
508 <dep package="scrollkeeper"/>
509 <dep package="esound"/>
510 <dep package="eel"/>
511 <dep package="librsvg"/>
512 <dep package="libgnomeui"/>
513 <dep package="gnome-desktop"/>
514 </dependencies>
515 </autotools>
516 <autotools id="nautilus-actions">
517 <branch/>
518 <dependencies>
519 <dep package="nautilus"/>
520 </dependencies>
521 </autotools>
522 <autotools id="nautilus-cd-burner">
523 <branch/>
524 <dependencies>
525 <dep package="nautilus"/>
526 </dependencies>
527 </autotools>
528 <autotools id="nautilus-open-terminal">
529 <branch/>
530 <dependencies>
531 <dep package="nautilus"/>
532 </dependencies>
533 </autotools>
534 <autotools id="nautilus-media" supports-non-srcdir-builds="no">
535 <branch/>
536 <dependencies>
537 <dep package="nautilus"/>
538 <dep package="gstreamer-0-8"/>
539 <dep package="gst-plugins-0-8"/>
540 </dependencies>
541 </autotools>
542 <autotools id="nautilus-vcs">
543 <branch/>
544 <dependencies>
545 <dep package="nautilus"/>
546 </dependencies>
547 </autotools>
548 <autotools id="metacity">
549 <branch/>
550 <dependencies>
551 <dep package="gtk+"/>
552 <dep package="gconf"/>
553 <dep package="intltool"/>
554 <dep package="libglade"/>
555 </dependencies>
556 </autotools>
557 <autotools id="libgtop">
558 <branch/>
559 <dependencies>
560 <dep package="glib"/>
561 </dependencies>
562 </autotools>
563 <autotools id="gnome-system-monitor">
564 <branch/>
565 <dependencies>
566 <dep package="libgnomeui"/>
567 <dep package="libwnck"/>
568 <dep package="libgtop"/>
569 </dependencies>
570 </autotools>
571 <autotools id="gnome-control-center" autogenargs="--enable-gstreamer=0.10"
572 supports-non-srcdir-builds="no">
573 <branch/>
574 <dependencies>
575 <dep package="libgnomeui"/>
576 <dep package="esound"/>
577 <dep package="gnome-desktop"/>
578 <dep package="metacity"/>
579 <dep package="nautilus"/>
580 <dep package="libxklavier"/>
581 <dep package="gnome-menus"/>
582 <dep package="gnome-doc-utils"/>
583 <dep package="gst-plugins-base"/>
584 </dependencies>
585 </autotools>
586 <autotools id="yelp">
587 <branch/>
588 <dependencies>
589 <dep package="scrollkeeper"/>
590 <dep package="libgnomeui"/>
591 <dep package="gnome-vfs"/>
592 <dep package="gnome-doc-utils"/>
593 <dep package="startup-notification"/>
594 <dep package="mozilla"/>
595 </dependencies>
596 </autotools>
597 <autotools id="devhelp">
598 <branch/>
599 <dependencies>
600 <dep package="libgnomeui"/>
601 <dep package="gnome-vfs"/>
602 <dep package="mozilla"/>
603 </dependencies>
604 </autotools>
605 <autotools id="gnome-utils">
606 <branch/>
607 <dependencies>
608 <dep package="libgnomeui"/>
609 <dep package="gnome-panel"/>
610 <dep package="gnome-doc-utils"/>
611 </dependencies>
612 </autotools>
613 <autotools id="gconf-editor" supports-non-srcdir-builds="no">
614 <branch/>
615 <dependencies>
616 <dep package="libgnomeui"/>
617 <dep package="gconf"/>
618 </dependencies>
619 </autotools>
620 <tarball id="audiofile" version="0.2.6" supports-non-srcdir-builds="no">
621 <source href="http://www.68k.org/~michael/audiofile/audiofile-0.2.6.tar.gz"
622 size="374688" md5sum="9c1049876cd51c0f1b12c2886cce4d42"/>
623 </tarball>
624 <autotools id="esound">
625 <branch/>
626 <dependencies>
627 <dep package="audiofile"/>
628 </dependencies>
629 </autotools>
630 <autotools id="gnome-media">
631 <branch/>
632 <dependencies>
633 <dep package="scrollkeeper"/>
634 <dep package="libgnomeui"/>
635 <dep package="esound"/>
636 <dep package="gail"/>
637 <dep package="gstreamer"/>
638 <dep package="gst-plugins-base"/>
639 <dep package="gst-plugins-good"/>
640 <dep package="nautilus-cd-burner"/>
641 </dependencies>
642 </autotools>
643 <autotools id="gdm2">
644 <branch/>
645 <dependencies>
646 <dep package="librsvg"/>
647 <dep package="gnome-doc-utils"/>
648 </dependencies>
649 </autotools>
650 <autotools id="vte">
651 <branch/>
652 <dependencies>
653 <dep package="gtk+"/>
654 </dependencies>
655 </autotools>
656 <autotools id="gnome-terminal">
657 <branch/>
658 <dependencies>
659 <dep package="libglade"/>
660 <dep package="libgnomeui"/>
661 <dep package="vte"/>
662 <dep package="startup-notification"/>
663 </dependencies>
664 </autotools>
665 <autotools id="gtk-engines">
666 <branch/>
667 <dependencies>
668 <dep package="gtk+"/>
669 </dependencies>
670 </autotools>
671 <autotools id="libgnomeprint">
672 <branch/>
673 <dependencies>
674 <dep package="intltool"/>
675 <dep package="libart_lgpl"/>
676 <dep package="glib"/>
677 <dep package="gnome-common"/>
678 <dep package="pango"/>
679 <dep package="libgnomecups"/>
680 </dependencies>
681 </autotools>
682 <autotools id="libgnomeprintui">
683 <branch/>
684 <dependencies>
685 <dep package="libgnomeprint"/>
686 <dep package="gtk+"/>
687 <dep package="libgnomecanvas"/>
688 <dep package="gnome-icon-theme"/>
689 </dependencies>
690 </autotools>
691 <autotools id="gedit">
692 <branch/>
693 <dependencies>
694 <dep package="scrollkeeper"/>
695 <dep package="libgnomeui"/>
696 <dep package="gnome-doc-utils"/>
697 <dep package="libgnomeprintui"/>
698 <dep package="gtksourceview"/>
699 <dep package="gnome-python-desktop"/>
700 </dependencies>
701 </autotools>
702 <autotools id="gedit-plugins">
703 <branch/>
704 <dependencies>
705 <dep package="gedit"/>
706 </dependencies>
707 </autotools>
708 <autotools id="memprof">
709 <branch/>
710 <dependencies>
711 <dep package="libgnomeui"/>
712 </dependencies>
713 </autotools>
714 <autotools id="eog">
715 <branch/>
716 <dependencies>
717 <dep package="libgnomeui"/>
718 <dep package="libgnomeprint"/>
719 </dependencies>
720 </autotools>
721 <autotools id="libgsf">
722 <branch/>
723 <dependencies>
724 <dep package="glib"/>
725 <dep package="gnome-vfs"/>
726 <dep package="libbonobo"/>
727 </dependencies>
728 </autotools>
729 <autotools id="goffice">
730 <branch/>
731 <dependencies>
732 <dep package="glib"/>
733 <dep package="libgsf"/>
734 <dep package="libxml2"/>
735 <dep package="pango"/>
736 <dep package="libglade"/>
737 <dep package="libgnomeprint"/>
738 <dep package="libgnomeprintui"/>
739 <dep package="libart_lgpl"/>
740 </dependencies>
741 </autotools>
742 <autotools id="gnumeric">
743 <branch/>
744 <dependencies>
745 <dep package="goffice"/>
746 <dep package="libgsf"/>
747 <dep package="pygtk"/>
748 <dep package="libgnomeprintui"/>
749 </dependencies>
750 </autotools>
751 <autotools id="gimp" autogenargs="--disable-print">
752 <branch/>
753 <dependencies>
754 <dep package="gtk+"/>
755 <dep package="libart_lgpl"/>
756 </dependencies>
757 </autotools>
758 <autotools id="glade">
759 <branch/>
760 <dependencies>
761 <dep package="gtk+"/>
762 <dep package="libxml2"/>
763 <dep package="libgnomeui"/>
764 <dep package="libgnomeprintui"/>
765 </dependencies>
766 </autotools>
767 <autotools id="glade2c">
768 <branch/>
769 <dependencies>
770 <dep package="gtk+"/>
771 <dep package="libxml2"/>
772 <dep package="libgnomeui"/>
773 </dependencies>
774 </autotools>
775 <autotools id="sawfish">
776 <branch revision="gnome-2"/>
777 <dependencies>
778 <dep package="rep-gtk"/>
779 </dependencies>
780 </autotools>
781 <autotools id="rep-gtk">
782 <branch/>
783 <dependencies>
784 <dep package="librep"/>
785 <dep package="gtk+"/>
786 </dependencies>
787 </autotools>
788 <autotools id="librep">
789 <branch/>
790 </autotools>
791 <autotools id="rhythmbox">
792 <branch/>
793 <dependencies>
794 <dep package="libgnomeui"/>
795 <dep package="gst-plugins-base"/>
796 <dep package="nautilus-cd-burner"/>
797 <dep package="totem"/>
798 <dep package="gnome-doc-utils"/>
799 </dependencies>
800 </autotools>
801 <autotools id="gstreamer-0-8" autogenargs="-- --disable-plugin-builddir --disable-tests" supports-non-srcdir-builds="no">
802 <branch repo="gstreamer.freedesktop.org" module="gstreamer"
803 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gstreamer-0-8"/>
804 <dependencies>
805 <dep package="glib"/>
806 <dep package="libxml2"/>
807 </dependencies>
808 </autotools>
809
810 <autotools id="gst-plugins-0-8" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
811 <branch repo="gstreamer.freedesktop.org" module="gst-plugins"
812 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gst-plugins-0-8"/>
813 <dependencies>
814 <dep package="gstreamer-0-8"/>
815 <dep package="gnome-vfs"/>
816 <dep package="gtk+"/>
817 </dependencies>
818 </autotools>
819
820 <autotools id="gst-python-0-8" autogenargs="--" supports-non-srcdir-builds="no">
821 <branch repo="gstreamer.freedesktop.org" module="gst-python"
822 revision="BRANCH-GSTREAMER-0_8" checkoutdir="gst-python-0-8"/>
823 <dependencies>
824 <dep package="gstreamer-0-8"/>
825 <dep package="gst-plugins-0-8"/>
826 </dependencies>
827 </autotools>
828
829 <autotools id="gstreamer" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
830 <branch repo="gstreamer.freedesktop.org" module="gstreamer"/>
831 <dependencies>
832 <dep package="glib"/>
833 <dep package="libxml2"/>
834 </dependencies>
835 </autotools>
836
837 <autotools id="liboil">
838 <branch repo="liboil.freedesktop.org" revision="liboil_0_3_6"/>
839 </autotools>
840
841 <autotools id="gst-plugins-base" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
842 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-base"/>
843 <dependencies>
844 <dep package="gstreamer"/>
845 <dep package="gnome-vfs"/>
846 <dep package="gtk+"/>
847 <dep package="liboil"/>
848 </dependencies>
849 </autotools>
850
851 <autotools id="gst-plugins-good" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
852 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-good"/>
853 <dependencies>
854 <dep package="gstreamer"/>
855 <dep package="gst-plugins-base"/>
856 </dependencies>
857 </autotools>
858
859 <autotools id="gst-plugins-ugly" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
860 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-ugly"/>
861 <dependencies>
862 <dep package="gstreamer"/>
863 <dep package="gst-plugins-base"/>
864 </dependencies>
865 </autotools>
866
867 <autotools id="gst-plugins-bad" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
868 <branch repo="gstreamer.freedesktop.org" module="gst-plugins-bad"/>
869 <dependencies>
870 <dep package="gstreamer"/>
871 <dep package="gst-plugins-base"/>
872 </dependencies>
873 </autotools>
874
875 <autotools id="gst-ffmpeg" autogenargs="-- --disable-tests" supports-non-srcdir-builds="no">
876 <branch repo="gstreamer.freedesktop.org" module="gst-ffmpeg"/>
877 <dependencies>
878 <dep package="gstreamer"/>
879 <dep package="gst-plugins-base"/>
880 </dependencies>
881 </autotools>
882
883 <autotools id="gst-python" autogenargs="--" supports-non-srcdir-builds="no">
884 <branch repo="gstreamer.freedesktop.org" module="gst-python"/>
885 <dependencies>
886 <dep package="gstreamer"/>
887 <dep package="gst-plugins-base"/>
888 </dependencies>
889 </autotools>
890
891 <autotools id="planner">
892 <branch/>
893 <dependencies>
894 <dep package="glib"/>
895 <dep package="libxml2"/>
896 <dep package="libgnomeui"/>
897 <dep package="libgnomeprintui"/>
898 <dep package="libgsf"/>
899 </dependencies>
900 </autotools>
901 <autotools id="file-roller">
902 <branch/>
903 <dependencies>
904 <dep package="scrollkeeper"/>
905 <dep package="gnome-doc-utils"/>
906 <dep package="nautilus"/>
907 </dependencies>
908 </autotools>
909 <autotools id="balsa">
910 <branch revision="BALSA_2"/>
911 <dependencies>
912 <dep package="libgnomeui"/>
913 </dependencies>
914 </autotools>
915 <autotools id="pan">
916 <branch/>
917 <dependencies>
918 <dep package="libgnomeui"/>
919 <dep package="gnet"/>
920 </dependencies>
921 </autotools>
922 <distutils id="pyspi">
923 <branch/>
924 <dependencies>
925 <dep package="at-spi"/>
926 </dependencies>
927 </distutils>
928 <distutils id="dogtail">
929 <branch/>
930 <dependencies>
931 <dep package="pyspi"/>
932 </dependencies>
933 <after>
934 <dep package="gnome-python-desktop"/>
935 </after>
936 </distutils>
937 <autotools id="gcalctool" supports-non-srcdir-builds="no">
938 <branch/>
939 <dependencies>
940 <dep package="scrollkeeper"/>
941 <dep package="libgnomeui"/>
942 <dep package="gnome-doc-utils"/>
943 </dependencies>
944 </autotools>
945 <autotools id="ggv" supports-non-srcdir-builds="no">
946 <branch/>
947 <dependencies>
948 <dep package="scrollkeeper"/>
949 <dep package="libgnomeui"/>
950 </dependencies>
951 </autotools>
952 <autotools id="ekiga" autogenargs="--with-pwlib-dir=`ptlib-config --prefix` --with-opal-dir=`ptlib-config --prefix`">
953 <branch revision="gnome-2-14"/>
954 <dependencies>
955 <dep package="libgnomeui"/>
956 <dep package="evolution-data-server"/>
957 <dep package="opal" />
958 </dependencies>
959 </autotools>
960 <autotools id="pwlib" autogen-sh="configure">
961 <branch repo="openh323.sf.net" module="ptlib_unix" checkoutdir="pwlib"
962 override-checkoutdir="no" update-new-dirs="no" />
963 </autotools>
964 <autotools id="opal" autogen-sh="configure">
965 <branch repo="openh323.sf.net"/>
966 <dependencies>
967 <dep package="pwlib"/>
968 </dependencies>
969 </autotools>
970 <autotools id="gucharmap">
971 <branch/>
972 <dependencies>
973 <dep package="libgnomeui"/>
974 <dep package="gnome-doc-utils"/>
975 </dependencies>
976 </autotools>
977 <autotools id="gtksourceview" autogenargs="--enable-compile-warnings=maximum">
978 <branch/>
979 <dependencies>
980 <dep package="gtk+"/>
981 <dep package="libxml2"/>
982 <dep package="libgnomeprint"/>
983 <dep package="gnome-vfs"/>
984 </dependencies>
985 </autotools>
986 <autotools id="glimmer">
987 <branch/>
988 <dependencies>
989 <dep package="gtksourceview"/>
990 <dep package="libgnomeprint"/>
991 </dependencies>
992 </autotools>
993 <autotools id="gdl">
994 <branch/>
995 <dependencies>
996 <dep package="libgnomeui"/>
997 <dep package="librsvg"/>
998 </dependencies>
999 </autotools>
1000 <autotools id="gnome-build">
1001 <branch/>
1002 <dependencies>
1003 <dep package="gdl"/>
1004 <dep package="gnome-vfs"/>
1005 <dep package="gtkhtml2"/>
1006 </dependencies>
1007 </autotools>
1008 <autotools id="scaffold">
1009 <branch/>
1010 <dependencies>
1011 <dep package="libgnomeui"/>
1012 <dep package="vte"/>
1013 <dep package="gdl"/>
1014 </dependencies>
1015 </autotools>
1016 <autotools id="libsigc++2">
1017 <branch revision="libsigc-2-0"/>
1018 </autotools>
1019 <autotools id="glibmm">
1020 <branch/>
1021 <dependencies>
1022 <dep package="glib"/>
1023 <dep package="libsigc++2"/>
1024 </dependencies>
1025 </autotools>
1026 <autotools id="gtkmm">
1027 <branch/>
1028 <dependencies>
1029 <dep package="glibmm"/>
1030 <dep package="cairomm"/>
1031 <dep package="gtk+"/>
1032 </dependencies>
1033 </autotools>
1034 <autotools id="orbitcpp">
1035 <branch/>
1036 <dependencies>
1037 <dep package="ORBit2"/>
1038 </dependencies>
1039 </autotools>
1040 <autotools id="gnomemm/libgnomemm">
1041 <branch/>
1042 <dependencies>
1043 <dep package="libgnome"/>
1044 <dep package="gtkmm"/>
1045 </dependencies>
1046 </autotools>
1047 <autotools id="gnomemm/libglademm">
1048 <branch/>
1049 <dependencies>
1050 <dep package="libglade"/>
1051 <dep package="gtkmm"/>
1052 </dependencies>
1053 </autotools>
1054 <autotools id="gnomemm/libbonobomm">
1055 <branch/>
1056 <dependencies>
1057 <dep package="libbonobo"/>
1058 <dep package="gtkmm"/>
1059 <dep package="orbitcpp"/>
1060 </dependencies>
1061 </autotools>
1062 <autotools id="gnomemm/libbonobouimm">
1063 <branch/>
1064 <dependencies>
1065 <dep package="libbonoboui"/>
1066 <dep package="gnomemm/libbonobomm"/>
1067 </dependencies>
1068 </autotools>
1069 <autotools id="gnomemm/libgnomecanvasmm">
1070 <branch/>
1071 <dependencies>
1072 <dep package="libgnomecanvas"/>
1073 <dep package="gtkmm"/>
1074 </dependencies>
1075 </autotools>
1076 <autotools id="gnomemm/gconfmm">
1077 <branch/>
1078 <dependencies>
1079 <dep package="gconf"/>
1080 <dep package="gtkmm"/>
1081 </dependencies>
1082 </autotools>
1083 <autotools id="gnomemm/libgnomeuimm">
1084 <branch/>
1085 <dependencies>
1086 <dep package="gtkmm"/>
1087 <dep package="libgnomeui"/>
1088 <dep package="gnomemm/libgnomemm"/>
1089 <dep package="gnomemm/gconfmm"/>
1090 <dep package="gnomemm/libgnomecanvasmm"/>
1091 <dep package="gnomemm/libglademm"/>
1092 <dep package="gnomemm/gnome-vfsmm"/>
1093 </dependencies>
1094 </autotools>
1095 <autotools id="gnomemm/gnome-vfsmm">
1096 <branch/>
1097 <dependencies>
1098 <dep package="glibmm"/>
1099 <dep package="gnome-vfs"/>
1100 </dependencies>
1101 </autotools>
1102 <autotools id="gnomemm/libpanelappletmm">
1103 <branch/>
1104 <dependencies>
1105 <dep package="gtkmm"/>
1106 </dependencies>
1107 </autotools>
1108 <autotools id="gnomemm/libgnomeprintmm">
1109 <branch/>
1110 <dependencies>
1111 <dep package="gtkmm"/>
1112 <dep package="libgnomeprint"/>
1113 </dependencies>
1114 </autotools>
1115 <autotools id="gnomemm/libgnomeprintuimm">
1116 <branch/>
1117 <dependencies>
1118 <dep package="gtkmm"/>
1119 <dep package="gnomemm/libgnomeprintmm"/>
1120 <dep package="libgnomeprintui"/>
1121 </dependencies>
1122 </autotools>
1123 <autotools id="gnomemm/libgdamm">
1124 <branch revision="libgda-1-2"/>
1125 <dependencies>
1126 <dep package="gtkmm"/>
1127 <dep package="libgda-1-2"/>
1128 </dependencies>
1129 </autotools>
1130 <autotools id="gnomemm/gtkmm_hello">
1131 <branch/>
1132 <dependencies>
1133 <dep package="gtkmm"/>
1134 </dependencies>
1135 </autotools>
1136 <autotools id="regexxer">
1137 <branch/>
1138 <dependencies>
1139 <dep package="intltool"/>
1140 <dep package="gtkmm"/>
1141 <dep package="gnomemm/gconfmm"/>
1142 <dep package="gnomemm/libglademm"/>
1143 </dependencies>
1144 </autotools>
1145 <autotools id="gnet" autogenargs="--enable-glib2">
1146 <branch revision="GNET_1_1"/>
1147 <dependencies>
1148 <dep package="glib"/>
1149 </dependencies>
1150 </autotools>
1151 <autotools id="gnomeicu">
1152 <branch/>
1153 <dependencies>
1154 <dep package="libgnomeui"/>
1155 </dependencies>
1156 </autotools>
1157 <autotools id="at-spi">
1158 <branch/>
1159 <dependencies>
1160 <dep package="libbonobo"/>
1161 <dep package="gail"/>
1162 </dependencies>
1163 </autotools>
1164 <autotools id="libgail-gnome">
1165 <branch/>
1166 <dependencies>
1167 <dep package="at-spi"/>
1168 <dep package="libgnomeui"/>
1169 <dep package="gnome-panel"/>
1170 </dependencies>
1171 </autotools>
1172 <autotools id="at-poke">
1173 <branch/>
1174 <dependencies>
1175 <dep package="libgail-gnome"/>
1176 </dependencies>
1177 </autotools>
1178 <autotools id="gnome-mag">
1179 <branch/>
1180 <dependencies>
1181 <dep package="at-spi"/>
1182 </dependencies>
1183 </autotools>
1184 <autotools id="gok">
1185 <branch/>
1186 <dependencies>
1187 <dep package="at-spi"/>
1188 <dep package="libgnomeui"/>
1189 <dep package="libwnck"/>
1190 <dep package="esound"/>
1191 <dep package="scrollkeeper"/>
1192 <dep package="gnome-speech"/>
1193 </dependencies>
1194 </autotools>
1195 <autotools id="gnome-speech">
1196 <branch/>
1197 <dependencies>
1198 <dep package="libbonobo"/>
1199 </dependencies>
1200 </autotools>
1201 <autotools id="gnopernicus">
1202 <branch/>
1203 <dependencies>
1204 <dep package="gconf"/>
1205 <dep package="libgnomeui"/>
1206 <dep package="gnome-speech"/>
1207 <dep package="gnome-mag"/>
1208 </dependencies>
1209 </autotools>
1210 <autotools id="orca">
1211 <branch/>
1212 <dependencies>
1213 <dep package="gnome-python"/>
1214 <dep package="libgail-gnome"/>
1215 <dep package="gnome-mag"/>
1216 <dep package="gnome-speech"/>
1217 <dep package="eel"/>
1218 </dependencies>
1219 </autotools>
1220 <autotools id="dasher" autogenargs="--with-a11y --with-gnome">
1221 <branch/>
1222 <dependencies>
1223 <dep package="at-spi"/>
1224 <dep package="libgnomeui"/>
1225 <dep package="gnome-speech"/>
1226 <dep package="gnome-vfs"/>
1227 <dep package="gnome-doc-utils"/>
1228 </dependencies>
1229 </autotools>
1230 <autotools id="gnome-screensaver">
1231 <branch/>
1232 <dependencies>
1233 <dep package="gconf"/>
1234 <dep package="gtk+"/>
1235 <dep package="dbus"/>
1236 <dep package="gnome-menus"/>
1237 <dep package="libgnomeui"/>
1238 </dependencies>
1239 </autotools>
1240 <autotools id="gnome-power-manager">
1241 <branch/>
1242 <dependencies>
1243 <dep package="libgnomeui"/>
1244 <dep package="hal"/>
1245 <dep package="libwnck"/>
1246 <dep package="gtk+"/>
1247 <dep package="gconf"/>
1248 <dep package="intltool"/>
1249 <dep package="libglade"/>
1250 <dep package="gnome-doc-utils"/>
1251 </dependencies>
1252 <suggests>
1253 <dep package="libnotify"/>
1254 </suggests>
1255 </autotools>
1256 <autotools id="gthumb">
1257 <branch/>
1258 <dependencies>
1259 <dep package="libgnomeui"/>
1260 <dep package="gnome-vfs"/>
1261 <dep package="libglade"/>
1262 <dep package="libbonoboui"/>
1263 <dep package="libgnomeprintui"/>
1264 </dependencies>
1265 </autotools>
1266 <autotools id="fast-user-switch-applet">
1267 <branch/>
1268 <dependencies>
1269 <dep package="gtk+"/>
1270 <dep package="gconf"/>
1271 <dep package="libglade"/>
1272 <dep package="gnome-panel"/>
1273 </dependencies>
1274 </autotools>
1275 <autotools id="gnome-mount" autogenargs="--enable-nautilus-extension">
1276 <branch/>
1277 <dependencies>
1278 <dep package="gnome-keyring"/>
1279 <dep package="libgnomeui"/>
1280 <dep package="dbus"/>
1281 <dep package="hal"/>
1282 <dep package="gtk+"/>
1283 <dep package="intltool"/>
1284 <dep package="libglade"/>
1285 <dep package="eel"/>
1286 <dep package="nautilus"/>
1287 </dependencies>
1288 </autotools>
1289 <autotools id="libnotify">
1290 <branch repo="svn.galago-project.org" module="trunk/libnotify"/>
1291 <dependencies>
1292 <dep package="gtk+"/>
1293 <dep package="dbus"/>
1294 </dependencies>
1295 </autotools>
1296 <autotools id="libsexy">
1297 <branch repo="osiris.chipx86.com" module="trunk/libsexy"/>
1298 <dependencies>
1299 <dep package="gtk+"/>
1300 <dep package="libxml2"/>
1301 <dep package="iso-codes"/>
1302 </dependencies>
1303 </autotools>
1304 <autotools id="notification-daemon">
1305 <branch repo="svn.galago-project.org" module="trunk/notification-daemon"/>
1306 <dependencies>
1307 <dep package="gtk+"/>
1308 <dep package="dbus"/>
1309 <dep package="libsexy"/>
1310 </dependencies>
1311 </autotools>
1312 <autotools id="alacarte">
1313 <branch/>
1314 <dependencies>
1315 <dep package="gnome-menus"/>
1316 <dep package="pygtk"/>
1317 </dependencies>
1318 </autotools>
1319
1320 <metamodule id="meta-gnome-devel-platform">
1321 <dependencies>
1322 <dep package="libgnome"/>
1323 <dep package="libbonobo"/>
1324 <dep package="libbonoboui"/>
1325 <dep package="libgnomeui"/>
1326 </dependencies>
1327 </metamodule>
1328 <metamodule id="meta-gnome-core">
1329 <dependencies>
1330 <dep package="gnome-desktop"/>
1331 <dep package="gnome-panel"/>
1332 <dep package="gnome-session"/>
1333 <dep package="gnome-terminal"/>
1334 <dep package="gnome-applets"/>
1335 </dependencies>
1336 </metamodule>
1337 <metamodule id="meta-nautilus">
1338 <dependencies>
1339 <dep package="nautilus"/>
1340 </dependencies>
1341 </metamodule>
1342 <metamodule id="meta-gnome-desktop">
1343 <dependencies>
1344 <dep package="meta-gnome-core"/>
1345 <dep package="gnome-control-center"/>
1346 <dep package="meta-nautilus"/>
1347 <dep package="yelp"/>
1348 <dep package="bug-buddy"/>
1349 <dep package="gedit"/>
1350 <dep package="gtk-engines"/>
1351 <dep package="eog"/>
1352 <dep package="metacity"/>
1353 <dep package="gconf-editor"/>
1354 <dep package="gnome-utils"/>
1355 <dep package="gnome-system-monitor"/>
1356 <dep package="gstreamer"/>
1357 <dep package="gnome-media"/>
1358 <dep package="gnome-netstatus"/>
1359 <dep package="gcalctool"/>
1360 <dep package="gucharmap"/>
1361 <dep package="nautilus-cd-burner"/>
1362 <dep package="zenity"/>
1363 <dep package="libgail-gnome"/>
1364 <dep package="gnopernicus"/>
1365 <dep package="gok"/>
1366 <dep package="epiphany"/>
1367 <dep package="gnome-games"/>
1368 <dep package="gnome-user-docs"/>
1369 <dep package="file-roller"/>
1370 <dep package="gnome-system-tools"/>
1371 <dep package="gnome-nettool"/>
1372 <dep package="vino"/>
1373 <dep package="gnome-volume-manager"/>
1374 <dep package="totem"/>
1375 <dep package="gnome-menus"/>
1376 <dep package="gnome-backgrounds"/>
1377 <dep package="sound-juicer"/>
1378 <dep package="evolution"/>
1379 <dep package="evolution-webcal"/>
1380 <dep package="evolution-exchange"/>
1381 <dep package="ekiga"/>
1382 <dep package="evince"/>
1383 <dep package="dasher"/>
1384 <dep package="gnome-keyring-manager"/>
1385 <dep package="deskbar-applet"/>
1386 <dep package="fast-user-switch-applet"/>
1387 <dep package="gnome-screensaver"/>
1388 <dep package="meta-gnome-admin"/>
1389 </dependencies>
1390 </metamodule>
1391 <metamodule id="meta-gnome-admin">
1392 <dependencies>
1393 <dep package="pessulus"/>
1394 <dep package="sabayon"/>
1395 </dependencies>
1396 </metamodule>
1397 <metamodule id="meta-gnome-devel-tools">
1398 <dependencies>
1399 <dep package="glade"/>
1400 <dep package="memprof"/>
1401 <dep package="gconf-editor"/>
1402 <dep package="devhelp"/>
1403 <dep package="nautilus-vcs"/>
1404 </dependencies>
1405 </metamodule>
1406 <metamodule id="meta-gnome-python">
1407 <dependencies>
1408 <dep package="pygtk"/>
1409 <dep package="gnome-python"/>
1410 <dep package="gnome-python-desktop"/>
1411 </dependencies>
1412 <after>
1413 <dep package="gnome-python-extras"/>
1414 </after>
1415 </metamodule>
1416 <metamodule id="meta-gnome-c++">
1417 <dependencies>
1418 <dep package="gtkmm"/>
1419 <dep package="gnomemm/libgnomeuimm"/>
1420 <dep package="gnomemm/gnome-vfsmm"/>
1421 <dep package="gnomemm/libpanelappletmm"/>
1422 <dep package="gnomemm/libbonobouimm"/>
1423 <dep package="gnomemm/libgnomeprintuimm"/>
1424 <dep package="libxml++"/>
1425 <dep package="gnomemm/libgdamm"/>
1426 <dep package="bakery"/>
1427 </dependencies>
1428 </metamodule>
1429 <metamodule id="meta-gnome-accessibility">
1430 <dependencies>
1431 <dep package="libgail-gnome"/>
1432 <dep package="at-poke"/>
1433 <dep package="dasher"/>
1434 <dep package="gnome-mag"/>
1435 <dep package="gok"/>
1436 <dep package="gnome-speech"/>
1437 <dep package="gnopernicus"/>
1438 </dependencies>
1439 </metamodule>
1440 <metamodule id="meta-gnome-proposed">
1441 <dependencies>
1442 <dep package="alacarte"/>
1443 <dep package="gnome-power-manager"/>
1444 <dep package="orca"/>
1445 </dependencies>
1446 </metamodule>
1447 <autotools id="sodipodi">
1448 <branch/>
1449 <dependencies>
1450 <dep package="gtk+"/>
1451 <dep package="libgnomeprintui"/>
1452 <dep package="libart_lgpl"/>
1453 <dep package="libxml2"/>
1454 </dependencies>
1455 </autotools>
1456 <autotools id="gnome-themes">
1457 <branch/>
1458 <dependencies>
1459 <dep package="gtk-engines"/>
1460 </dependencies>
1461 </autotools>
1462 <autotools id="gob">
1463 <branch/>
1464 <dependencies>
1465 <dep package="glib"/>
1466 </dependencies>
1467 </autotools>
1468 <autotools id="libgnetwork">
1469 <branch/>
1470 <dependencies>
1471 <dep package="glib"/>
1472 <dep package="gconf"/>
1473 <dep package="intltool"/>
1474 </dependencies>
1475 </autotools>
1476 <autotools id="libgircclient">
1477 <branch/>
1478 <dependencies>
1479 <dep package="libgnetwork"/>
1480 </dependencies>
1481 </autotools>
1482 <autotools id="gnomechat">
1483 <branch/>
1484 <dependencies>
1485 <dep package="libgnetwork"/>
1486 <dep package="libgircclient"/>
1487 <dep package="libgnomeui"/>
1488 </dependencies>
1489 </autotools>
1490 <mozillamodule id="mozilla" autogenargs="--enable-default-toolkit=gtk2 --disable-mailnews --disable-ldap --disable-debug --enable-optimize --disable-tests --enable-crypto --enable-xft --with-system-zlib --disable-freetype2 --enable-application=browser" cvsroot="mozilla.org" revision="MOZILLA_1_7_BRANCH">
1491 <dependencies>
1492 <dep package="gtk+"/>
1493 </dependencies>
1494 </mozillamodule>
1495 <autotools id="enchant">
1496 <branch repo="anoncvs.abisource.com"/>
1497 <dependencies>
1498 <dep package="glib"/>
1499 </dependencies>
1500 </autotools>
1501 <autotools id="epiphany">
1502 <branch/>
1503 <dependencies>
1504 <dep package="iso-codes"/>
1505 <dep package="libgnomeui"/>
1506 <dep package="pygtk"/>
1507 <dep package="gnome-python"/>
1508 <dep package="gnome-doc-utils"/>
1509 </dependencies>
1510 <suggests>
1511 <dep package="enchant"/>
1512 </suggests>
1513 </autotools>
1514 <autotools id="epiphany-extensions">
1515 <branch/>
1516 <dependencies>
1517 <dep package="epiphany"/>
1518 </dependencies>
1519 </autotools>
1520 <autotools id="galeon">
1521 <branch/>
1522 <dependencies>
1523 <dep package="mozilla"/>
1524 <dep package="libgnomeui"/>
1525 </dependencies>
1526 </autotools>
1527 <autotools id="libsoup">
1528 <branch/>
1529 <dependencies>
1530 <dep package="glib"/>
1531 <dep package="gnutls"/>
1532 <dep package="libxml2"/>
1533 </dependencies>
1534 </autotools>
1535 <autotools id="gtkhtml">
1536 <branch/>
1537 <dependencies>
1538 <dep package="gtk+"/>
1539 <dep package="libgnomeui"/>
1540 <dep package="libbonoboui"/>
1541 <dep package="libglade"/>
1542 <dep package="gail"/>
1543 <dep package="libgnomeprint"/>
1544 <dep package="libgnomeprintui"/>
1545 <dep package="libsoup"/>
1546 </dependencies>
1547 </autotools>
1548 <autotools id="evolution-data-server" supports-non-srcdir-builds="no">
1549 <branch/>
1550 <dependencies>
1551 <dep package="libbonobo"/>
1552 <dep package="libgnome"/>
1553 <dep package="libgnomeui"/>
1554 <dep package="libsoup"/>
1555 <dep package="libxml2"/>
1556 <dep package="gconf"/>
1557 <dep package="gnome-vfs"/>
1558 <dep package="mozilla"/>
1559 </dependencies>
1560 </autotools>
1561 <autotools id="evolution">
1562 <branch/>
1563 <dependencies>
1564 <dep package="evolution-data-server"/>
1565 <dep package="gtkhtml"/>
1566 <dep package="libgnomeui"/>
1567 <dep package="libbonoboui"/>
1568 </dependencies>
1569 <after>
1570 <dep package="libnotify"/>
1571 </after>
1572 </autotools>
1573 <autotools id="evolution-webcal">
1574 <branch/>
1575 <dependencies>
1576 <dep package="evolution-data-server"/>
1577 <dep package="libsoup"/>
1578 <dep package="libgnomeui"/>
1579 </dependencies>
1580 </autotools>
1581 <autotools id="evolution-exchange">
1582 <branch/>
1583 <dependencies>
1584 <dep package="evolution-data-server"/>
1585 <dep package="evolution"/>
1586 <dep package="libsoup"/>
1587 </dependencies>
1588 </autotools>
1589 <tarball id="xchat" version="2.6.2">
1590 <source href="http://xchat.org/files/source/2.6/xchat-2.6.2.tar.bz2"
1591 size="1046910" md5sum="6b534baf9a4df6bf23d7d16f7e4eb379"/>
1592 <dependencies>
1593 <dep package="gtk+"/>
1594 <dep package="libxml2"/>
1595 </dependencies>
1596 </tarball>
1597 <tarball id="camorama" version="0.17">
1598 <source href="http://camorama.fixedgear.org/downloads/camorama-0.17.tar.bz2"
1599 size="312233" md5sum="2b2784af53a1ba8fa4419aa806967b35"/>
1600 <dependencies>
1601 <dep package="gtk+"/>
1602 </dependencies>
1603 </tarball>
1604 <autotools id="gtk-engines-cleanice">
1605 <branch repo="elysium-project.sf.net"/>
1606 <dependencies>
1607 <dep package="gtk+"/>
1608 </dependencies>
1609 </autotools>
1610 <autotools id="gaim">
1611 <branch repo="gaim.sf.net" module="trunk" checkoutdir="gaim"/>
1612 <dependencies>
1613 <dep package="libgnomeui"/>
1614 </dependencies>
1615 </autotools>
1616 <autotools id="zenity">
1617 <branch/>
1618 <dependencies>
1619 <dep package="gtk+"/>
1620 <dep package="gconf"/>
1621 <dep package="libgnomecanvas"/>
1622 <dep package="gnome-doc-utils"/>
1623 </dependencies>
1624 </autotools>
1625 <autotools id="gpdf">
1626 <branch/>
1627 <dependencies>
1628 <dep package="libgnomeui"/>
1629 <dep package="libbonoboui"/>
1630 <dep package="libgnomeprintui"/>
1631 </dependencies>
1632 </autotools>
1633 <autotools id="gnome-netstatus">
1634 <branch/>
1635 <dependencies>
1636 <dep package="libgnomeui"/>
1637 <dep package="gnome-panel"/>
1638 <dep package="gnome-doc-utils"/>
1639 </dependencies>
1640 </autotools>
1641 <autotools id="gnome-doc-utils">
1642 <branch/>
1643 <dependencies>
1644 <dep package="libxslt"/>
1645 <dep package="intltool"/>
1646 <dep package="glib"/>
1647 </dependencies>
1648 </autotools>
1649 <tarball id="libmusicbrainz" version="2.1.2">
1650 <source href="http://ftp.musicbrainz.org/pub/musicbrainz/libmusicbrainz-2.1.2.tar.gz"
1651 size="504432" md5sum="88d35af903665fecbdee77eb6d5e6cdd"/>
1652 </tarball>
1653 <autotools id="totem" autogenargs="--enable-gstreamer">
1654 <branch/>
1655 <dependencies>
1656 <dep package="gnome-desktop"/>
1657 <dep package="nautilus-cd-burner"/>
1658 <dep package="gstreamer"/>
1659 <dep package="gst-plugins-base"/>
1660 <dep package="gst-plugins-good"/>
1661 <dep package="libmusicbrainz"/>
1662 <dep package="iso-codes"/>
1663 </dependencies>
1664 </autotools>
1665 <autotools id="gnome-themes-extras">
1666 <branch/>
1667 <dependencies>
1668 <dep package="gnome-themes"/>
1669 </dependencies>
1670 </autotools>
1671
1672 <autotools id="libgda">
1673 <branch module="libgda"/>
1674 <dependencies>
1675 <dep package="glib"/>
1676 </dependencies>
1677 </autotools>
1678 <autotools id="libgda-1-2">
1679 <branch module="libgda" revision="release-1-2-branch"
1680 checkoutdir="libgda-1-2"/>
1681 <dependencies>
1682 <dep package="glib"/>
1683 </dependencies>
1684 </autotools>
1685
1686 <autotools id="libgnomedb" autogenargs="--enable-gnome=yes">
1687 <branch/>
1688 <dependencies>
1689 <dep package="libgda"/>
1690 <dep package="libgnomeui"/>
1691 <dep package="libbonoboui"/>
1692 </dependencies>
1693 </autotools>
1694 <autotools id="mergeant">
1695 <branch/>
1696 <dependencies>
1697 <dep package="libgnomedb"/>
1698 </dependencies>
1699 </autotools>
1700 <autotools id="gtranslator">
1701 <branch/>
1702 <dependencies>
1703 <dep package="libgnomeui"/>
1704 </dependencies>
1705 </autotools>
1706 <autotools id="gnome-spell">
1707 <branch/>
1708 <dependencies>
1709 <dep package="libgnomeui"/>
1710 </dependencies>
1711 </autotools>
1712 <autotools id="libgnomecups">
1713 <branch/>
1714 <dependencies>
1715 <dep package="glib"/>
1716 </dependencies>
1717 </autotools>
1718 <autotools id="gnome-cups-manager">
1719 <branch/>
1720 <dependencies>
1721 <dep package="libgnomecups"/>
1722 <dep package="libgnomeui"/>
1723 <dep package="libglade"/>
1724 </dependencies>
1725 </autotools>
1726 <autotools id="libxml++">
1727 <branch/>
1728 <dependencies>
1729 <dep package="libxml2"/>
1730 <dep package="glibmm"/>
1731 </dependencies>
1732 </autotools>
1733 <autotools id="bakery">
1734 <branch/>
1735 <dependencies>
1736 <dep package="libxml++"/>
1737 <dep package="gtkmm"/>
1738 <dep package="gnomemm/libglademm"/>
1739 <dep package="gnomemm/gconfmm"/>
1740 <dep package="gnomemm/gnome-vfsmm"/>
1741 </dependencies>
1742 </autotools>
1743 <autotools id="gnome-hello">
1744 <branch/>
1745 <dependencies>
1746 <dep package="glib"/>
1747 <dep package="libgnome"/>
1748 <dep package="libgnomeui"/>
1749 </dependencies>
1750 </autotools>
1751 <autotools id="liboobs">
1752 <branch/>
1753 <dependencies>
1754 <dep package="glib"/>
1755 <dep package="dbus"/>
1756 <dep package="gtk-doc"/>
1757 <dep package="system-tools-backends"/>
1758 </dependencies>
1759 </autotools>
1760 <autotools id="gnome-system-tools">
1761 <branch revision="gnome-2-14"/>
1762 <dependencies>
1763 <dep package="glib"/>
1764 <dep package="libxml2"/>
1765 <dep package="gconf"/>
1766 <dep package="libgnomeui"/>
1767 <dep package="libbonoboui"/>
1768 <dep package="libglade"/>
1769 <dep package="nautilus"/>
1770 <dep package="system-tools-backends"/>
1771 <dep package="gnome-doc-utils"/>
1772 </dependencies>
1773 </autotools>
1774 <autotools id="gnome-user-docs">
1775 <branch/>
1776 <dependencies>
1777 <dep package="scrollkeeper"/>
1778 <dep package="gnome-doc-utils"/>
1779 </dependencies>
1780 </autotools>
1781 <autotools id="loudmouth">
1782 <branch/>
1783 <dependencies>
1784 <dep package="glib"/>
1785 </dependencies>
1786 </autotools>
1787 <autotools id="gossip">
1788 <branch/>
1789 <dependencies>
1790 <dep package="loudmouth"/>
1791 <dep package="libgnomeui"/>
1792 </dependencies>
1793 </autotools>
1794 <autotools id="conglomerate">
1795 <branch/>
1796 <dependencies>
1797 <dep package="libxslt"/>
1798 <dep package="gconf"/>
1799 <dep package="libgnomeui"/>
1800 </dependencies>
1801 </autotools>
1802 <autotools id="sound-juicer">
1803 <branch/>
1804 <dependencies>
1805 <dep package="gnome-doc-utils"/>
1806 <dep package="libgnomeui"/>
1807 <dep package="gnome-media"/>
1808 <dep package="gstreamer"/>
1809 <dep package="gst-plugins-base"/>
1810 <dep package="gst-plugins-good"/>
1811 <dep package="nautilus-cd-burner"/>
1812 </dependencies>
1813 </autotools>
1814 <autotools id="gnome-network">
1815 <branch/>
1816 <dependencies>
1817 <dep package="glib"/>
1818 </dependencies>
1819 </autotools>
1820 <tarball id="guile" version="1.8.0">
1821 <source href="ftp://ftp.gnu.org/gnu/guile/guile-1.8.0.tar.gz"
1822 size="3691677" md5sum="3f47443602f93e94bf43218d9b86099d"/>
1823 </tarball>
1824 <tarball id="autogen" version="5.8.4">
1825 <source href="http://internap.dl.sourceforge.net/sourceforge/autogen/autogen-5.8.4.tar.bz2"
1826 size="931015" md5sum="b65d4b9e3ddbcfd5418b708858c05b66"/>
1827 <dependencies>
1828 <dep package="guile"/>
1829 </dependencies>
1830 </tarball>
1831 <autotools id="anjuta">
1832 <branch/>
1833 <dependencies>
1834 <dep package="libbonoboui"/>
1835 <dep package="libgnomeprintui"/>
1836 <dep package="vte"/>
1837 <dep package="gnome-build"/>
1838 <dep package="autogen"/>
1839 <dep package="devhelp"/>
1840 </dependencies>
1841 </autotools>
1842 <autotools id="OpenApplet">
1843 <branch/>
1844 <dependencies>
1845 <dep package="gnome-panel"/>
1846 </dependencies>
1847 </autotools>
1848 <autotools id="gtetrinet">
1849 <branch/>
1850 <dependencies>
1851 <dep package="libgnomeui"/>
1852 </dependencies>
1853 </autotools>
1854 <autotools id="glom">
1855 <branch/>
1856 <dependencies>
1857 <dep package="gnomemm/libgdamm"/>
1858 <dep package="bakery"/>
1859 <dep package="gnomemm/libgnomecanvasmm"/>
1860 <dep package="libgnome"/>
1861 <dep package="iso-codes"/>
1862 <dep package="pygtk"/>
1863 <dep package="gnome-python-extras"/>
1864 </dependencies>
1865 </autotools>
1866 <autotools id="vino">
1867 <branch/>
1868 <dependencies>
1869 <dep package="libgnomeui"/>
1870 <dep package="libglade"/>
1871 <dep package="gconf"/>
1872 <dep package="gnutls"/>
1873 </dependencies>
1874 </autotools>
1875 <autotools id="gnome-keyring-manager" autogenargs="--disable-more-warnings">
1876 <branch/>
1877 <dependencies>
1878 <dep package="libgnomeui"/>
1879 <dep package="gnome-keyring"/>
1880 <dep package="gconf"/>
1881 </dependencies>
1882 </autotools>
1883 <autotools id="gnome-volume-manager">
1884 <branch/>
1885 <dependencies>
1886 <dep package="libgnomeui"/>
1887 <dep package="libglade"/>
1888 <dep package="hal"/>
1889 </dependencies>
1890 </autotools>
1891 <metamodule id="meta-storage">
1892 <dependencies>
1893 <dep package="storage/storage-store"/>
1894 <dep package="storage/vfs"/>
1895 <dep package="storage/applet"/>
1896 </dependencies>
1897 </metamodule>
1898 <autotools id="storage/storage-store">
1899 <branch/>
1900 <dependencies>
1901 <dep package="dbus"/>
1902 </dependencies>
1903 </autotools>
1904 <autotools id="storage/libstorage">
1905 <branch/>
1906 <dependencies>
1907 <dep package="gnome-vfs"/>
1908 <dep package="pygtk"/>
1909 </dependencies>
1910 </autotools>
1911 <autotools id="storage/libstorage-translators">
1912 <branch/>
1913 <dependencies>
1914 <dep package="storage/libstorage"/>
1915 </dependencies>
1916 </autotools>
1917 <autotools id="storage/vfs">
1918 <branch/>
1919 <dependencies>
1920 <dep package="storage/libstorage"/>
1921 <dep package="storage/libstorage-translators"/>
1922 </dependencies>
1923 </autotools>
1924 <autotools id="storage/pet">
1925 <branch/>
1926 </autotools>
1927 <autotools id="storage/libmrs">
1928 <branch/>
1929 <dependencies>
1930 <dep package="storage/pet"/>
1931 </dependencies>
1932 </autotools>
1933 <autotools id="storage/libmrs-converter">
1934 <branch/>
1935 <dependencies>
1936 <dep package="storage/libmrs"/>
1937 </dependencies>
1938 </autotools>
1939 <autotools id="storage/libstorage-nl">
1940 <branch/>
1941 <dependencies>
1942 <dep package="storage/libstorage"/>
1943 <dep package="storage/libmrs"/>
1944 <dep package="storage/libmrs-converter"/>
1945 </dependencies>
1946 </autotools>
1947 <autotools id="storage/applet">
1948 <branch/>
1949 <dependencies>
1950 <dep package="gnome-python"/>
1951 <dep package="storage/libstorage-nl"/>
1952 </dependencies>
1953 </autotools>
1954 <autotools id="gnome-nettool">
1955 <branch/>
1956 <dependencies>
1957 <dep package="gtk+"/>
1958 <dep package="gconf"/>
1959 <dep package="libglade"/>
1960 <dep package="gnome-doc-utils"/>
1961 </dependencies>
1962 </autotools>
1963 <autotools id="monkey-bubble">
1964 <branch/>
1965 <dependencies>
1966 <dep package="gstreamer-0-8"/>
1967 <dep package="gst-plugins-0-8"/>
1968 <dep package="libxml2"/>
1969 <dep package="gconf"/>
1970 <dep package="librsvg"/>
1971 <dep package="libgnomeui"/>
1972 </dependencies>
1973 </autotools>
1974 <autotools id="gnome-schedule">
1975 <branch/>
1976 <dependencies>
1977 <dep package="pygtk"/>
1978 <dep package="yelp"/>
1979 </dependencies>
1980 </autotools>
1981 <autotools id="gnome-backgrounds">
1982 <branch/>
1983 <dependencies>
1984 <dep package="glib"/>
1985 </dependencies>
1986 </autotools>
1987 <autotools id="evince">
1988 <branch/>
1989 <dependencies>
1990 <dep package="libgnomeui"/>
1991 <dep package="libgnomeprintui"/>
1992 <dep package="poppler"/>
1993 <dep package="gnome-doc-utils"/>
1994 </dependencies>
1995 </autotools>
1996 <autotools id="nautilus-python" supports-non-srcdir-builds="no">
1997 <branch/>
1998 <dependencies>
1999 <dep package="nautilus"/>
2000 <dep package="pygtk"/>
2001 <dep package="gnome-python"/>
2002 </dependencies>
2003 </autotools>
2004 <autotools id="inkscape">
2005 <branch repo="inkscape.sf.net"/>
2006 <dependencies>
2007 <dep package="gtkmm"/>
2008 <dep package="libxslt"/>
2009 </dependencies>
2010 </autotools>
2011 <autotools id="NetworkManager">
2012 <branch repo="gnome.org"/>
2013 <dependencies>
2014 <dep package="dbus"/>
2015 </dependencies>
2016 </autotools>
2017 <autotools id="atomix">
2018 <branch/>
2019 <dependencies>
2020 <dep package="gtk+"/>
2021 <dep package="libgnome"/>
2022 <dep package="libgnomeui"/>
2023 <dep package="libxml2"/>
2024 <dep package="libgnomecanvas"/>
2025 <dep package="libbonoboui"/>
2026 </dependencies>
2027 </autotools>
2028 <autotools id="deskbar-applet">
2029 <branch/>
2030 <dependencies>
2031 <dep package="gtk+"/>
2032 <dep package="gnome-desktop"/>
2033 <dep package="pygtk"/>
2034 <dep package="gnome-python"/>
2035 <dep package="gnome-python-desktop"/>
2036 </dependencies>
2037 </autotools>
2038 <autotools id="pessulus">
2039 <branch/>
2040 <dependencies>
2041 <dep package="pygtk"/>
2042 <dep package="gnome-python"/>
2043 </dependencies>
2044 </autotools>
2045 <autotools id="sabayon">
2046 <branch/>
2047 <dependencies>
2048 <dep package="gtk+"/>
2049 <dep package="pygtk"/>
2050 </dependencies>
2051 </autotools>
2052 <autotools id="muine">
2053 <branch/>
2054 <dependencies>
2055 <dep package="gtk+"/>
2056 <dep package="gstreamer"/>
2057 </dependencies>
2058 </autotools>
2059 <autotools id="gnonlin">
2060 <branch repo="gstreamer.freedesktop.org" module="gnonlin"/>
2061 <dependencies>
2062 <dep package="gstreamer"/>
2063 <dep package="gst-plugins-base"/>
2064 </dependencies>
2065 </autotools>
2066 <autotools id="pitivi">
2067 <branch/>
2068 <dependencies>
2069 <dep package="pygtk"/>
2070 <dep package="gnome-python"/>
2071 <dep package="gstreamer"/>
2072 <dep package="gst-python"/>
2073 <dep package="gnonlin"/>
2074 </dependencies>
2075 </autotools>
2076 <autotools id="xchat-gnome">
2077 <branch repo="svn.navi.cx" module="misc/trunk/xchat-gnome"/>
2078 <dependencies>
2079 <dep package="gtk+" />
2080 <dep package="gconf" />
2081 <dep package="libgnomeui" />
2082 <dep package="libglade" />
2083 <dep package="gnome-vfs" />
2084 <dep package="libsexy" />
2085 </dependencies>
2086 </autotools>
2087</moduleset>
diff --git a/scripts/jhbuild/modulesets/gnutls.modules b/scripts/jhbuild/modulesets/gnutls.modules
new file mode 100644
index 0000000000..e8f75cfe86
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gnutls.modules
@@ -0,0 +1,36 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
2<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
3<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
4<moduleset>
5 <tarball id="libgpg-error" version="1.3">
6 <source href="http://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.3.tar.bz2"
7 size="452266" md5sum="d978065d62cde48e79497b63f80ba8fc" />
8 </tarball>
9 <tarball id="libgcrypt" version="1.2.2">
10 <source href="http://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.2.2.tar.bz2"
11 size="780315" md5sum="4a8a9a7572892ae3803a5aa558e52e02" />
12 <dependencies>
13 <dep package="libgpg-error" />
14 </dependencies>
15 </tarball>
16 <tarball id="libtasn1" version="0.3.4" supports-non-srcdir-builds="no">
17 <source href="http://ftp.gnupg.org/gcrypt/alpha/gnutls/libtasn1/libtasn1-0.3.4.tar.gz"
18 size="1246545" md5sum="1dbfce0e1fbd6aebc1a4506814c23d35" />
19 </tarball>
20 <tarball id="opencdk" version="0.5.8" supports-non-srcdir-builds="no">
21 <source href="http://ftp.gnupg.org/gcrypt/alpha/gnutls/opencdk/opencdk-0.5.8.tar.gz"
22 size="497122" md5sum="900c4dee7712845c19d7b2d2a93ea546" />
23 <dependencies>
24 <dep package="libgcrypt" />
25 </dependencies>
26 </tarball>
27 <tarball id="gnutls" version="1.4.0">
28 <source href="http://ftp.gnupg.org/gcrypt/alpha/gnutls/gnutls-1.4.0.tar.bz2"
29 size="3281324" md5sum="9e1e1b07e971c604923ec394f6922301" />
30 <dependencies>
31 <dep package="libgcrypt" />
32 <dep package="libtasn1" />
33 <dep package="opencdk" />
34 </dependencies>
35 </tarball>
36</moduleset>
diff --git a/scripts/jhbuild/modulesets/gtk.modules b/scripts/jhbuild/modulesets/gtk.modules
new file mode 100644
index 0000000000..a26a44c2ac
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gtk.modules
@@ -0,0 +1,72 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="gnome.org" default="yes"
5 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
6 password=""/>
7 <repository type="cvs" name="mime.freedesktop.org"
8 cvsroot=":pserver:anoncvs@cvs.freedesktop.org:/cvs/mime"
9 password=""/>
10
11 <include href="freedesktop.modules"/>
12
13 <autotools id="gnome-common">
14 <branch/>
15 </autotools>
16 <autotools id="intltool">
17 <branch/>
18 <dependencies>
19 <dep package="gnome-common"/>
20 </dependencies>
21 </autotools>
22 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
23 <branch repo="mime.freedesktop.org"/>
24 <dependencies>
25 <dep package="intltool"/>
26 </dependencies>
27 </autotools>
28 <autotools id="libxml2">
29 <branch module="gnome-xml" checkoutdir="libxml2"/>
30 </autotools>
31 <autotools id="libxslt">
32 <branch/>
33 <dependencies>
34 <dep package="libxml2"/>
35 </dependencies>
36 </autotools>
37 <autotools id="gtk-doc">
38 <branch/>
39 <dependencies>
40 <dep package="libxslt"/>
41 </dependencies>
42 </autotools>
43 <autotools id="glib">
44 <branch/>
45 <dependencies>
46 <dep package="gtk-doc"/>
47 </dependencies>
48 </autotools>
49 <autotools id="pango">
50 <branch/>
51 <dependencies>
52 <dep package="glib"/>
53 <dep package="cairo"/>
54 <dep package="libXft"/>
55 </dependencies>
56 </autotools>
57 <autotools id="atk">
58 <branch/>
59 <dependencies>
60 <dep package="glib"/>
61 </dependencies>
62 </autotools>
63 <autotools id="gtk+">
64 <branch/>
65 <dependencies>
66 <dep package="cairo"/>
67 <dep package="atk"/>
68 <dep package="pango"/>
69 <dep package="shared-mime-info"/>
70 </dependencies>
71 </autotools>
72</moduleset>
diff --git a/scripts/jhbuild/modulesets/gtk28.modules b/scripts/jhbuild/modulesets/gtk28.modules
new file mode 100644
index 0000000000..5fe56ea926
--- /dev/null
+++ b/scripts/jhbuild/modulesets/gtk28.modules
@@ -0,0 +1,72 @@
1<?xml version="1.0"?><!--*- mode: nxml -*-->
2<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
3<moduleset>
4 <repository type="cvs" name="gnome.org" default="yes"
5 cvsroot=":pserver:anonymous@anoncvs.gnome.org:/cvs/gnome"
6 password=""/>
7 <repository type="cvs" name="mime.freedesktop.org"
8 cvsroot=":pserver:anoncvs@cvs.freedesktop.org:/cvs/mime"
9 password=""/>
10
11 <include href="freedesktop.modules"/>
12
13 <autotools id="gnome-common">
14 <branch/>
15 </autotools>
16 <autotools id="intltool">
17 <branch/>
18 <dependencies>
19 <dep package="gnome-common"/>
20 </dependencies>
21 </autotools>
22 <autotools id="shared-mime-info" supports-non-srcdir-builds="no">
23 <branch repo="mime.freedesktop.org"/>
24 <dependencies>
25 <dep package="intltool"/>
26 </dependencies>
27 </autotools>
28 <autotools id="libxml2">
29 <branch module="gnome-xml" checkoutdir="libxml2"/>
30 </autotools>
31 <autotools id="libxslt">
32 <branch/>
33 <dependencies>
34 <dep package="libxml2"/>
35 </dependencies>
36 </autotools>
37 <autotools id="gtk-doc">
38 <branch/>
39 <dependencies>
40 <dep package="libxslt"/>
41 </dependencies>
42 </autotools>
43 <autotools id="glib">
44 <branch revision="glib-2-8"/>
45 <dependencies>
46 <dep package="gtk-doc"/>
47 </dependencies>
48 </autotools>
49 <autotools id="pango">
50 <branch revision="pango-1-10"/>
51 <dependencies>
52 <dep package="glib"/>
53 <dep package="cairo"/>
54 <dep package="libXft"/>
55 </dependencies>
56 </autotools>
57 <autotools id="atk">
58 <branch/>
59 <dependencies>
60 <dep package="glib"/>
61 </dependencies>
62 </autotools>
63 <autotools id="gtk+">
64 <branch revision="gtk-2-8"/>
65 <dependencies>
66 <dep package="cairo"/>
67 <dep package="atk"/>
68 <dep package="pango"/>
69 <dep package="shared-mime-info"/>
70 </dependencies>
71 </autotools>
72</moduleset>
diff --git a/scripts/jhbuild/modulesets/moduleset.dtd b/scripts/jhbuild/modulesets/moduleset.dtd
new file mode 100644
index 0000000000..bee7c8c17e
--- /dev/null
+++ b/scripts/jhbuild/modulesets/moduleset.dtd
@@ -0,0 +1,115 @@
1<!ELEMENT moduleset ((cvsroot|svnroot|arch-archive|darcs-archive)*,
2 (include|cvsmodule|svnmodule|archmodule|darcsmodule|
3 metamodule|tarball|mozillamodule)*) >
4
5<!ELEMENT cvsroot EMPTY >
6<!ATTLIST cvsroot
7 name CDATA #REQUIRED
8 root CDATA #REQUIRED
9 password CDATA #IMPLIED
10 default (yes|no) 'no' >
11
12<!ELEMENT svnroot EMPTY >
13<!ATTLIST svnroot
14 name CDATA #REQUIRED
15 href CDATA #REQUIRED
16 default (yes|no) 'no' >
17
18<!ELEMENT arch-archive EMPTY >
19<!ATTLIST arch-archive
20 name CDATA #REQUIRED
21 href CDATA #REQUIRED
22 default (yes|no) 'no' >
23
24<!ELEMENT darcs-archive EMPTY >
25<!ATTLIST darcs-archive
26 name CDATA #REQUIRED
27 href CDATA #REQUIRED
28 default (yes|no) 'no' >
29
30<!ELEMENT include EMPTY >
31<!ATTLIST include
32 href CDATA #REQUIRED >
33
34<!ELEMENT cvsmodule (dependencies?,suggests?) >
35<!ATTLIST cvsmodule
36 id CDATA #REQUIRED
37 module CDATA #IMPLIED
38 revision CDATA #IMPLIED
39 checkoutdir CDATA #IMPLIED
40 autogenargs CDATA #IMPLIED
41 makeargs CDATA #IMPLIED
42 cvsroot CDATA #IMPLIED
43 supports-non-srcdir-builds (yes|no) 'yes' >
44
45<!ELEMENT svnmodule (dependencies?,suggests?) >
46<!ATTLIST svnmodule
47 id CDATA #REQUIRED
48 module CDATA #IMPLIED
49 checkoutdir CDATA #IMPLIED
50 autogenargs CDATA #IMPLIED
51 makeargs CDATA #IMPLIED
52 root CDATA #IMPLIED
53 supports-non-srcdir-builds (yes|no) 'yes' >
54
55<!ELEMENT archmodule (dependencies?,suggests?) >
56<!ATTLIST archmodule
57 id CDATA #REQUIRED
58 version CDATA #IMPLIED
59 checkoutdir CDATA #IMPLIED
60 autogenargs CDATA #IMPLIED
61 makeargs CDATA #IMPLIED
62 root CDATA #IMPLIED
63 supports-non-srcdir-builds (yes|no) 'yes' >
64
65<!ELEMENT darcsmodule (dependencies?,suggests?) >
66<!ATTLIST darcsmodule
67 id CDATA #REQUIRED
68 checkoutdir CDATA #IMPLIED
69 autogenargs CDATA #IMPLIED
70 makeargs CDATA #IMPLIED
71 root CDATA #IMPLIED
72 supports-non-srcdir-builds (yes|no) 'yes' >
73
74<!ELEMENT metamodule (dependencies) >
75<!ATTLIST metamodule
76 id CDATA #REQUIRED >
77
78<!ELEMENT tarball
79 (source,patches?,dependencies?,suggests?) >
80<!ATTLIST tarball
81 id CDATA #REQUIRED
82 version CDATA #REQUIRED
83 checkoutdir CDATA #IMPLIED
84 autogenargs CDATA #IMPLIED
85 makeargs CDATA #IMPLIED
86 supports-non-srcdir-builds (yes|no) 'yes' >
87
88<!ELEMENT mozillamodule (dependencies?,suggests?) >
89<!ATTLIST mozillamodule
90 id CDATA #REQUIRED
91 module CDATA #IMPLIED
92 revision CDATA #IMPLIED
93 checkoutdir CDATA #IMPLIED
94 autogenargs CDATA #IMPLIED
95 makeargs CDATA #IMPLIED
96 cvsroot CDATA #IMPLIED >
97
98<!-- Tarball sub-elements -->
99<!ELEMENT source EMPTY >
100<!ATTLIST source
101 href CDATA #REQUIRED
102 size CDATA #IMPLIED
103 md5sum CDATA #IMPLIED >
104<!ELEMENT patches (patch)* >
105<!ELEMENT patch EMPTY >
106<!ATTLIST patch
107 file CDATA #REQUIRED
108 strip CDATA '0' >
109
110<!-- common sub-elements -->
111<!ELEMENT dependencies (dep*) >
112<!ELEMENT suggests (dep*) >
113<!ELEMENT dep EMPTY >
114<!ATTLIST dep
115 package CDATA #REQUIRED >
diff --git a/scripts/jhbuild/modulesets/moduleset.rnc b/scripts/jhbuild/modulesets/moduleset.rnc
new file mode 100644
index 0000000000..b46122101d
--- /dev/null
+++ b/scripts/jhbuild/modulesets/moduleset.rnc
@@ -0,0 +1,131 @@
1default namespace = ""
2
3start = moduleset
4
5boolean = "yes" | "no"
6
7moduleset = element moduleset { repository*,
8 (\include|package)* }
9
10repository_cvs = attribute type { "cvs" },
11 attribute cvsroot { text },
12 attribute password { text }?
13repository_svn = attribute type { "svn" },
14 attribute href { xsd:anyURI }
15repository_arch = attribute type { "arch" },
16 attribute archive { text },
17 attribute href { xsd:anyURI }?
18repository_darcs = attribute type { "darcs" },
19 attribute href { xsd:anyURI }
20repository_git = attribute type { "git" },
21 attribute href { xsd:anyURI }
22repository_tarball = attribute type { "tarball" },
23 attribute href { xsd:anyURI }
24
25repository = element repository {
26 attribute name { text },
27 attribute default { boolean }?,
28 (repository_cvs|repository_svn|repository_arch|
29 repository_darcs|repository_git|repository_tarball)
30}
31
32\include = element include {
33 attribute href { xsd:anyURI }
34}
35
36package = autotools |
37 metamodule |
38 distutils |
39 perl |
40 tarball |
41 mozillamodule
42
43dep = element dep {
44 attribute package { text }
45}
46dependencies = element dependencies { dep* }
47after = element after { dep* } | element suggests { dep* }
48
49common = attribute id { text } & dependencies* & after*
50
51branch_cvs = attribute module { text }?,
52 attribute checkoutdir { text }?,
53 attribute revision { text}?,
54 attribute override-checkoutdir { boolean }?,
55 attribute update-new-dirs { boolean }?
56branch_svn = attribute module { xsd:anyURI }?,
57 attribute checkoutdir { text }?
58branch_arch = attribute module { xsd:anyURI }?,
59 attribute checkoutdir { text }?
60branch_darcs = attribute module { xsd:anyURI }?,
61 attribute checkoutdir { text }?
62branch_git = attribute module { xsd:anyURI }?,
63 attribute checkoutdir { text }?
64branch_tarball = attribute module { xsd:anyURI },
65 attribute version { text },
66 attribute size { text }?,
67 attribute md5sum { text }?,
68 element patch {
69 attribute file { text },
70 attribute strip { text }?
71 }*
72
73
74branch = element branch {
75 attribute repo { text }?,
76 (branch_cvs|branch_svn|branch_arch|branch_darcs|branch_git|branch_tarball)
77}
78
79autotools = element autotools {
80 branch &
81 attribute autogen-sh { text }? &
82 attribute autogenargs { text }? &
83 attribute makeargs { text }? &
84 attribute supports-non-srcdir-builds { boolean }? &
85 common
86}
87
88metamodule = element metamodule { common }
89
90distutils = element distutils {
91 branch &
92 attribute supports-non-srcdir-builds { boolean }? &
93 common
94}
95
96perl = element perl {
97 branch &
98 attribute makeargs { text }? &
99 common
100}
101
102tarball = element tarball {
103 attribute version { text },
104 attribute checkoutdir { text }?,
105 attribute autogenargs { text }?,
106 attribute makeargs { text }?,
107 attribute supports-non-srcdir-builds { boolean }?,
108
109 (element source {
110 attribute href { text },
111 attribute size { text }?,
112 attribute md5sum { text }? } &
113 element patches {
114 element patch {
115 attribute file { text },
116 attribute strip { text }?
117 }+ }? &
118 common)
119}
120
121mozillamodule = element mozillamodule {
122 attribute module { text }?,
123 attribute revision { text }?,
124 attribute checkoutdir { text }?,
125 attribute autogenargs { text }?,
126 attribute makeargs { text }?,
127 attribute cvsroot { text }?,
128 attribute root { text }?,
129 common
130}
131
diff --git a/scripts/jhbuild/modulesets/moduleset.xsl b/scripts/jhbuild/modulesets/moduleset.xsl
new file mode 100644
index 0000000000..a057bfa692
--- /dev/null
+++ b/scripts/jhbuild/modulesets/moduleset.xsl
@@ -0,0 +1,283 @@
1<?xml version='1.0'?> <!--*- mode: nxml -*-->
2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3 version="1.0">
4
5 <xsl:output method="html" encoding="ISO-8859-1" indent="yes" />
6 <xsl:key name="module-id" match="moduleset/*" use="@id" />
7
8 <xsl:template match="/">
9 <html>
10 <head>
11 <title>Module Set</title>
12 <style type="text/css">
13 <xsl:text>
14 div.cvsmodule, div.mozillamodule {
15 padding: 0.5em;
16 margin: 0.5em;
17 background: #87CEFA;
18 }
19 div.svnmodule {
20 padding: 0.5em;
21 margin: 0.5em;
22 background: #67AEDA;
23 }
24 div.metamodule {
25 padding: 0.5em;
26 margin: 0.5em;
27 background: #F08080;
28 }
29 div.tarball {
30 padding: 0.5em;
31 margin: 0.5em;
32 background: #EEDD82;
33 }
34 </xsl:text>
35 </style>
36 </head>
37 <body>
38 <xsl:apply-templates />
39 </body>
40 </html>
41 </xsl:template>
42
43 <xsl:template match="moduleset">
44 <h1>Module Set</h1>
45 <xsl:apply-templates />
46 </xsl:template>
47
48 <xsl:template match="dependencies">
49 <xsl:variable name="deps" select="dep/@package" />
50 <xsl:for-each select="$deps">
51 <a href="#{generate-id(key('module-id', .))}">
52 <xsl:value-of select="." />
53 </a>
54 <xsl:if test="not($deps[last()] = .)">
55 <xsl:text>, </xsl:text>
56 </xsl:if>
57 </xsl:for-each>
58 </xsl:template>
59
60 <xsl:template match="cvsmodule">
61 <div class="{name(.)}">
62 <h2>
63 <xsl:value-of select="@id" />
64 <a name="{generate-id(.)}" />
65 </h2>
66 <table>
67 <tr>
68 <th align="left">Module:</th>
69 <td>
70 <xsl:choose>
71 <xsl:when test="@module">
72 <xsl:value-of select="@module" />
73 </xsl:when>
74 <xsl:otherwise>
75 <xsl:value-of select="@id" />
76 </xsl:otherwise>
77 </xsl:choose>
78 <xsl:if test="@revision">
79 <xsl:text> rv:</xsl:text>
80 <xsl:value-of select="@revision" />
81 </xsl:if>
82 </td>
83 </tr>
84 <xsl:if test="@checkoutdir">
85 <tr>
86 <th align="left">Checkout directory:</th>
87 <td><xsl:value-of select="@checkoutdir" /></td>
88 </tr>
89 </xsl:if>
90 <xsl:if test="@autogenargs">
91 <tr>
92 <th align="left">Autogen args:</th>
93 <td><xsl:value-of select="@autogenargs" /></td>
94 </tr>
95 </xsl:if>
96 <xsl:if test="@cvsroot">
97 <tr>
98 <th align="left">CVS Root:</th>
99 <td><xsl:value-of select="@cvsroot" /></td>
100 </tr>
101 </xsl:if>
102 <xsl:if test="dependencies">
103 <tr>
104 <th align="left" valign="top">Dependencies:</th>
105 <td><xsl:apply-templates select="dependencies" /></td>
106 </tr>
107 </xsl:if>
108 </table>
109 </div>
110 </xsl:template>
111
112 <xsl:template match="svnmodule">
113 <div class="{name(.)}">
114 <h2>
115 <xsl:value-of select="@id" />
116 <a name="{generate-id(.)}" />
117 </h2>
118 <table>
119 <tr>
120 <th align="left">Module:</th>
121 <td>
122 <xsl:choose>
123 <xsl:when test="@module">
124 <xsl:value-of select="@module" />
125 </xsl:when>
126 <xsl:otherwise>
127 <xsl:value-of select="@id" />
128 </xsl:otherwise>
129 </xsl:choose>
130 </td>
131 </tr>
132 <xsl:if test="@checkoutdir">
133 <tr>
134 <th align="left">Checkout directory:</th>
135 <td><xsl:value-of select="@checkoutdir" /></td>
136 </tr>
137 </xsl:if>
138 <xsl:if test="@autogenargs">
139 <tr>
140 <th align="left">Autogen args:</th>
141 <td><xsl:value-of select="@autogenargs" /></td>
142 </tr>
143 </xsl:if>
144 <xsl:if test="@svnroot">
145 <tr>
146 <th align="left">SVN Repository:</th>
147 <td><xsl:value-of select="@svnroot" /><xsl:if test="@path"><xsl:value-of select="@path" /></xsl:if></td>
148 </tr>
149 </xsl:if>
150 <xsl:if test="dependencies">
151 <tr>
152 <th align="left" valign="top">Dependencies:</th>
153 <td><xsl:apply-templates select="dependencies" /></td>
154 </tr>
155 </xsl:if>
156 </table>
157 </div>
158 </xsl:template>
159
160 <xsl:template match="metamodule">
161 <div class="{name(.)}">
162 <h2>
163 <xsl:value-of select="@id" />
164 <a name="{generate-id(.)}" />
165 </h2>
166 <table>
167 <xsl:if test="dependencies">
168 <tr>
169 <th align="left" valign="top">Dependencies:</th>
170 <td><xsl:apply-templates select="dependencies" /></td>
171 </tr>
172 </xsl:if>
173 </table>
174 </div>
175 </xsl:template>
176
177 <xsl:template match="patches">
178 <ul>
179 <xsl:for-each select="patch">
180 <li><xsl:value-of select="." /></li>
181 </xsl:for-each>
182 </ul>
183 </xsl:template>
184
185 <xsl:template match="tarball">
186 <div class="{name(.)}">
187 <h2>
188 <xsl:value-of select="@id" />
189 <a name="{generate-id(.)}" />
190 </h2>
191 <table>
192 <tr>
193 <th align="left">Version:</th>
194 <td><xsl:value-of select="@version" /></td>
195 </tr>
196 <xsl:if test="@versioncheck">
197 <tr>
198 <th align="left">Version check:</th>
199 <td><xsl:value-of select="@versioncheck" /></td>
200 </tr>
201 </xsl:if>
202 <tr>
203 <th align="left">Source:</th>
204 <td>
205 <a href="{source/@href}">
206 <xsl:value-of select="source/@href" />
207 </a>
208 <xsl:if test="source/@size">
209 <xsl:text> (</xsl:text>
210 <xsl:value-of select="source/@size" />
211 <xsl:text> bytes)</xsl:text>
212 </xsl:if>
213 </td>
214 </tr>
215 <xsl:if test="patches">
216 <tr>
217 <th align="left" valign="top">Patches:</th>
218 <td><xsl:apply-templates select="patches" /></td>
219 </tr>
220 </xsl:if>
221 <xsl:if test="dependencies">
222 <tr>
223 <th align="left" valign="top">Dependencies:</th>
224 <td><xsl:apply-templates select="dependencies" /></td>
225 </tr>
226 </xsl:if>
227 </table>
228 </div>
229 </xsl:template>
230
231 <xsl:template match="mozillamodule">
232 <div class="{name(.)}">
233 <h2>
234 <xsl:value-of select="@id" />
235 <a name="{generate-id(.)}" />
236 </h2>
237 <table>
238 <tr>
239 <th align="left">Module:</th>
240 <td>
241 <xsl:choose>
242 <xsl:when test="@module">
243 <xsl:value-of select="@module" />
244 </xsl:when>
245 <xsl:otherwise>
246 <xsl:value-of select="@id" />
247 </xsl:otherwise>
248 </xsl:choose>
249 <xsl:if test="@revision">
250 <xsl:text> rv:</xsl:text>
251 <xsl:value-of select="@revision" />
252 </xsl:if>
253 </td>
254 </tr>
255 <xsl:if test="@checkoutdir">
256 <tr>
257 <th align="left">Checkout directory:</th>
258 <td><xsl:value-of select="@checkoutdir" /></td>
259 </tr>
260 </xsl:if>
261 <xsl:if test="@autogenargs">
262 <tr>
263 <th align="left">Autogen args:</th>
264 <td><xsl:value-of select="@autogenargs" /></td>
265 </tr>
266 </xsl:if>
267 <xsl:if test="@cvsroot">
268 <tr>
269 <th align="left">CVS Root:</th>
270 <td><xsl:value-of select="@cvsroot" /></td>
271 </tr>
272 </xsl:if>
273 <xsl:if test="dependencies">
274 <tr>
275 <th align="left" valign="top">Dependencies:</th>
276 <td><xsl:apply-templates select="dependencies" /></td>
277 </tr>
278 </xsl:if>
279 </table>
280 </div>
281 </xsl:template>
282
283</xsl:stylesheet>
diff --git a/scripts/jhbuild/modulesets/schemas.xml b/scripts/jhbuild/modulesets/schemas.xml
new file mode 100644
index 0000000000..94675e4da6
--- /dev/null
+++ b/scripts/jhbuild/modulesets/schemas.xml
@@ -0,0 +1,4 @@
1<?xml version="1.0"?>
2<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
3 <documentElement localName="moduleset" uri="moduleset.rnc" />
4</locatingRules>
diff --git a/scripts/jhbuild/modulesets/xorg-7.0.modules b/scripts/jhbuild/modulesets/xorg-7.0.modules
new file mode 100644
index 0000000000..72e7328ab6
--- /dev/null
+++ b/scripts/jhbuild/modulesets/xorg-7.0.modules
@@ -0,0 +1,4847 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
2
3<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
4<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
5<moduleset>
6
7 <!--
8 Note that all of the dependencies below are in metamodules. The
9 reason for using this scheme is because the list of tarballs can
10 be automatically generated whereas the dependency information
11 currently cannot.
12
13 The dependencies work as follows: Each tarball depends on a
14 metamodule with the same name (see below for the metamodule and
15 tarball id naming scheme used), and each metamodule can have
16 dependencies on other tarballs.
17
18 Each metamodule id is "<module name>-<tarballname>".
19 Each tarball id is "<module name>/<tarballname>"
20
21 For example, if you need to add a new dependency on
22 lib/foo-1.2.3.tar.bz2 to app/bar-4.5.6.tar.bz2, then you would
23 add a <dep package="lib/foo"/> to <metamodule id="app-bar">.
24 -->
25
26 <!-- util -->
27
28 <metamodule id="util-util-macros"/>
29
30 <metamodule id="util-xorg-cf-files">
31 <dependencies>
32 <dep package="util/util-macros"/>
33 </dependencies>
34 </metamodule>
35
36 <metamodule id="util-makedepend">
37 <dependencies>
38 <dep package="util/util-macros"/>
39 </dependencies>
40 </metamodule>
41
42 <metamodule id="util-imake">
43 <dependencies>
44 <dep package="util/util-macros"/>
45 <dep package="util/xorg-cf-files"/>
46 <dep package="proto/xproto"/>
47 </dependencies>
48 </metamodule>
49
50 <metamodule id="util-gccmakedep">
51 <dependencies>
52 <dep package="util/util-macros"/>
53 </dependencies>
54 </metamodule>
55
56 <metamodule id="util-lndir">
57 <dependencies>
58 <dep package="util/util-macros"/>
59 <dep package="proto/xproto"/>
60 </dependencies>
61 </metamodule>
62
63 <metamodule id="util">
64 <dependencies>
65 <dep package="util/util-macros"/>
66 <dep package="util/xorg-cf-files"/>
67 <dep package="util/imake"/>
68 <dep package="util/makedepend"/>
69 <dep package="util/gccmakedep"/>
70 <dep package="util/lndir"/>
71 </dependencies>
72 </metamodule>
73
74
75 <!-- doc -->
76
77 <metamodule id="doc-xorg-sgml-doctools">
78 <dependencies>
79 <dep package="util/util-macros"/>
80 </dependencies>
81 </metamodule>
82
83 <metamodule id="doc-xorg-docs">
84 <dependencies>
85 <dep package="util/util-macros"/>
86 <dep package="doc/xorg-sgml-doctools"/>
87 </dependencies>
88 </metamodule>
89
90 <metamodule id="doc">
91 <dependencies>
92 <dep package="doc/xorg-sgml-doctools"/>
93 <dep package="doc/xorg-docs"/>
94 </dependencies>
95 </metamodule>
96
97
98 <!-- proto -->
99
100 <metamodule id="proto-applewmproto">
101 <dependencies>
102 <dep package="util/util-macros"/>
103 </dependencies>
104 </metamodule>
105
106 <metamodule id="proto-bigreqsproto">
107 <dependencies>
108 <dep package="util/util-macros"/>
109 </dependencies>
110 </metamodule>
111
112 <metamodule id="proto-compositeproto">
113 <dependencies>
114 <dep package="util/util-macros"/>
115 </dependencies>
116 </metamodule>
117
118 <metamodule id="proto-damageproto">
119 <dependencies>
120 <dep package="util/util-macros"/>
121 </dependencies>
122 </metamodule>
123
124 <metamodule id="proto-dmxproto">
125 <dependencies>
126 <dep package="util/util-macros"/>
127 </dependencies>
128 </metamodule>
129
130 <metamodule id="proto-evieext">
131 <dependencies>
132 <dep package="util/util-macros"/>
133 </dependencies>
134 </metamodule>
135
136 <metamodule id="proto-fixesproto">
137 <dependencies>
138 <dep package="util/util-macros"/>
139 </dependencies>
140 </metamodule>
141
142 <metamodule id="proto-fontcacheproto">
143 <dependencies>
144 <dep package="util/util-macros"/>
145 </dependencies>
146 </metamodule>
147
148 <metamodule id="proto-fontsproto">
149 <dependencies>
150 <dep package="util/util-macros"/>
151 </dependencies>
152 </metamodule>
153
154 <metamodule id="proto-glproto">
155 <dependencies>
156 <dep package="util/util-macros"/>
157 </dependencies>
158 </metamodule>
159
160 <metamodule id="proto-inputproto">
161 <dependencies>
162 <dep package="util/util-macros"/>
163 </dependencies>
164 </metamodule>
165
166 <metamodule id="proto-kbproto">
167 <dependencies>
168 <dep package="util/util-macros"/>
169 </dependencies>
170 </metamodule>
171
172 <metamodule id="proto-printproto">
173 <dependencies>
174 <dep package="util/util-macros"/>
175 </dependencies>
176 </metamodule>
177
178 <metamodule id="proto-xproxymanagementprotocol">
179 <dependencies>
180 <dep package="util/util-macros"/>
181 </dependencies>
182 </metamodule>
183
184 <metamodule id="proto-randrproto">
185 <dependencies>
186 <dep package="util/util-macros"/>
187 </dependencies>
188 </metamodule>
189
190 <metamodule id="proto-recordproto">
191 <dependencies>
192 <dep package="util/util-macros"/>
193 </dependencies>
194 </metamodule>
195
196 <metamodule id="proto-renderproto">
197 <dependencies>
198 <dep package="util/util-macros"/>
199 </dependencies>
200 </metamodule>
201
202 <metamodule id="proto-resourceproto">
203 <dependencies>
204 <dep package="util/util-macros"/>
205 </dependencies>
206 </metamodule>
207
208 <metamodule id="proto-scrnsaverproto">
209 <dependencies>
210 <dep package="util/util-macros"/>
211 </dependencies>
212 </metamodule>
213
214 <metamodule id="proto-trapproto">
215 <dependencies>
216 <dep package="util/util-macros"/>
217 </dependencies>
218 </metamodule>
219
220 <metamodule id="proto-videoproto">
221 <dependencies>
222 <dep package="util/util-macros"/>
223 </dependencies>
224 </metamodule>
225
226 <metamodule id="proto-windowswmproto">
227 <dependencies>
228 <dep package="util/util-macros"/>
229 </dependencies>
230 </metamodule>
231
232 <metamodule id="proto-xcmiscproto">
233 <dependencies>
234 <dep package="util/util-macros"/>
235 </dependencies>
236 </metamodule>
237
238 <metamodule id="proto-xextproto">
239 <dependencies>
240 <dep package="util/util-macros"/>
241 </dependencies>
242 </metamodule>
243
244 <metamodule id="proto-xf86bigfontproto">
245 <dependencies>
246 <dep package="util/util-macros"/>
247 </dependencies>
248 </metamodule>
249
250 <metamodule id="proto-xf86dgaproto">
251 <dependencies>
252 <dep package="util/util-macros"/>
253 </dependencies>
254 </metamodule>
255
256 <metamodule id="proto-xf86driproto">
257 <dependencies>
258 <dep package="util/util-macros"/>
259 </dependencies>
260 </metamodule>
261
262 <metamodule id="proto-xf86miscproto">
263 <dependencies>
264 <dep package="util/util-macros"/>
265 </dependencies>
266 </metamodule>
267
268 <metamodule id="proto-xf86rushproto">
269 <dependencies>
270 <dep package="util/util-macros"/>
271 </dependencies>
272 </metamodule>
273
274 <metamodule id="proto-xf86vidmodeproto">
275 <dependencies>
276 <dep package="util/util-macros"/>
277 </dependencies>
278 </metamodule>
279
280 <metamodule id="proto-xineramaproto">
281 <dependencies>
282 <dep package="util/util-macros"/>
283 </dependencies>
284 </metamodule>
285
286 <metamodule id="proto-xproto">
287 <dependencies>
288 <dep package="util/util-macros"/>
289 </dependencies>
290 </metamodule>
291
292 <metamodule id="proto">
293 <dependencies>
294 <!-- <dep package="proto/applewmproto"/> -->
295 <dep package="proto/bigreqsproto"/>
296 <dep package="proto/compositeproto"/>
297 <dep package="proto/damageproto"/>
298 <dep package="proto/dmxproto"/>
299 <dep package="proto/evieext"/>
300 <dep package="proto/fixesproto"/>
301 <dep package="proto/fontcacheproto"/>
302 <dep package="proto/fontsproto"/>
303 <dep package="proto/glproto"/>
304 <dep package="proto/inputproto"/>
305 <dep package="proto/kbproto"/>
306 <dep package="proto/printproto"/>
307 <dep package="proto/xproxymanagementprotocol"/>
308 <dep package="proto/randrproto"/>
309 <dep package="proto/recordproto"/>
310 <dep package="proto/renderproto"/>
311 <dep package="proto/resourceproto"/>
312 <dep package="proto/scrnsaverproto"/>
313 <dep package="proto/trapproto"/>
314 <dep package="proto/videoproto"/>
315 <!-- <dep package="proto/windowswmproto"/> -->
316 <dep package="proto/xcmiscproto"/>
317 <dep package="proto/xextproto"/>
318 <dep package="proto/xf86bigfontproto"/>
319 <dep package="proto/xf86dgaproto"/>
320 <dep package="proto/xf86driproto"/>
321 <dep package="proto/xf86miscproto"/>
322 <dep package="proto/xf86rushproto"/>
323 <dep package="proto/xf86vidmodeproto"/>
324 <dep package="proto/xineramaproto"/>
325 <dep package="proto/xproto"/>
326 </dependencies>
327 </metamodule>
328
329
330 <!-- lib -->
331
332 <metamodule id="lib-libdmx">
333 <dependencies>
334 <dep package="util/util-macros"/>
335 <dep package="lib/libX11"/>
336 <dep package="lib/libXext"/>
337 <dep package="proto/xextproto"/>
338 <dep package="proto/dmxproto"/>
339 </dependencies>
340 </metamodule>
341
342 <metamodule id="lib-libfontenc">
343 <dependencies>
344 <dep package="util/util-macros"/>
345 <dep package="proto/xproto"/>
346 </dependencies>
347 </metamodule>
348
349 <metamodule id="lib-libAppleWM">
350 <dependencies>
351 <dep package="util/util-macros"/>
352 <dep package="lib/libX11"/>
353 <dep package="lib/libXext"/>
354 </dependencies>
355 </metamodule>
356
357 <metamodule id="lib-libFS">
358 <dependencies>
359 <dep package="util/util-macros"/>
360 <dep package="proto/xproto"/>
361 <dep package="proto/fontsproto"/>
362 <dep package="lib/xtrans"/>
363 </dependencies>
364 </metamodule>
365
366 <metamodule id="lib-libICE">
367 <dependencies>
368 <dep package="util/util-macros"/>
369 <dep package="proto/xproto"/>
370 <dep package="lib/xtrans"/>
371 </dependencies>
372 </metamodule>
373
374 <metamodule id="lib-liblbxutil">
375 <dependencies>
376 <dep package="util/util-macros"/>
377 <dep package="proto/xextproto"/>
378 <dep package="proto/xproto"/>
379 </dependencies>
380 </metamodule>
381
382 <metamodule id="lib-liboldX">
383 <dependencies>
384 <dep package="util/util-macros"/>
385 <dep package="lib/libX11"/>
386 </dependencies>
387 </metamodule>
388
389 <metamodule id="lib-libSM">
390 <dependencies>
391 <dep package="util/util-macros"/>
392 <dep package="proto/xproto"/>
393 <dep package="lib/libICE"/>
394 <dep package="lib/xtrans"/>
395 </dependencies>
396 </metamodule>
397
398 <metamodule id="lib-libX11">
399 <dependencies>
400 <dep package="util/util-macros"/>
401 <dep package="proto/xproto"/>
402 <dep package="proto/bigreqsproto"/>
403 <dep package="proto/xextproto"/>
404 <dep package="lib/xtrans"/>
405 <dep package="lib/libXau"/>
406 <dep package="proto/xcmiscproto"/>
407 <dep package="proto/xf86bigfontproto"/>
408 <dep package="lib/libXdmcp"/>
409 <dep package="proto/kbproto"/>
410 <dep package="proto/inputproto"/>
411 </dependencies>
412 </metamodule>
413
414 <metamodule id="lib-libXau">
415 <dependencies>
416 <dep package="util/util-macros"/>
417 <dep package="proto/xproto"/>
418 </dependencies>
419 </metamodule>
420
421 <metamodule id="lib-libXaw">
422 <dependencies>
423 <dep package="util/util-macros"/>
424 <dep package="proto/xproto"/>
425 <dep package="lib/libX11"/>
426 <dep package="lib/libXt"/>
427 <dep package="lib/libXmu"/>
428 <dep package="lib/libXpm"/>
429 </dependencies>
430 <suggests>
431 <dep package="lib/libXp"/>
432 </suggests>
433 </metamodule>
434
435 <metamodule id="lib-libXcomposite">
436 <dependencies>
437 <dep package="util/util-macros"/>
438 <dep package="proto/compositeproto"/>
439 <dep package="lib/libX11"/>
440 <dep package="lib/libXfixes"/>
441 <dep package="lib/libXext"/>
442 <dep package="proto/fixesproto"/>
443 </dependencies>
444 </metamodule>
445
446 <metamodule id="lib-libXcursor">
447 <dependencies>
448 <dep package="util/util-macros"/>
449 <dep package="lib/libXrender"/>
450 <dep package="lib/libX11"/>
451 <dep package="lib/libXfixes"/>
452 <dep package="proto/fixesproto"/>
453 </dependencies>
454 </metamodule>
455
456 <metamodule id="lib-libXdamage">
457 <dependencies>
458 <dep package="util/util-macros"/>
459 <dep package="lib/libX11"/>
460 <dep package="proto/damageproto"/>
461 <dep package="lib/libXfixes"/>
462 <dep package="proto/fixesproto"/>
463 <dep package="proto/xextproto"/>
464 </dependencies>
465 </metamodule>
466
467 <metamodule id="lib-libXdmcp">
468 <dependencies>
469 <dep package="util/util-macros"/>
470 <dep package="proto/xproto"/>
471 </dependencies>
472 </metamodule>
473
474 <metamodule id="lib-libXevie">
475 <dependencies>
476 <dep package="util/util-macros"/>
477 <dep package="proto/xproto"/>
478 <dep package="lib/libX11"/>
479 <dep package="proto/xextproto"/>
480 <dep package="lib/libXext"/>
481 <dep package="proto/evieext"/>
482 </dependencies>
483 </metamodule>
484
485 <metamodule id="lib-libXext">
486 <dependencies>
487 <dep package="util/util-macros"/>
488 <dep package="proto/xproto"/>
489 <dep package="lib/libX11"/>
490 <dep package="proto/xextproto"/>
491 <dep package="lib/libXau"/>
492 </dependencies>
493 </metamodule>
494
495 <metamodule id="lib-libXfixes">
496 <dependencies>
497 <dep package="util/util-macros"/>
498 <dep package="lib/libX11"/>
499 <dep package="proto/xproto"/>
500 <dep package="proto/fixesproto"/>
501 <dep package="proto/xextproto"/>
502 </dependencies>
503 </metamodule>
504
505 <metamodule id="lib-libXfont">
506 <dependencies>
507 <dep package="util/util-macros"/>
508 <dep package="proto/xproto"/>
509 <dep package="lib/xtrans"/>
510 <dep package="proto/fontsproto"/>
511 <dep package="lib/libfontenc"/>
512 <dep package="proto/fontcacheproto"/>
513 </dependencies>
514 </metamodule>
515
516 <metamodule id="lib-libXfontcache">
517 <dependencies>
518 <dep package="util/util-macros"/>
519 <dep package="lib/libX11"/>
520 <dep package="lib/libXext"/>
521 <dep package="proto/xextproto"/>
522 <dep package="proto/fontcacheproto"/>
523 </dependencies>
524 </metamodule>
525
526 <metamodule id="lib-libXft">
527 <dependencies>
528 <dep package="util/util-macros"/>
529 <dep package="lib/libXrender"/>
530 <dep package="fontconfig"/>
531 </dependencies>
532 </metamodule>
533
534 <metamodule id="lib-libXi">
535 <dependencies>
536 <dep package="util/util-macros"/>
537 <dep package="proto/xproto"/>
538 <dep package="lib/libX11"/>
539 <dep package="proto/xextproto"/>
540 <dep package="lib/libXext"/>
541 <dep package="proto/inputproto"/>
542 </dependencies>
543 </metamodule>
544
545 <metamodule id="lib-libXinerama">
546 <dependencies>
547 <dep package="util/util-macros"/>
548 <dep package="lib/libX11"/>
549 <dep package="lib/libXext"/>
550 <dep package="proto/xextproto"/>
551 <dep package="proto/xineramaproto"/>
552 </dependencies>
553 </metamodule>
554
555 <metamodule id="lib-libxkbfile">
556 <dependencies>
557 <dep package="util/util-macros"/>
558 <dep package="lib/libX11"/>
559 <dep package="proto/kbproto"/>
560 </dependencies>
561 </metamodule>
562
563 <metamodule id="lib-libxkbui">
564 <dependencies>
565 <dep package="util/util-macros"/>
566 <dep package="lib/libX11"/>
567 <dep package="lib/libXt"/>
568 <dep package="lib/libxkbfile"/>
569 </dependencies>
570 </metamodule>
571
572 <metamodule id="lib-libXmu">
573 <dependencies>
574 <dep package="util/util-macros"/>
575 <dep package="lib/libX11"/>
576 <dep package="lib/libXt"/>
577 <dep package="lib/libXext"/>
578 </dependencies>
579 </metamodule>
580
581 <metamodule id="lib-libXp">
582 <dependencies>
583 <dep package="util/util-macros"/>
584 <dep package="lib/libX11"/>
585 <dep package="lib/libXext"/>
586 <dep package="lib/libXau"/>
587 <dep package="proto/printproto"/>
588 </dependencies>
589 </metamodule>
590
591 <metamodule id="lib-libXpm">
592 <dependencies>
593 <dep package="util/util-macros"/>
594 <dep package="lib/libX11"/>
595 <dep package="proto/xproto"/>
596 <dep package="lib/libXt"/>
597 <dep package="lib/libXext"/>
598 </dependencies>
599 </metamodule>
600
601 <metamodule id="lib-libXprintAppUtil">
602 <dependencies>
603 <dep package="util/util-macros"/>
604 <dep package="lib/libX11"/>
605 <dep package="lib/libXp"/>
606 <dep package="lib/libXprintUtil"/>
607 </dependencies>
608 </metamodule>
609
610 <metamodule id="lib-libXprintUtil">
611 <dependencies>
612 <dep package="util/util-macros"/>
613 <dep package="lib/libX11"/>
614 <dep package="lib/libXp"/>
615 </dependencies>
616 </metamodule>
617
618 <metamodule id="lib-libXrandr">
619 <dependencies>
620 <dep package="util/util-macros"/>
621 <dep package="lib/libX11"/>
622 <dep package="lib/libXext"/>
623 <dep package="lib/libXrender"/>
624 <dep package="proto/randrproto"/>
625 </dependencies>
626 </metamodule>
627
628 <metamodule id="lib-libXrender">
629 <dependencies>
630 <dep package="util/util-macros"/>
631 <dep package="proto/renderproto"/>
632 <dep package="lib/libX11"/>
633 </dependencies>
634 </metamodule>
635
636 <metamodule id="lib-libXres">
637 <dependencies>
638 <dep package="util/util-macros"/>
639 <dep package="lib/libX11"/>
640 <dep package="lib/libXext"/>
641 <dep package="proto/resourceproto"/>
642 </dependencies>
643 </metamodule>
644
645 <metamodule id="lib-libXScrnSaver">
646 <dependencies>
647 <dep package="util/util-macros"/>
648 <dep package="lib/libX11"/>
649 <dep package="lib/libXext"/>
650 <dep package="proto/xextproto"/>
651 <dep package="proto/scrnsaverproto"/>
652 </dependencies>
653 </metamodule>
654
655 <metamodule id="lib-libXt">
656 <dependencies>
657 <dep package="util/util-macros"/>
658 <dep package="lib/libSM"/>
659 <dep package="lib/libX11"/>
660 <dep package="proto/xproto"/>
661 <dep package="proto/kbproto"/>
662 </dependencies>
663 </metamodule>
664
665 <metamodule id="lib-libXTrap">
666 <dependencies>
667 <dep package="util/util-macros"/>
668 <dep package="lib/libX11"/>
669 <dep package="lib/libXt"/>
670 <dep package="proto/trapproto"/>
671 <dep package="lib/libXext"/>
672 <dep package="proto/xextproto"/>
673 </dependencies>
674 </metamodule>
675
676 <metamodule id="lib-libXtst">
677 <dependencies>
678 <dep package="util/util-macros"/>
679 <dep package="lib/libX11"/>
680 <dep package="lib/libXext"/>
681 <dep package="proto/recordproto"/>
682 <dep package="proto/xextproto"/>
683 <dep package="proto/inputproto"/>
684 </dependencies>
685 </metamodule>
686
687 <metamodule id="lib-libXv">
688 <dependencies>
689 <dep package="util/util-macros"/>
690 <dep package="lib/libX11"/>
691 <dep package="lib/libXext"/>
692 <dep package="proto/xextproto"/>
693 <dep package="proto/videoproto"/>
694 </dependencies>
695 </metamodule>
696
697 <metamodule id="lib-libXvMC">
698 <dependencies>
699 <dep package="util/util-macros"/>
700 <dep package="lib/libX11"/>
701 <dep package="lib/libXext"/>
702 <dep package="proto/xextproto"/>
703 <dep package="proto/videoproto"/>
704 </dependencies>
705 </metamodule>
706
707 <metamodule id="lib-libXxf86dga">
708 <dependencies>
709 <dep package="util/util-macros"/>
710 <dep package="proto/xproto"/>
711 <dep package="lib/libX11"/>
712 <dep package="lib/libXext"/>
713 <dep package="proto/xextproto"/>
714 <dep package="proto/xf86dgaproto"/>
715 </dependencies>
716 </metamodule>
717
718 <metamodule id="lib-libXxf86misc">
719 <dependencies>
720 <dep package="util/util-macros"/>
721 <dep package="proto/xproto"/>
722 <dep package="lib/libX11"/>
723 <dep package="lib/libXext"/>
724 <dep package="proto/xextproto"/>
725 <dep package="proto/xf86miscproto"/>
726 </dependencies>
727 </metamodule>
728
729 <metamodule id="lib-libXxf86vm">
730 <dependencies>
731 <dep package="util/util-macros"/>
732 <dep package="proto/xproto"/>
733 <dep package="lib/libX11"/>
734 <dep package="lib/libXext"/>
735 <dep package="proto/xextproto"/>
736 <dep package="proto/xf86vidmodeproto"/>
737 </dependencies>
738 </metamodule>
739
740 <metamodule id="lib-xtrans">
741 <dependencies>
742 <dep package="util/util-macros"/>
743 </dependencies>
744 </metamodule>
745
746 <metamodule id="lib">
747 <dependencies>
748 <!-- <dep package="lib/libAppleWM"/> -->
749 <dep package="lib/libdmx"/>
750 <dep package="lib/libfontenc"/>
751 <dep package="lib/libFS"/>
752 <dep package="lib/libICE"/>
753 <dep package="lib/liblbxutil"/>
754 <dep package="lib/liboldX"/>
755 <dep package="lib/libSM"/>
756 <!-- <dep package="lib/libWindowsWM"/> -->
757 <dep package="lib/libX11"/>
758 <dep package="lib/libXau"/>
759 <dep package="lib/libXaw"/>
760 <dep package="lib/libXcomposite"/>
761 <dep package="lib/libXcursor"/>
762 <dep package="lib/libXdamage"/>
763 <dep package="lib/libXdmcp"/>
764 <dep package="lib/libXevie"/>
765 <dep package="lib/libXext"/>
766 <dep package="lib/libXfixes"/>
767 <dep package="lib/libXfont"/>
768 <dep package="lib/libXfontcache"/>
769 <dep package="lib/libXft"/>
770 <dep package="lib/libXi"/>
771 <dep package="lib/libXinerama"/>
772 <dep package="lib/libxkbfile"/>
773 <dep package="lib/libxkbui"/>
774 <dep package="lib/libXmu"/>
775 <dep package="lib/libXp"/>
776 <dep package="lib/libXpm"/>
777 <dep package="lib/libXprintAppUtil"/>
778 <dep package="lib/libXprintUtil"/>
779 <dep package="lib/libXrandr"/>
780 <dep package="lib/libXrender"/>
781 <dep package="lib/libXres"/>
782 <dep package="lib/libXScrnSaver"/>
783 <dep package="lib/libXt"/>
784 <dep package="lib/libXTrap"/>
785 <dep package="lib/libXtst"/>
786 <dep package="lib/libXv"/>
787 <dep package="lib/libXvMC"/>
788 <dep package="lib/libXxf86dga"/>
789 <dep package="lib/libXxf86misc"/>
790 <dep package="lib/libXxf86vm"/>
791 <dep package="lib/xtrans"/>
792 </dependencies>
793 </metamodule>
794
795
796 <!-- font -->
797
798 <metamodule id="font-encodings">
799 <dependencies>
800 <dep package="util/util-macros"/>
801 <dep package="app/mkfontscale"/>
802 </dependencies>
803 </metamodule>
804
805 <metamodule id="font-font-adobe-100dpi">
806 <dependencies>
807 <dep package="util/util-macros"/>
808 <dep package="font/font-util"/>
809 <dep package="app/bdftopcf"/>
810 <dep package="app/mkfontscale"/>
811 <dep package="app/mkfontdir"/>
812 </dependencies>
813 </metamodule>
814
815 <metamodule id="font-font-adobe-75dpi">
816 <dependencies>
817 <dep package="util/util-macros"/>
818 <dep package="font/font-util"/>
819 <dep package="app/bdftopcf"/>
820 <dep package="app/mkfontscale"/>
821 <dep package="app/mkfontdir"/>
822 </dependencies>
823 </metamodule>
824
825 <metamodule id="font-font-adobe-utopia-100dpi">
826 <dependencies>
827 <dep package="util/util-macros"/>
828 <dep package="font/font-util"/>
829 <dep package="app/bdftopcf"/>
830 <dep package="app/mkfontscale"/>
831 <dep package="app/mkfontdir"/>
832 </dependencies>
833 </metamodule>
834
835 <metamodule id="font-font-adobe-utopia-75dpi">
836 <dependencies>
837 <dep package="util/util-macros"/>
838 <dep package="font/font-util"/>
839 <dep package="app/bdftopcf"/>
840 <dep package="app/mkfontscale"/>
841 <dep package="app/mkfontdir"/>
842 </dependencies>
843 </metamodule>
844
845 <metamodule id="font-font-adobe-utopia-type1">
846 <dependencies>
847 <dep package="util/util-macros"/>
848 <dep package="app/mkfontscale"/>
849 <dep package="app/mkfontdir"/>
850 <dep package="fontconfig"/>
851 </dependencies>
852 </metamodule>
853
854 <metamodule id="font-font-alias">
855 <dependencies>
856 <dep package="util/util-macros"/>
857 </dependencies>
858 </metamodule>
859
860 <metamodule id="font-font-arabic-misc">
861 <dependencies>
862 <dep package="util/util-macros"/>
863 <dep package="app/bdftopcf"/>
864 <dep package="app/mkfontscale"/>
865 <dep package="app/mkfontdir"/>
866 </dependencies>
867 </metamodule>
868
869 <metamodule id="font-font-bh-100dpi">
870 <dependencies>
871 <dep package="util/util-macros"/>
872 <dep package="font/font-util"/>
873 <dep package="app/bdftopcf"/>
874 <dep package="app/mkfontscale"/>
875 <dep package="app/mkfontdir"/>
876 </dependencies>
877 </metamodule>
878
879 <metamodule id="font-font-bh-75dpi">
880 <dependencies>
881 <dep package="util/util-macros"/>
882 <dep package="font/font-util"/>
883 <dep package="app/bdftopcf"/>
884 <dep package="app/mkfontscale"/>
885 <dep package="app/mkfontdir"/>
886 </dependencies>
887 </metamodule>
888
889 <metamodule id="font-font-bh-lucidatypewriter-100dpi">
890 <dependencies>
891 <dep package="util/util-macros"/>
892 <dep package="font/font-util"/>
893 <dep package="app/bdftopcf"/>
894 <dep package="app/mkfontscale"/>
895 <dep package="app/mkfontdir"/>
896 </dependencies>
897 </metamodule>
898
899 <metamodule id="font-font-bh-lucidatypewriter-75dpi">
900 <dependencies>
901 <dep package="util/util-macros"/>
902 <dep package="font/font-util"/>
903 <dep package="app/bdftopcf"/>
904 <dep package="app/mkfontscale"/>
905 <dep package="app/mkfontdir"/>
906 </dependencies>
907 </metamodule>
908
909 <metamodule id="font-font-bh-ttf">
910 <dependencies>
911 <dep package="util/util-macros"/>
912 <dep package="app/mkfontscale"/>
913 <dep package="app/mkfontdir"/>
914 <dep package="fontconfig"/>
915 </dependencies>
916 </metamodule>
917
918 <metamodule id="font-font-bh-type1">
919 <dependencies>
920 <dep package="util/util-macros"/>
921 <dep package="app/mkfontscale"/>
922 <dep package="app/mkfontdir"/>
923 <dep package="fontconfig"/>
924 </dependencies>
925 </metamodule>
926
927 <metamodule id="font-font-bitstream-100dpi">
928 <dependencies>
929 <dep package="util/util-macros"/>
930 <dep package="app/bdftopcf"/>
931 <dep package="app/mkfontscale"/>
932 <dep package="app/mkfontdir"/>
933 </dependencies>
934 </metamodule>
935
936 <metamodule id="font-font-bitstream-75dpi">
937 <dependencies>
938 <dep package="util/util-macros"/>
939 <dep package="app/bdftopcf"/>
940 <dep package="app/mkfontscale"/>
941 <dep package="app/mkfontdir"/>
942 </dependencies>
943 </metamodule>
944
945 <metamodule id="font-font-bitstream-speedo">
946 <dependencies>
947 <dep package="util/util-macros"/>
948 <dep package="app/mkfontdir"/>
949 </dependencies>
950 </metamodule>
951
952 <metamodule id="font-font-bitstream-type1">
953 <dependencies>
954 <dep package="util/util-macros"/>
955 <dep package="app/mkfontscale"/>
956 <dep package="app/mkfontdir"/>
957 <dep package="fontconfig"/>
958 </dependencies>
959 </metamodule>
960
961 <metamodule id="font-font-cronyx-cyrillic">
962 <dependencies>
963 <dep package="util/util-macros"/>
964 <dep package="app/bdftopcf"/>
965 <dep package="app/mkfontscale"/>
966 <dep package="app/mkfontdir"/>
967 </dependencies>
968 </metamodule>
969
970 <metamodule id="font-font-cursor-misc">
971 <dependencies>
972 <dep package="util/util-macros"/>
973 <dep package="app/bdftopcf"/>
974 <dep package="app/mkfontscale"/>
975 <dep package="app/mkfontdir"/>
976 </dependencies>
977 </metamodule>
978
979 <metamodule id="font-font-daewoo-misc">
980 <dependencies>
981 <dep package="util/util-macros"/>
982 <dep package="app/bdftopcf"/>
983 <dep package="app/mkfontscale"/>
984 <dep package="app/mkfontdir"/>
985 </dependencies>
986 </metamodule>
987
988 <metamodule id="font-font-dec-misc">
989 <dependencies>
990 <dep package="util/util-macros"/>
991 <dep package="app/bdftopcf"/>
992 <dep package="app/mkfontscale"/>
993 <dep package="app/mkfontdir"/>
994 </dependencies>
995 </metamodule>
996
997 <metamodule id="font-font-ibm-type1">
998 <dependencies>
999 <dep package="util/util-macros"/>
1000 <dep package="app/mkfontscale"/>
1001 <dep package="app/mkfontdir"/>
1002 <dep package="fontconfig"/>
1003 </dependencies>
1004 </metamodule>
1005
1006 <metamodule id="font-font-isas-misc">
1007 <dependencies>
1008 <dep package="util/util-macros"/>
1009 <dep package="app/bdftopcf"/>
1010 <dep package="app/mkfontscale"/>
1011 <dep package="app/mkfontdir"/>
1012 </dependencies>
1013 </metamodule>
1014
1015 <metamodule id="font-font-jis-misc">
1016 <dependencies>
1017 <dep package="util/util-macros"/>
1018 <dep package="app/bdftopcf"/>
1019 <dep package="app/mkfontscale"/>
1020 <dep package="app/mkfontdir"/>
1021 </dependencies>
1022 </metamodule>
1023
1024 <metamodule id="font-font-micro-misc">
1025 <dependencies>
1026 <dep package="util/util-macros"/>
1027 <dep package="app/bdftopcf"/>
1028 <dep package="app/mkfontscale"/>
1029 <dep package="app/mkfontdir"/>
1030 </dependencies>
1031 </metamodule>
1032
1033 <metamodule id="font-font-misc-cyrillic">
1034 <dependencies>
1035 <dep package="util/util-macros"/>
1036 <dep package="app/bdftopcf"/>
1037 <dep package="app/mkfontscale"/>
1038 <dep package="app/mkfontdir"/>
1039 </dependencies>
1040 </metamodule>
1041
1042 <metamodule id="font-font-misc-ethiopic">
1043 <dependencies>
1044 <dep package="util/util-macros"/>
1045 <dep package="app/mkfontscale"/>
1046 <dep package="app/mkfontdir"/>
1047 <dep package="fontconfig"/>
1048 </dependencies>
1049 </metamodule>
1050
1051 <metamodule id="font-font-misc-meltho">
1052 <dependencies>
1053 <dep package="util/util-macros"/>
1054 <dep package="app/mkfontscale"/>
1055 <dep package="app/mkfontdir"/>
1056 <dep package="fontconfig"/>
1057 </dependencies>
1058 </metamodule>
1059
1060 <metamodule id="font-font-misc-misc">
1061 <dependencies>
1062 <dep package="util/util-macros"/>
1063 <dep package="font/font-util"/>
1064 <dep package="app/bdftopcf"/>
1065 <dep package="app/mkfontscale"/>
1066 <dep package="app/mkfontdir"/>
1067 </dependencies>
1068 </metamodule>
1069
1070 <metamodule id="font-font-mutt-misc">
1071 <dependencies>
1072 <dep package="util/util-macros"/>
1073 <dep package="app/bdftopcf"/>
1074 <dep package="app/mkfontscale"/>
1075 <dep package="app/mkfontdir"/>
1076 </dependencies>
1077 </metamodule>
1078
1079 <metamodule id="font-font-schumacher-misc">
1080 <dependencies>
1081 <dep package="util/util-macros"/>
1082 <dep package="font/font-util"/>n
1083 <dep package="app/bdftopcf"/>
1084 <dep package="app/mkfontscale"/>
1085 <dep package="app/mkfontdir"/>
1086 </dependencies>
1087 </metamodule>
1088
1089 <metamodule id="font-font-screen-cyrillic">
1090 <dependencies>
1091 <dep package="util/util-macros"/>
1092 <dep package="app/bdftopcf"/>
1093 <dep package="app/mkfontscale"/>
1094 <dep package="app/mkfontdir"/>
1095 </dependencies>
1096 </metamodule>
1097
1098 <metamodule id="font-font-sony-misc">
1099 <dependencies>
1100 <dep package="util/util-macros"/>
1101 <dep package="app/bdftopcf"/>
1102 <dep package="app/mkfontscale"/>
1103 <dep package="app/mkfontdir"/>
1104 </dependencies>
1105 </metamodule>
1106
1107 <metamodule id="font-font-sun-misc">
1108 <dependencies>
1109 <dep package="util/util-macros"/>
1110 <dep package="app/bdftopcf"/>
1111 <dep package="app/mkfontscale"/>
1112 <dep package="app/mkfontdir"/>
1113 </dependencies>
1114 </metamodule>
1115
1116 <metamodule id="font-font-util">
1117 <dependencies>
1118 <dep package="util/util-macros"/>
1119 </dependencies>
1120 </metamodule>
1121
1122 <metamodule id="font-font-winitzki-cyrillic">
1123 <dependencies>
1124 <dep package="util/util-macros"/>
1125 <dep package="app/bdftopcf"/>
1126 <dep package="app/mkfontscale"/>
1127 <dep package="app/mkfontdir"/>
1128 </dependencies>
1129 </metamodule>
1130
1131 <metamodule id="font-font-xfree86-type1">
1132 <dependencies>
1133 <dep package="util/util-macros"/>
1134 <dep package="app/mkfontscale"/>
1135 <dep package="app/mkfontdir"/>
1136 <dep package="fontconfig"/>
1137 </dependencies>
1138 </metamodule>
1139
1140 <metamodule id="font">
1141 <dependencies>
1142 <dep package="font/encodings"/>
1143 <dep package="font/font-adobe-100dpi"/>
1144 <dep package="font/font-adobe-75dpi"/>
1145 <dep package="font/font-adobe-utopia-100dpi"/>
1146 <dep package="font/font-adobe-utopia-75dpi"/>
1147 <dep package="font/font-adobe-utopia-type1"/>
1148 <dep package="font/font-alias"/>
1149 <dep package="font/font-arabic-misc"/>
1150 <dep package="font/font-bh-100dpi"/>
1151 <dep package="font/font-bh-75dpi"/>
1152 <dep package="font/font-bh-lucidatypewriter-100dpi"/>
1153 <dep package="font/font-bh-lucidatypewriter-75dpi"/>
1154 <dep package="font/font-bh-ttf"/>
1155 <dep package="font/font-bh-type1"/>
1156 <dep package="font/font-bitstream-100dpi"/>
1157 <dep package="font/font-bitstream-75dpi"/>
1158 <dep package="font/font-bitstream-speedo"/>
1159 <dep package="font/font-bitstream-type1"/>
1160 <dep package="font/font-cronyx-cyrillic"/>
1161 <dep package="font/font-cursor-misc"/>
1162 <dep package="font/font-daewoo-misc"/>
1163 <dep package="font/font-dec-misc"/>
1164 <dep package="font/font-ibm-type1"/>
1165 <dep package="font/font-isas-misc"/>
1166 <dep package="font/font-jis-misc"/>
1167 <dep package="font/font-micro-misc"/>
1168 <dep package="font/font-misc-cyrillic"/>
1169 <dep package="font/font-misc-ethiopic"/>
1170 <dep package="font/font-misc-meltho"/>
1171 <dep package="font/font-misc-misc"/>
1172 <dep package="font/font-mutt-misc"/>
1173 <dep package="font/font-schumacher-misc"/>
1174 <dep package="font/font-screen-cyrillic"/>
1175 <dep package="font/font-sony-misc"/>
1176 <dep package="font/font-sun-misc"/>
1177 <dep package="font/font-util"/>
1178 <dep package="font/font-winitzki-cyrillic"/>
1179 <dep package="font/font-xfree86-type1"/>
1180 </dependencies>
1181 </metamodule>
1182
1183
1184 <!-- data -->
1185
1186 <metamodule id="data-xbitmaps">
1187 <dependencies>
1188 <dep package="util/util-macros"/>
1189 </dependencies>
1190 </metamodule>
1191
1192 <metamodule id="data-xcursor-themes">
1193 <dependencies>
1194 <dep package="util/util-macros"/>
1195 <dep package="app/xcursorgen"/>
1196 </dependencies>
1197 </metamodule>
1198
1199 <metamodule id="data-xkbdata">
1200 <dependencies>
1201 <dep package="util/util-macros"/>
1202 <dep package="app/xkbcomp"/>
1203 </dependencies>
1204 </metamodule>
1205
1206 <metamodule id="data">
1207 <dependencies>
1208 <dep package="data/xbitmaps"/>
1209 <dep package="data/xcursor-themes"/>
1210 <dep package="data/xkbdata"/>
1211 </dependencies>
1212 </metamodule>
1213
1214
1215 <!-- app -->
1216
1217 <metamodule id="app-appres">
1218 <dependencies>
1219 <dep package="util/util-macros"/>
1220 <dep package="lib/libX11"/>
1221 <dep package="lib/libXt"/>
1222 </dependencies>
1223 </metamodule>
1224
1225 <metamodule id="app-bdftopcf">
1226 <dependencies>
1227 <dep package="util/util-macros"/>
1228 <dep package="lib/libXfont"/>
1229 <dep package="proto/fontsproto"/>
1230 <dep package="proto/xproto"/>
1231 </dependencies>
1232 </metamodule>
1233
1234 <metamodule id="app-beforelight">
1235 <dependencies>
1236 <dep package="util/util-macros"/>
1237 <dep package="lib/libX11"/>
1238 <dep package="lib/libXScrnSaver"/>
1239 <dep package="lib/libXt"/>
1240 <dep package="lib/libXaw"/>
1241 </dependencies>
1242 </metamodule>
1243
1244 <metamodule id="app-bitmap">
1245 <dependencies>
1246 <dep package="util/util-macros"/>
1247 <dep package="lib/libX11"/>
1248 <dep package="lib/libXmu"/>
1249 <dep package="lib/libXaw"/>
1250 <dep package="data/xbitmaps"/>
1251 </dependencies>
1252 </metamodule>
1253
1254 <metamodule id="app-constype">
1255 <dependencies>
1256 <dep package="util/util-macros"/>
1257 </dependencies>
1258 </metamodule>
1259
1260 <metamodule id="app-editres">
1261 <dependencies>
1262 <dep package="util/util-macros"/>
1263 <dep package="lib/libXaw"/>
1264 <dep package="lib/libX11"/>
1265 <dep package="lib/libXt"/>
1266 <dep package="lib/libXmu"/>
1267 </dependencies>
1268 </metamodule>
1269
1270 <metamodule id="app-fonttosfnt">
1271 <dependencies>
1272 <dep package="util/util-macros"/>
1273 <dep package="lib/libX11"/>
1274 <dep package="lib/libfontenc"/>
1275 <dep package="freetype2"/>
1276 </dependencies>
1277 </metamodule>
1278
1279 <metamodule id="app-fslsfonts">
1280 <dependencies>
1281 <dep package="util/util-macros"/>
1282 <dep package="lib/libX11"/>
1283 <dep package="lib/libFS"/>
1284 </dependencies>
1285 </metamodule>
1286
1287 <metamodule id="app-fstobdf">
1288 <dependencies>
1289 <dep package="util/util-macros"/>
1290 <dep package="lib/libX11"/>
1291 <dep package="lib/libFS"/>
1292 </dependencies>
1293 </metamodule>
1294
1295 <metamodule id="app-iceauth">
1296 <dependencies>
1297 <dep package="util/util-macros"/>
1298 <dep package="lib/libX11"/>
1299 <dep package="lib/libICE"/>
1300 </dependencies>
1301 </metamodule>
1302
1303 <metamodule id="app-ico">
1304 <dependencies>
1305 <dep package="util/util-macros"/>
1306 <dep package="lib/libX11"/>
1307 </dependencies>
1308 </metamodule>
1309
1310 <metamodule id="app-lbxproxy">
1311 <dependencies>
1312 <dep package="util/util-macros"/>
1313 <dep package="lib/xtrans"/>
1314 <dep package="lib/libXext"/>
1315 <dep package="lib/liblbxutil"/>
1316 <dep package="lib/libX11"/>
1317 <dep package="lib/libICE"/>
1318 <dep package="proto/xproxymanagementprotocol"/>
1319 <dep package="proto/bigreqsproto"/>
1320 </dependencies>
1321 </metamodule>
1322
1323 <metamodule id="app-listres">
1324 <dependencies>
1325 <dep package="util/util-macros"/>
1326 <dep package="lib/libXaw"/>
1327 <dep package="lib/libX11"/>
1328 <dep package="lib/libXt"/>
1329 <dep package="lib/libXmu"/>
1330 </dependencies>
1331 </metamodule>
1332
1333 <metamodule id="app-luit">
1334 <dependencies>
1335 <dep package="util/util-macros"/>
1336 <dep package="lib/libX11"/>
1337 <dep package="lib/libfontenc"/>
1338 </dependencies>
1339 </metamodule>
1340
1341 <metamodule id="app-mkcfm">
1342 <dependencies>
1343 <dep package="util/util-macros"/>
1344 <dep package="lib/libX11"/>
1345 <dep package="lib/libXfont"/>
1346 <dep package="lib/libFS"/>
1347 <dep package="proto/fontsproto"/>
1348 <dep package="lib/libfontenc"/>
1349 </dependencies>
1350 </metamodule>
1351
1352 <metamodule id="app-mkfontdir">
1353 <dependencies>
1354 <dep package="util/util-macros"/>
1355 </dependencies>
1356 </metamodule>
1357
1358 <metamodule id="app-mkfontscale">
1359 <dependencies>
1360 <dep package="util/util-macros"/>
1361 <dep package="lib/libfontenc"/>
1362 <dep package="freetype2"/>
1363 </dependencies>
1364 </metamodule>
1365
1366 <metamodule id="app-oclock">
1367 <dependencies>
1368 <dep package="util/util-macros"/>
1369 <dep package="lib/libX11"/>
1370 <dep package="lib/libXmu"/>
1371 <dep package="lib/libXext"/>
1372 </dependencies>
1373 </metamodule>
1374
1375 <metamodule id="app-proxymngr">
1376 <dependencies>
1377 <dep package="util/util-macros"/>
1378 <dep package="lib/libX11"/>
1379 <dep package="lib/libXt"/>
1380 <dep package="lib/libICE"/>
1381 <dep package="proto/xproxymanagementprotocol"/>
1382 </dependencies>
1383 </metamodule>
1384
1385 <metamodule id="app-rgb">
1386 <dependencies>
1387 <dep package="util/util-macros"/>
1388 <dep package="proto/xproto"/>
1389 </dependencies>
1390 </metamodule>
1391
1392 <metamodule id="app-rstart">
1393 <dependencies>
1394 <dep package="util/util-macros"/>
1395 <dep package="lib/libX11"/>
1396 </dependencies>
1397 </metamodule>
1398
1399 <metamodule id="app-scripts">
1400 <dependencies>
1401 <dep package="util/util-macros"/>
1402 <dep package="lib/libX11"/>
1403 </dependencies>
1404 </metamodule>
1405
1406 <metamodule id="app-sessreg">
1407 <dependencies>
1408 <dep package="util/util-macros"/>
1409 <dep package="proto/xproto"/>
1410 </dependencies>
1411 </metamodule>
1412
1413 <metamodule id="app-setxkbmap">
1414 <dependencies>
1415 <dep package="util/util-macros"/>
1416 <dep package="lib/libxkbfile"/>
1417 <dep package="lib/libX11"/>
1418 </dependencies>
1419 </metamodule>
1420
1421 <metamodule id="app-showfont">
1422 <dependencies>
1423 <dep package="util/util-macros"/>
1424 <dep package="lib/libFS"/>
1425 </dependencies>
1426 </metamodule>
1427
1428 <metamodule id="app-smproxy">
1429 <dependencies>
1430 <dep package="util/util-macros"/>
1431 <dep package="lib/libXt"/>
1432 <dep package="lib/libXmu"/>
1433 </dependencies>
1434 </metamodule>
1435
1436 <metamodule id="app-twm">
1437 <dependencies>
1438 <dep package="util/util-macros"/>
1439 <dep package="lib/libX11"/>
1440 <dep package="lib/libXt"/>
1441 <dep package="lib/libXmu"/>
1442 </dependencies>
1443 </metamodule>
1444
1445 <metamodule id="app-viewres">
1446 <dependencies>
1447 <dep package="util/util-macros"/>
1448 <dep package="lib/libXaw"/>
1449 </dependencies>
1450 </metamodule>
1451
1452 <metamodule id="app-x11perf">
1453 <dependencies>
1454 <dep package="util/util-macros"/>
1455 <dep package="lib/libX11"/>
1456 <dep package="lib/libXmu"/>
1457 </dependencies>
1458 </metamodule>
1459
1460 <metamodule id="app-xauth">
1461 <dependencies>
1462 <dep package="util/util-macros"/>
1463 <dep package="lib/libX11"/>
1464 <dep package="lib/libXau"/>
1465 <dep package="lib/libXext"/>
1466 <dep package="lib/libXmu"/>
1467 </dependencies>
1468 </metamodule>
1469
1470 <metamodule id="app-xbiff">
1471 <dependencies>
1472 <dep package="util/util-macros"/>
1473 <dep package="lib/libXaw"/>
1474 <dep package="data/xbitmaps"/>
1475 </dependencies>
1476 </metamodule>
1477
1478 <metamodule id="app-xcalc">
1479 <dependencies>
1480 <dep package="util/util-macros"/>
1481 <dep package="lib/libXaw"/>
1482 </dependencies>
1483 </metamodule>
1484
1485 <metamodule id="app-xclipboard">
1486 <dependencies>
1487 <dep package="util/util-macros"/>
1488 <dep package="lib/libXaw"/>
1489 </dependencies>
1490 </metamodule>
1491
1492 <metamodule id="app-xclock">
1493 <dependencies>
1494 <dep package="util/util-macros"/>
1495 <dep package="lib/libXaw"/>
1496 </dependencies>
1497 </metamodule>
1498
1499 <metamodule id="app-xcmsdb">
1500 <dependencies>
1501 <dep package="util/util-macros"/>
1502 <dep package="lib/libX11"/>
1503 </dependencies>
1504 </metamodule>
1505
1506 <metamodule id="app-xconsole">
1507 <dependencies>
1508 <dep package="util/util-macros"/>
1509 <dep package="lib/libXaw"/>
1510 </dependencies>
1511 </metamodule>
1512
1513 <metamodule id="app-xcursorgen">
1514 <dependencies>
1515 <dep package="util/util-macros"/>
1516 <dep package="lib/libX11"/>
1517 <dep package="lib/libXcursor"/>
1518 </dependencies>
1519 </metamodule>
1520
1521 <metamodule id="app-xdbedizzy">
1522 <dependencies>
1523 <dep package="util/util-macros"/>
1524 <dep package="lib/libXext"/>
1525 </dependencies>
1526 </metamodule>
1527
1528 <metamodule id="app-xditview">
1529 <dependencies>
1530 <dep package="util/util-macros"/>
1531 <dep package="lib/libXaw"/>
1532 </dependencies>
1533 </metamodule>
1534
1535 <metamodule id="app-xdm">
1536 <dependencies>
1537 <dep package="util/util-macros"/>
1538 <dep package="lib/libXaw"/>
1539 <dep package="lib/libXdmcp"/>
1540 <dep package="proto/xproto"/>
1541 <dep package="lib/libXau"/>
1542 <dep package="lib/libXt"/>
1543 </dependencies>
1544 <suggests>
1545 <dep package="lib/libXinerama"/>
1546 <dep package="lib/libXpm"/>
1547 </suggests>
1548 </metamodule>
1549
1550 <metamodule id="app-xdpyinfo">
1551 <dependencies>
1552 <dep package="util/util-macros"/>
1553 <dep package="lib/libX11"/>
1554 <dep package="lib/libXext"/>
1555 <dep package="lib/libXtst"/>
1556 </dependencies>
1557 <suggests>
1558 <dep package="proto/xextproto"/>
1559 <dep package="proto/kbproto"/>
1560 <dep package="proto/xf86vidmodeproto"/>
1561 <dep package="lib/libXxf86vm"/>
1562 <dep package="proto/xf86dgaproto"/>
1563 <dep package="lib/libXxf86dga"/>
1564 <dep package="proto/xf86miscproto"/>
1565 <dep package="lib/libXxf86misc"/>
1566 <dep package="proto/inputproto"/>
1567 <dep package="lib/libXi"/>
1568 <dep package="proto/renderproto"/>
1569 <dep package="lib/libXrender"/>
1570 <dep package="proto/xineramaproto"/>
1571 <dep package="lib/libXinerama"/>
1572 <dep package="proto/dmxproto"/>
1573 <dep package="lib/libdmx"/>
1574 <dep package="proto/printproto"/>
1575 <dep package="lib/libXp"/>
1576 </suggests>
1577 </metamodule>
1578
1579 <metamodule id="app-xdriinfo">
1580 <dependencies>
1581 <dep package="util/util-macros"/>
1582 <dep package="lib/libX11"/>
1583 <dep package="proto/glproto"/>
1584 </dependencies>
1585 </metamodule>
1586
1587 <metamodule id="app-xedit">
1588 <dependencies>
1589 <dep package="util/util-macros"/>
1590 <dep package="lib/libXaw"/>
1591 </dependencies>
1592 </metamodule>
1593
1594 <metamodule id="app-xev">
1595 <dependencies>
1596 <dep package="util/util-macros"/>
1597 <dep package="lib/libX11"/>
1598 </dependencies>
1599 </metamodule>
1600
1601 <metamodule id="app-xeyes">
1602 <dependencies>
1603 <dep package="util/util-macros"/>
1604 <dep package="lib/libX11"/>
1605 <dep package="lib/libXt"/>
1606 <dep package="lib/libXext"/>
1607 <dep package="lib/libXmu"/>
1608 </dependencies>
1609 </metamodule>
1610
1611 <metamodule id="app-xf86dga">
1612 <dependencies>
1613 <dep package="util/util-macros"/>
1614 <dep package="lib/libX11"/>
1615 <dep package="lib/libXxf86dga"/>
1616 <dep package="lib/libXt"/>
1617 <dep package="lib/libXaw"/>
1618 <dep package="lib/libXmu"/>
1619 </dependencies>
1620 </metamodule>
1621
1622 <metamodule id="app-xfd">
1623 <dependencies>
1624 <dep package="util/util-macros"/>
1625 <dep package="lib/libXaw"/>
1626 <dep package="lib/libXft"/>
1627 <dep package="freetype2"/>
1628 <dep package="fontconfig"/>
1629 </dependencies>
1630 </metamodule>
1631
1632 <metamodule id="app-xfindproxy">
1633 <dependencies>
1634 <dep package="util/util-macros"/>
1635 <dep package="lib/libX11"/>
1636 <dep package="lib/libICE"/>
1637 <dep package="lib/libXt"/>
1638 <dep package="proto/xproxymanagementprotocol"/>
1639 </dependencies>
1640 </metamodule>
1641
1642 <metamodule id="app-xfontsel">
1643 <dependencies>
1644 <dep package="util/util-macros"/>
1645 <dep package="lib/libXaw"/>
1646 </dependencies>
1647 </metamodule>
1648
1649 <metamodule id="app-xfs">
1650 <dependencies>
1651 <dep package="util/util-macros"/>
1652 <dep package="lib/libFS"/>
1653 <dep package="lib/libXfont"/>
1654 <dep package="proto/fontsproto"/>
1655 <dep package="lib/xtrans"/>
1656 </dependencies>
1657 </metamodule>
1658
1659 <metamodule id="app-xfsinfo">
1660 <dependencies>
1661 <dep package="util/util-macros"/>
1662 <dep package="lib/libX11"/>
1663 <dep package="lib/libFS"/>
1664 </dependencies>
1665 </metamodule>
1666
1667 <metamodule id="app-xfwp">
1668 <dependencies>
1669 <dep package="util/util-macros"/>
1670 <dep package="lib/libX11"/>
1671 <dep package="lib/libICE"/>
1672 <dep package="proto/xproxymanagementprotocol"/>
1673 </dependencies>
1674 </metamodule>
1675
1676 <metamodule id="app-xgamma">
1677 <dependencies>
1678 <dep package="util/util-macros"/>
1679 <dep package="lib/libXxf86vm"/>
1680 </dependencies>
1681 </metamodule>
1682
1683 <metamodule id="app-xgc">
1684 <dependencies>
1685 <dep package="util/util-macros"/>
1686 <dep package="lib/libXaw"/>
1687 </dependencies>
1688 </metamodule>
1689
1690 <metamodule id="app-xhost">
1691 <dependencies>
1692 <dep package="util/util-macros"/>
1693 <dep package="lib/libX11"/>
1694 <dep package="lib/libXmu"/>
1695 <dep package="lib/libXau"/>
1696 </dependencies>
1697 </metamodule>
1698
1699 <metamodule id="app-xinit">
1700 <dependencies>
1701 <dep package="util/util-macros"/>
1702 <dep package="lib/libX11"/>
1703 </dependencies>
1704 </metamodule>
1705
1706 <metamodule id="app-xkbcomp">
1707 <dependencies>
1708 <dep package="util/util-macros"/>
1709 <dep package="lib/libX11"/>
1710 <dep package="lib/libxkbfile"/>
1711 </dependencies>
1712 </metamodule>
1713
1714 <metamodule id="app-xkbevd">
1715 <dependencies>
1716 <dep package="util/util-macros"/>
1717 <dep package="lib/libxkbfile"/>
1718 </dependencies>
1719 </metamodule>
1720
1721 <metamodule id="app-xkbprint">
1722 <dependencies>
1723 <dep package="util/util-macros"/>
1724 <dep package="lib/libxkbfile"/>
1725 </dependencies>
1726 </metamodule>
1727
1728 <metamodule id="app-xkbutils">
1729 <dependencies>
1730 <dep package="util/util-macros"/>
1731 <dep package="lib/libxkbfile"/>
1732 <dep package="lib/libXaw"/>
1733 <dep package="proto/inputproto"/>
1734 </dependencies>
1735 </metamodule>
1736
1737 <metamodule id="app-xkill">
1738 <dependencies>
1739 <dep package="util/util-macros"/>
1740 <dep package="lib/libX11"/>
1741 <dep package="lib/libXmu"/>
1742 </dependencies>
1743 </metamodule>
1744
1745 <metamodule id="app-xload">
1746 <dependencies>
1747 <dep package="util/util-macros"/>
1748 <dep package="lib/libXaw"/>
1749 </dependencies>
1750 </metamodule>
1751
1752 <metamodule id="app-xlogo">
1753 <dependencies>
1754 <dep package="util/util-macros"/>
1755 <dep package="lib/libXaw"/>
1756 </dependencies>
1757 </metamodule>
1758
1759 <metamodule id="app-xlsatoms">
1760 <dependencies>
1761 <dep package="util/util-macros"/>
1762 <dep package="lib/libX11"/>
1763 <dep package="lib/libXmu"/>
1764 </dependencies>
1765 </metamodule>
1766
1767 <metamodule id="app-xlsclients">
1768 <dependencies>
1769 <dep package="util/util-macros"/>
1770 <dep package="lib/libX11"/>
1771 <dep package="lib/libXmu"/>
1772 </dependencies>
1773 </metamodule>
1774
1775 <metamodule id="app-xlsfonts">
1776 <dependencies>
1777 <dep package="util/util-macros"/>
1778 <dep package="lib/libX11"/>
1779 </dependencies>
1780 </metamodule>
1781
1782 <metamodule id="app-xmag">
1783 <dependencies>
1784 <dep package="util/util-macros"/>
1785 <dep package="lib/libXaw"/>
1786 </dependencies>
1787 </metamodule>
1788
1789 <metamodule id="app-xman">
1790 <dependencies>
1791 <dep package="util/util-macros"/>
1792 <dep package="lib/libXaw"/>
1793 </dependencies>
1794 </metamodule>
1795
1796 <metamodule id="app-xmessage">
1797 <dependencies>
1798 <dep package="util/util-macros"/>
1799 <dep package="lib/libXaw"/>
1800 </dependencies>
1801 </metamodule>
1802
1803 <metamodule id="app-xmh">
1804 <dependencies>
1805 <dep package="util/util-macros"/>
1806 <dep package="lib/libXaw"/>
1807 </dependencies>
1808 </metamodule>
1809
1810 <metamodule id="app-xmodmap">
1811 <dependencies>
1812 <dep package="util/util-macros"/>
1813 <dep package="lib/libX11"/>
1814 </dependencies>
1815 </metamodule>
1816
1817 <metamodule id="app-xmore">
1818 <dependencies>
1819 <dep package="util/util-macros"/>
1820 <dep package="lib/libXaw"/>
1821 </dependencies>
1822 </metamodule>
1823
1824 <metamodule id="app-xphelloworld">
1825 <dependencies>
1826 <dep package="util/util-macros"/>
1827 <dep package="lib/libX11"/>
1828 <dep package="lib/libXaw"/>
1829 <dep package="lib/libXprintUtil"/>
1830 <dep package="lib/libXt"/>
1831 </dependencies>
1832 </metamodule>
1833
1834 <metamodule id="app-xplsprinters">
1835 <dependencies>
1836 <dep package="util/util-macros"/>
1837 <dep package="lib/libX11"/>
1838 <dep package="lib/libXprintUtil"/>
1839 <dep package="lib/libXt"/>
1840 </dependencies>
1841 </metamodule>
1842
1843 <metamodule id="app-xpr">
1844 <dependencies>
1845 <dep package="util/util-macros"/>
1846 <dep package="lib/libX11"/>
1847 <dep package="lib/libXmu"/>
1848 </dependencies>
1849 </metamodule>
1850
1851 <metamodule id="app-xprehashprinterlist">
1852 <dependencies>
1853 <dep package="util/util-macros"/>
1854 <dep package="lib/libX11"/>
1855 <dep package="lib/libXp"/>
1856 </dependencies>
1857 </metamodule>
1858
1859 <metamodule id="app-xprop">
1860 <dependencies>
1861 <dep package="util/util-macros"/>
1862 <dep package="lib/libX11"/>
1863 <dep package="lib/libXmu"/>
1864 </dependencies>
1865 </metamodule>
1866
1867 <metamodule id="app-xrandr">
1868 <dependencies>
1869 <dep package="util/util-macros"/>
1870 <dep package="lib/libX11"/>
1871 <dep package="lib/libXrandr"/>
1872 </dependencies>
1873 </metamodule>
1874
1875 <metamodule id="app-xrdb">
1876 <dependencies>
1877 <dep package="util/util-macros"/>
1878 <dep package="lib/libX11"/>
1879 <dep package="lib/libXmu"/>
1880 </dependencies>
1881 </metamodule>
1882
1883 <metamodule id="app-xrefresh">
1884 <dependencies>
1885 <dep package="util/util-macros"/>
1886 <dep package="lib/libX11"/>
1887 </dependencies>
1888 </metamodule>
1889
1890 <metamodule id="app-xrx">
1891 <dependencies>
1892 <dep package="util/util-macros"/>
1893 <dep package="lib/libX11"/>
1894 <dep package="lib/libXt"/>
1895 <dep package="lib/libXext"/>
1896 <dep package="lib/xtrans"/>
1897 <dep package="proto/xproxymanagementprotocol"/>
1898 </dependencies>
1899 </metamodule>
1900
1901 <metamodule id="app-xset">
1902 <dependencies>
1903 <dep package="util/util-macros"/>
1904 <dep package="lib/libXmu"/>
1905 </dependencies>
1906 <suggests>
1907 <dep package="proto/xextproto"/>
1908 <dep package="lib/libXext"/>
1909 <dep package="proto/kbproto"/>
1910 <dep package="lib/libX11"/>
1911 <dep package="proto/xf86miscproto"/>
1912 <dep package="lib/libXxf86misc"/>
1913 <dep package="proto/fontcacheproto"/>
1914 <dep package="lib/libXfontcache"/>
1915 <dep package="proto/printproto"/>
1916 <dep package="lib/libXp"/>
1917 </suggests>
1918 </metamodule>
1919
1920 <metamodule id="app-xsetmode">
1921 <dependencies>
1922 <dep package="util/util-macros"/>
1923 <dep package="lib/libX11"/>
1924 <dep package="lib/libXi"/>
1925 </dependencies>
1926 </metamodule>
1927
1928 <metamodule id="app-xsetpointer">
1929 <dependencies>
1930 <dep package="util/util-macros"/>
1931 <dep package="lib/libX11"/>
1932 <dep package="lib/libXi"/>
1933 </dependencies>
1934 </metamodule>
1935
1936 <metamodule id="app-xsetroot">
1937 <dependencies>
1938 <dep package="util/util-macros"/>
1939 <dep package="lib/libX11"/>
1940 <dep package="lib/libXmu"/>
1941 <dep package="data/xbitmaps"/>
1942 </dependencies>
1943 </metamodule>
1944
1945 <metamodule id="app-xsm">
1946 <dependencies>
1947 <dep package="util/util-macros"/>
1948 <dep package="lib/libXaw"/>
1949 </dependencies>
1950 </metamodule>
1951
1952 <metamodule id="app-xstdcmap">
1953 <dependencies>
1954 <dep package="util/util-macros"/>
1955 <dep package="lib/libX11"/>
1956 <dep package="lib/libXmu"/>
1957 </dependencies>
1958 </metamodule>
1959
1960 <metamodule id="app-xtrap">
1961 <dependencies>
1962 <dep package="util/util-macros"/>
1963 <dep package="lib/libX11"/>
1964 <dep package="lib/libXTrap"/>
1965 </dependencies>
1966 </metamodule>
1967
1968 <metamodule id="app-xvidtune">
1969 <dependencies>
1970 <dep package="util/util-macros"/>
1971 <dep package="lib/libXaw"/>
1972 <dep package="lib/libXxf86vm"/>
1973 </dependencies>
1974 </metamodule>
1975
1976 <metamodule id="app-xvinfo">
1977 <dependencies>
1978 <dep package="util/util-macros"/>
1979 <dep package="lib/libX11"/>
1980 <dep package="lib/libXv"/>
1981 </dependencies>
1982 </metamodule>
1983
1984 <metamodule id="app-xwd">
1985 <dependencies>
1986 <dep package="util/util-macros"/>
1987 <dep package="lib/libX11"/>
1988 <dep package="lib/libXmu"/>
1989 </dependencies>
1990 </metamodule>
1991
1992 <metamodule id="app-xwininfo">
1993 <dependencies>
1994 <dep package="util/util-macros"/>
1995 <dep package="lib/libX11"/>
1996 <dep package="lib/libXmu"/>
1997 </dependencies>
1998 </metamodule>
1999
2000 <metamodule id="app-xwud">
2001 <dependencies>
2002 <dep package="util/util-macros"/>
2003 <dep package="lib/libX11"/>
2004 </dependencies>
2005 </metamodule>
2006
2007 <metamodule id="app">
2008 <dependencies>
2009 <dep package="app/appres"/>
2010 <dep package="app/bdftopcf"/>
2011 <dep package="app/beforelight"/>
2012 <dep package="app/bitmap"/>
2013 <!-- <dep package="app/constype"/> -->
2014 <dep package="app/editres"/>
2015 <dep package="app/fonttosfnt"/>
2016 <dep package="app/fslsfonts"/>
2017 <dep package="app/fstobdf"/>
2018 <dep package="app/iceauth"/>
2019 <dep package="app/ico"/>
2020 <dep package="app/lbxproxy"/>
2021 <dep package="app/listres"/>
2022 <dep package="app/luit"/>
2023 <dep package="app/mkcfm"/>
2024 <dep package="app/mkfontdir"/>
2025 <dep package="app/mkfontscale"/>
2026 <dep package="app/oclock"/>
2027 <dep package="app/proxymngr"/>
2028 <dep package="app/rgb"/>
2029 <dep package="app/rstart"/>
2030 <dep package="app/scripts"/>
2031 <dep package="app/sessreg"/>
2032 <dep package="app/setxkbmap"/>
2033 <dep package="app/showfont"/>
2034 <dep package="app/smproxy"/>
2035 <dep package="app/twm"/>
2036 <dep package="app/viewres"/>
2037 <dep package="app/x11perf"/>
2038 <dep package="app/xauth"/>
2039 <dep package="app/xbiff"/>
2040 <dep package="app/xcalc"/>
2041 <dep package="app/xclipboard"/>
2042 <dep package="app/xclock"/>
2043 <dep package="app/xcmsdb"/>
2044 <dep package="app/xconsole"/>
2045 <dep package="app/xcursorgen"/>
2046 <dep package="app/xdbedizzy"/>
2047 <dep package="app/xditview"/>
2048 <dep package="app/xdm"/>
2049 <dep package="app/xdpyinfo"/>
2050 <dep package="app/xdriinfo"/>
2051 <dep package="app/xedit"/>
2052 <dep package="app/xev"/>
2053 <dep package="app/xeyes"/>
2054 <dep package="app/xf86dga"/>
2055 <dep package="app/xfd"/>
2056 <dep package="app/xfindproxy"/>
2057 <dep package="app/xfontsel"/>
2058 <dep package="app/xfs"/>
2059 <dep package="app/xfsinfo"/>
2060 <dep package="app/xfwp"/>
2061 <dep package="app/xgamma"/>
2062 <dep package="app/xgc"/>
2063 <dep package="app/xhost"/>
2064 <dep package="app/xinit"/>
2065 <dep package="app/xkbcomp"/>
2066 <dep package="app/xkbevd"/>
2067 <dep package="app/xkbprint"/>
2068 <dep package="app/xkbutils"/>
2069 <dep package="app/xkill"/>
2070 <dep package="app/xload"/>
2071 <dep package="app/xlogo"/>
2072 <dep package="app/xlsatoms"/>
2073 <dep package="app/xlsclients"/>
2074 <dep package="app/xlsfonts"/>
2075 <dep package="app/xmag"/>
2076 <dep package="app/xman"/>
2077 <dep package="app/xmessage"/>
2078 <dep package="app/xmh"/>
2079 <dep package="app/xmodmap"/>
2080 <dep package="app/xmore"/>
2081 <dep package="app/xphelloworld"/>
2082 <dep package="app/xplsprinters"/>
2083 <dep package="app/xpr"/>
2084 <dep package="app/xprehashprinterlist"/>
2085 <dep package="app/xprop"/>
2086 <dep package="app/xrandr"/>
2087 <dep package="app/xrdb"/>
2088 <dep package="app/xrefresh"/>
2089 <dep package="app/xrx"/>
2090 <dep package="app/xset"/>
2091 <dep package="app/xsetmode"/>
2092 <dep package="app/xsetpointer"/>
2093 <dep package="app/xsetroot"/>
2094 <dep package="app/xsm"/>
2095 <dep package="app/xstdcmap"/>
2096 <dep package="app/xtrap"/>
2097 <dep package="app/xvidtune"/>
2098 <dep package="app/xvinfo"/>
2099 <dep package="app/xwd"/>
2100 <dep package="app/xwininfo"/>
2101 <dep package="app/xwud"/>
2102 </dependencies>
2103 </metamodule>
2104
2105
2106 <!-- input drivers -->
2107
2108 <metamodule id="driver-xf86-input-acecad">
2109 <dependencies>
2110 <dep package="util/util-macros"/>
2111 <dep package="proto/xproto"/>
2112 <dep package="xserver/xorg-server"/>
2113 </dependencies>
2114 </metamodule>
2115
2116 <metamodule id="driver-xf86-input-aiptek">
2117 <dependencies>
2118 <dep package="util/util-macros"/>
2119 <dep package="proto/xproto"/>
2120 <dep package="xserver/xorg-server"/>
2121 </dependencies>
2122 </metamodule>
2123
2124 <metamodule id="driver-xf86-input-calcomp">
2125 <dependencies>
2126 <dep package="util/util-macros"/>
2127 <dep package="proto/xproto"/>
2128 <dep package="xserver/xorg-server"/>
2129 </dependencies>
2130 </metamodule>
2131
2132 <metamodule id="driver-xf86-input-citron">
2133 <dependencies>
2134 <dep package="util/util-macros"/>
2135 <dep package="proto/xproto"/>
2136 <dep package="xserver/xorg-server"/>
2137 </dependencies>
2138 </metamodule>
2139
2140 <metamodule id="driver-xf86-input-digitaledge">
2141 <dependencies>
2142 <dep package="util/util-macros"/>
2143 <dep package="proto/xproto"/>
2144 <dep package="xserver/xorg-server"/>
2145 </dependencies>
2146 </metamodule>
2147
2148 <metamodule id="driver-xf86-input-dmc">
2149 <dependencies>
2150 <dep package="util/util-macros"/>
2151 <dep package="proto/xproto"/>
2152 <dep package="xserver/xorg-server"/>
2153 </dependencies>
2154 </metamodule>
2155
2156 <metamodule id="driver-xf86-input-dynapro">
2157 <dependencies>
2158 <dep package="util/util-macros"/>
2159 <dep package="proto/xproto"/>
2160 <dep package="xserver/xorg-server"/>
2161 </dependencies>
2162 </metamodule>
2163
2164 <metamodule id="driver-xf86-input-elo2300">
2165 <dependencies>
2166 <dep package="util/util-macros"/>
2167 <dep package="proto/xproto"/>
2168 <dep package="xserver/xorg-server"/>
2169 </dependencies>
2170 </metamodule>
2171
2172 <metamodule id="driver-xf86-input-elographics">
2173 <dependencies>
2174 <dep package="util/util-macros"/>
2175 <dep package="proto/xproto"/>
2176 <dep package="xserver/xorg-server"/>
2177 </dependencies>
2178 </metamodule>
2179
2180 <metamodule id="driver-xf86-input-evdev">
2181 <dependencies>
2182 <dep package="util/util-macros"/>
2183 <dep package="proto/xproto"/>
2184 <dep package="xserver/xorg-server"/>
2185 </dependencies>
2186 </metamodule>
2187
2188 <metamodule id="driver-xf86-input-fpit">
2189 <dependencies>
2190 <dep package="util/util-macros"/>
2191 <dep package="proto/xproto"/>
2192 <dep package="xserver/xorg-server"/>
2193 </dependencies>
2194 </metamodule>
2195
2196 <metamodule id="driver-xf86-input-hyperpen">
2197 <dependencies>
2198 <dep package="util/util-macros"/>
2199 <dep package="proto/xproto"/>
2200 <dep package="xserver/xorg-server"/>
2201 </dependencies>
2202 </metamodule>
2203
2204 <metamodule id="driver-xf86-input-jamstudio">
2205 <dependencies>
2206 <dep package="util/util-macros"/>
2207 <dep package="proto/xproto"/>
2208 <dep package="xserver/xorg-server"/>
2209 </dependencies>
2210 </metamodule>
2211
2212 <metamodule id="driver-xf86-input-joystick">
2213 <dependencies>
2214 <dep package="util/util-macros"/>
2215 <dep package="proto/xproto"/>
2216 <dep package="xserver/xorg-server"/>
2217 </dependencies>
2218 </metamodule>
2219
2220 <metamodule id="driver-xf86-input-keyboard">
2221 <dependencies>
2222 <dep package="util/util-macros"/>
2223 <dep package="proto/xproto"/>
2224 <dep package="xserver/xorg-server"/>
2225 </dependencies>
2226 </metamodule>
2227
2228 <metamodule id="driver-xf86-input-magellan">
2229 <dependencies>
2230 <dep package="util/util-macros"/>
2231 <dep package="proto/xproto"/>
2232 <dep package="xserver/xorg-server"/>
2233 </dependencies>
2234 </metamodule>
2235
2236 <metamodule id="driver-xf86-input-magictouch">
2237 <dependencies>
2238 <dep package="util/util-macros"/>
2239 <dep package="proto/xproto"/>
2240 <dep package="xserver/xorg-server"/>
2241 </dependencies>
2242 </metamodule>
2243
2244 <metamodule id="driver-xf86-input-microtouch">
2245 <dependencies>
2246 <dep package="util/util-macros"/>
2247 <dep package="proto/xproto"/>
2248 <dep package="xserver/xorg-server"/>
2249 </dependencies>
2250 </metamodule>
2251
2252 <metamodule id="driver-xf86-input-mouse">
2253 <dependencies>
2254 <dep package="util/util-macros"/>
2255 <dep package="proto/xproto"/>
2256 <dep package="xserver/xorg-server"/>
2257 </dependencies>
2258 </metamodule>
2259
2260 <metamodule id="driver-xf86-input-mutouch">
2261 <dependencies>
2262 <dep package="util/util-macros"/>
2263 <dep package="proto/xproto"/>
2264 <dep package="xserver/xorg-server"/>
2265 </dependencies>
2266 </metamodule>
2267
2268 <metamodule id="driver-xf86-input-palmax">
2269 <dependencies>
2270 <dep package="util/util-macros"/>
2271 <dep package="proto/xproto"/>
2272 <dep package="xserver/xorg-server"/>
2273 </dependencies>
2274 </metamodule>
2275
2276 <metamodule id="driver-xf86-input-penmount">
2277 <dependencies>
2278 <dep package="util/util-macros"/>
2279 <dep package="proto/xproto"/>
2280 <dep package="xserver/xorg-server"/>
2281 </dependencies>
2282 </metamodule>
2283
2284 <metamodule id="driver-xf86-input-spaceorb">
2285 <dependencies>
2286 <dep package="util/util-macros"/>
2287 <dep package="proto/xproto"/>
2288 <dep package="xserver/xorg-server"/>
2289 </dependencies>
2290 </metamodule>
2291
2292 <metamodule id="driver-xf86-input-summa">
2293 <dependencies>
2294 <dep package="util/util-macros"/>
2295 <dep package="proto/xproto"/>
2296 <dep package="xserver/xorg-server"/>
2297 </dependencies>
2298 </metamodule>
2299
2300 <metamodule id="driver-xf86-input-tek4957">
2301 <dependencies>
2302 <dep package="util/util-macros"/>
2303 <dep package="proto/xproto"/>
2304 <dep package="xserver/xorg-server"/>
2305 </dependencies>
2306 </metamodule>
2307
2308 <metamodule id="driver-xf86-input-ur98">
2309 <dependencies>
2310 <dep package="util/util-macros"/>
2311 <dep package="proto/xproto"/>
2312 <dep package="xserver/xorg-server"/>
2313 </dependencies>
2314 </metamodule>
2315
2316 <metamodule id="driver-xf86-input-void">
2317 <dependencies>
2318 <dep package="util/util-macros"/>
2319 <dep package="proto/xproto"/>
2320 <dep package="xserver/xorg-server"/>
2321 </dependencies>
2322 </metamodule>
2323
2324
2325 <!-- video drivers -->
2326
2327 <metamodule id="driver-xf86-video-apm">
2328 <dependencies>
2329 <dep package="util/util-macros"/>
2330 <dep package="proto/xproto"/>
2331 <dep package="xserver/xorg-server"/>
2332 </dependencies>
2333 </metamodule>
2334
2335 <metamodule id="driver-xf86-video-ark">
2336 <dependencies>
2337 <dep package="util/util-macros"/>
2338 <dep package="proto/xproto"/>
2339 <dep package="xserver/xorg-server"/>
2340 </dependencies>
2341 </metamodule>
2342
2343 <metamodule id="driver-xf86-video-ati">
2344 <dependencies>
2345 <dep package="util/util-macros"/>
2346 <dep package="proto/xproto"/>
2347 <dep package="xserver/xorg-server"/>
2348 </dependencies>
2349 </metamodule>
2350
2351 <metamodule id="driver-xf86-video-chips">
2352 <dependencies>
2353 <dep package="util/util-macros"/>
2354 <dep package="proto/xproto"/>
2355 <dep package="xserver/xorg-server"/>
2356 </dependencies>
2357 </metamodule>
2358
2359 <metamodule id="driver-xf86-video-cirrus">
2360 <dependencies>
2361 <dep package="util/util-macros"/>
2362 <dep package="proto/xproto"/>
2363 <dep package="xserver/xorg-server"/>
2364 </dependencies>
2365 </metamodule>
2366
2367 <metamodule id="driver-xf86-video-cyrix">
2368 <dependencies>
2369 <dep package="util/util-macros"/>
2370 <dep package="proto/xproto"/>
2371 <dep package="xserver/xorg-server"/>
2372 </dependencies>
2373 </metamodule>
2374
2375 <metamodule id="driver-xf86-video-dummy">
2376 <dependencies>
2377 <dep package="util/util-macros"/>
2378 <dep package="proto/xproto"/>
2379 <dep package="xserver/xorg-server"/>
2380 </dependencies>
2381 </metamodule>
2382
2383 <metamodule id="driver-xf86-video-fbdev">
2384 <dependencies>
2385 <dep package="util/util-macros"/>
2386 <dep package="proto/xproto"/>
2387 <dep package="xserver/xorg-server"/>
2388 </dependencies>
2389 </metamodule>
2390
2391 <metamodule id="driver-xf86-video-glide">
2392 <dependencies>
2393 <dep package="util/util-macros"/>
2394 <dep package="proto/xproto"/>
2395 <dep package="xserver/xorg-server"/>
2396 </dependencies>
2397 </metamodule>
2398
2399 <metamodule id="driver-xf86-video-glint">
2400 <dependencies>
2401 <dep package="util/util-macros"/>
2402 <dep package="proto/xproto"/>
2403 <dep package="xserver/xorg-server"/>
2404 </dependencies>
2405 </metamodule>
2406
2407 <metamodule id="driver-xf86-video-i128">
2408 <dependencies>
2409 <dep package="util/util-macros"/>
2410 <dep package="proto/xproto"/>
2411 <dep package="xserver/xorg-server"/>
2412 </dependencies>
2413 </metamodule>
2414
2415 <metamodule id="driver-xf86-video-i740">
2416 <dependencies>
2417 <dep package="util/util-macros"/>
2418 <dep package="proto/xproto"/>
2419 <dep package="xserver/xorg-server"/>
2420 </dependencies>
2421 </metamodule>
2422
2423 <metamodule id="driver-xf86-video-i810">
2424 <dependencies>
2425 <dep package="util/util-macros"/>
2426 <dep package="proto/xproto"/>
2427 <dep package="xserver/xorg-server"/>
2428 </dependencies>
2429 </metamodule>
2430
2431 <metamodule id="driver-xf86-video-imstt">
2432 <dependencies>
2433 <dep package="util/util-macros"/>
2434 <dep package="proto/xproto"/>
2435 <dep package="xserver/xorg-server"/>
2436 </dependencies>
2437 </metamodule>
2438
2439 <metamodule id="driver-xf86-video-mga">
2440 <dependencies>
2441 <dep package="util/util-macros"/>
2442 <dep package="proto/xproto"/>
2443 <dep package="xserver/xorg-server"/>
2444 </dependencies>
2445 </metamodule>
2446
2447 <metamodule id="driver-xf86-video-neomagic">
2448 <dependencies>
2449 <dep package="util/util-macros"/>
2450 <dep package="proto/xproto"/>
2451 <dep package="xserver/xorg-server"/>
2452 </dependencies>
2453 </metamodule>
2454
2455 <metamodule id="driver-xf86-video-newport">
2456 <dependencies>
2457 <dep package="util/util-macros"/>
2458 <dep package="proto/xproto"/>
2459 <dep package="xserver/xorg-server"/>
2460 </dependencies>
2461 </metamodule>
2462
2463 <metamodule id="driver-xf86-video-nsc">
2464 <dependencies>
2465 <dep package="util/util-macros"/>
2466 <dep package="proto/xproto"/>
2467 <dep package="xserver/xorg-server"/>
2468 </dependencies>
2469 </metamodule>
2470
2471 <metamodule id="driver-xf86-video-nv">
2472 <dependencies>
2473 <dep package="util/util-macros"/>
2474 <dep package="proto/xproto"/>
2475 <dep package="xserver/xorg-server"/>
2476 </dependencies>
2477 </metamodule>
2478
2479 <metamodule id="driver-xf86-video-rendition">
2480 <dependencies>
2481 <dep package="util/util-macros"/>
2482 <dep package="proto/xproto"/>
2483 <dep package="xserver/xorg-server"/>
2484 </dependencies>
2485 </metamodule>
2486
2487 <metamodule id="driver-xf86-video-s3">
2488 <dependencies>
2489 <dep package="util/util-macros"/>
2490 <dep package="proto/xproto"/>
2491 <dep package="xserver/xorg-server"/>
2492 </dependencies>
2493 </metamodule>
2494
2495 <metamodule id="driver-xf86-video-s3virge">
2496 <dependencies>
2497 <dep package="util/util-macros"/>
2498 <dep package="proto/xproto"/>
2499 <dep package="xserver/xorg-server"/>
2500 </dependencies>
2501 </metamodule>
2502
2503 <metamodule id="driver-xf86-video-savage">
2504 <dependencies>
2505 <dep package="util/util-macros"/>
2506 <dep package="proto/xproto"/>
2507 <dep package="xserver/xorg-server"/>
2508 </dependencies>
2509 </metamodule>
2510
2511 <metamodule id="driver-xf86-video-siliconmotion">
2512 <dependencies>
2513 <dep package="util/util-macros"/>
2514 <dep package="proto/xproto"/>
2515 <dep package="xserver/xorg-server"/>
2516 </dependencies>
2517 </metamodule>
2518
2519 <metamodule id="driver-xf86-video-sis">
2520 <dependencies>
2521 <dep package="util/util-macros"/>
2522 <dep package="proto/xproto"/>
2523 <dep package="xserver/xorg-server"/>
2524 </dependencies>
2525 </metamodule>
2526
2527 <metamodule id="driver-xf86-video-sisusb">
2528 <dependencies>
2529 <dep package="util/util-macros"/>
2530 <dep package="proto/xproto"/>
2531 <dep package="xserver/xorg-server"/>
2532 </dependencies>
2533 </metamodule>
2534
2535 <metamodule id="driver-xf86-video-sunbw2">
2536 <dependencies>
2537 <dep package="util/util-macros"/>
2538 <dep package="proto/xproto"/>
2539 <dep package="xserver/xorg-server"/>
2540 </dependencies>
2541 </metamodule>
2542
2543 <metamodule id="driver-xf86-video-suncg14">
2544 <dependencies>
2545 <dep package="util/util-macros"/>
2546 <dep package="proto/xproto"/>
2547 <dep package="xserver/xorg-server"/>
2548 </dependencies>
2549 </metamodule>
2550
2551 <metamodule id="driver-xf86-video-suncg3">
2552 <dependencies>
2553 <dep package="util/util-macros"/>
2554 <dep package="proto/xproto"/>
2555 <dep package="xserver/xorg-server"/>
2556 </dependencies>
2557 </metamodule>
2558
2559 <metamodule id="driver-xf86-video-suncg6">
2560 <dependencies>
2561 <dep package="util/util-macros"/>
2562 <dep package="proto/xproto"/>
2563 <dep package="xserver/xorg-server"/>
2564 </dependencies>
2565 </metamodule>
2566
2567 <metamodule id="driver-xf86-video-sunffb">
2568 <dependencies>
2569 <dep package="util/util-macros"/>
2570 <dep package="proto/xproto"/>
2571 <dep package="xserver/xorg-server"/>
2572 </dependencies>
2573 </metamodule>
2574
2575 <metamodule id="driver-xf86-video-sunleo">
2576 <dependencies>
2577 <dep package="util/util-macros"/>
2578 <dep package="proto/xproto"/>
2579 <dep package="xserver/xorg-server"/>
2580 </dependencies>
2581 </metamodule>
2582
2583 <metamodule id="driver-xf86-video-suntcx">
2584 <dependencies>
2585 <dep package="util/util-macros"/>
2586 <dep package="proto/xproto"/>
2587 <dep package="xserver/xorg-server"/>
2588 </dependencies>
2589 </metamodule>
2590
2591 <metamodule id="driver-xf86-video-tdfx">
2592 <dependencies>
2593 <dep package="util/util-macros"/>
2594 <dep package="proto/xproto"/>
2595 <dep package="xserver/xorg-server"/>
2596 </dependencies>
2597 </metamodule>
2598
2599 <metamodule id="driver-xf86-video-tga">
2600 <dependencies>
2601 <dep package="util/util-macros"/>
2602 <dep package="proto/xproto"/>
2603 <dep package="xserver/xorg-server"/>
2604 </dependencies>
2605 </metamodule>
2606
2607 <metamodule id="driver-xf86-video-trident">
2608 <dependencies>
2609 <dep package="util/util-macros"/>
2610 <dep package="proto/xproto"/>
2611 <dep package="xserver/xorg-server"/>
2612 </dependencies>
2613 </metamodule>
2614
2615 <metamodule id="driver-xf86-video-tseng">
2616 <dependencies>
2617 <dep package="util/util-macros"/>
2618 <dep package="proto/xproto"/>
2619 <dep package="xserver/xorg-server"/>
2620 </dependencies>
2621 </metamodule>
2622
2623 <metamodule id="driver-xf86-video-v4l">
2624 <dependencies>
2625 <dep package="util/util-macros"/>
2626 <dep package="proto/xproto"/>
2627 <dep package="xserver/xorg-server"/>
2628 </dependencies>
2629 </metamodule>
2630
2631 <metamodule id="driver-xf86-video-vesa">
2632 <dependencies>
2633 <dep package="util/util-macros"/>
2634 <dep package="proto/xproto"/>
2635 <dep package="xserver/xorg-server"/>
2636 </dependencies>
2637 </metamodule>
2638
2639 <metamodule id="driver-xf86-video-vga">
2640 <dependencies>
2641 <dep package="util/util-macros"/>
2642 <dep package="proto/xproto"/>
2643 <dep package="xserver/xorg-server"/>
2644 </dependencies>
2645 </metamodule>
2646
2647 <metamodule id="driver-xf86-video-via">
2648 <dependencies>
2649 <dep package="util/util-macros"/>
2650 <dep package="proto/xproto"/>
2651 <dep package="xserver/xorg-server"/>
2652 <dep package="drm"/>
2653 </dependencies>
2654 </metamodule>
2655
2656 <metamodule id="driver-xf86-video-vmware">
2657 <dependencies>
2658 <dep package="util/util-macros"/>
2659 <dep package="proto/xproto"/>
2660 <dep package="xserver/xorg-server"/>
2661 </dependencies>
2662 </metamodule>
2663
2664 <metamodule id="driver-xf86-video-voodoo">
2665 <dependencies>
2666 <dep package="util/util-macros"/>
2667 <dep package="proto/xproto"/>
2668 <dep package="xserver/xorg-server"/>
2669 </dependencies>
2670 </metamodule>
2671
2672 <metamodule id="driver-xf86-video-wsfb">
2673 <dependencies>
2674 <dep package="util/util-macros"/>
2675 <dep package="proto/xproto"/>
2676 <dep package="xserver/xorg-server"/>
2677 </dependencies>
2678 </metamodule>
2679
2680 <metamodule id="driver-input">
2681 <dependencies>
2682 <dep package="driver/xf86-input-acecad"/>
2683 <dep package="driver/xf86-input-aiptek"/>
2684 <dep package="driver/xf86-input-calcomp"/>
2685 <dep package="driver/xf86-input-citron"/>
2686 <dep package="driver/xf86-input-digitaledge"/>
2687 <dep package="driver/xf86-input-dmc"/>
2688 <dep package="driver/xf86-input-dynapro"/>
2689 <dep package="driver/xf86-input-elo2300"/>
2690 <dep package="driver/xf86-input-elographics"/>
2691 <dep package="driver/xf86-input-evdev"/>
2692 <dep package="driver/xf86-input-fpit"/>
2693 <dep package="driver/xf86-input-hyperpen"/>
2694 <dep package="driver/xf86-input-jamstudio"/>
2695 <dep package="driver/xf86-input-joystick"/>
2696 <dep package="driver/xf86-input-keyboard"/>
2697 <dep package="driver/xf86-input-magellan"/>
2698 <dep package="driver/xf86-input-magictouch"/>
2699 <dep package="driver/xf86-input-microtouch"/>
2700 <dep package="driver/xf86-input-mouse"/>
2701 <dep package="driver/xf86-input-mutouch"/>
2702 <dep package="driver/xf86-input-palmax"/>
2703 <dep package="driver/xf86-input-penmount"/>
2704 <dep package="driver/xf86-input-spaceorb"/>
2705 <dep package="driver/xf86-input-summa"/>
2706 <dep package="driver/xf86-input-tek4957"/>
2707 <!-- <dep package="driver/xf86-input-ur98"/> -->
2708 <dep package="driver/xf86-input-void"/>
2709 </dependencies>
2710 </metamodule>
2711
2712 <metamodule id="driver-video">
2713 <dependencies>
2714 <dep package="driver/xf86-video-apm"/>
2715 <dep package="driver/xf86-video-ark"/>
2716 <dep package="driver/xf86-video-ati"/>
2717 <dep package="driver/xf86-video-chips"/>
2718 <dep package="driver/xf86-video-cirrus"/>
2719 <dep package="driver/xf86-video-cyrix"/>
2720 <dep package="driver/xf86-video-dummy"/>
2721 <dep package="driver/xf86-video-fbdev"/>
2722 <!-- <dep package="driver/xf86-video-glide"/> -->
2723 <dep package="driver/xf86-video-glint"/>
2724 <dep package="driver/xf86-video-i128"/>
2725 <dep package="driver/xf86-video-i740"/>
2726 <dep package="driver/xf86-video-i810"/>
2727 <dep package="driver/xf86-video-imstt"/>
2728 <dep package="driver/xf86-video-mga"/>
2729 <dep package="driver/xf86-video-neomagic"/>
2730 <dep package="driver/xf86-video-newport"/>
2731 <dep package="driver/xf86-video-nsc"/>
2732 <dep package="driver/xf86-video-nv"/>
2733 <dep package="driver/xf86-video-rendition"/>
2734 <dep package="driver/xf86-video-s3"/>
2735 <dep package="driver/xf86-video-s3virge"/>
2736 <dep package="driver/xf86-video-savage"/>
2737 <dep package="driver/xf86-video-siliconmotion"/>
2738 <dep package="driver/xf86-video-sis"/>
2739 <dep package="driver/xf86-video-sisusb"/> <!-- Linux only -->
2740 <dep package="driver/xf86-video-sunbw2"/>
2741 <dep package="driver/xf86-video-suncg14"/>
2742 <dep package="driver/xf86-video-suncg3"/>
2743 <dep package="driver/xf86-video-suncg6"/>
2744 <dep package="driver/xf86-video-sunffb"/>
2745 <dep package="driver/xf86-video-sunleo"/>
2746 <dep package="driver/xf86-video-suntcx"/>
2747 <dep package="driver/xf86-video-tdfx"/>
2748 <dep package="driver/xf86-video-tga"/>
2749 <dep package="driver/xf86-video-trident"/>
2750 <dep package="driver/xf86-video-tseng"/>
2751 <dep package="driver/xf86-video-v4l"/> <!-- Linux only -->
2752 <dep package="driver/xf86-video-vesa"/>
2753 <dep package="driver/xf86-video-vga"/>
2754 <dep package="driver/xf86-video-via"/>
2755 <dep package="driver/xf86-video-vmware"/>
2756 <dep package="driver/xf86-video-voodoo"/>
2757 </dependencies>
2758 </metamodule>
2759
2760 <metamodule id="driver-sun">
2761 <dependencies>
2762 <dep package="driver/xf86-video-wsfb"/>
2763 </dependencies>
2764 </metamodule>
2765
2766 <metamodule id="driver">
2767 <dependencies>
2768 <dep package="driver-input"/>
2769 <dep package="driver-video"/>
2770 </dependencies>
2771 </metamodule>
2772
2773
2774 <!-- X servers -->
2775
2776 <!-- TODO: Lots more work is needed here for deps -->
2777 <metamodule id="xserver-xorg-server">
2778 <dependencies>
2779 <dep package="util/util-macros"/>
2780 <dep package="proto"/>
2781 <dep package="lib/libXaw"/>
2782 <dep package="lib/libxkbui"/>
2783 <dep package="lib/libXfont"/>
2784 <dep package="lib/xtrans"/>
2785 <dep package="lib/libXau"/>
2786 <dep package="lib/libxkbfile"/>
2787 <dep package="lib/libXdmcp"/>
2788 <dep package="lib/libXxf86misc"/>
2789 <dep package="lib/libXxf86vm"/>
2790 <dep package="drm"/>
2791 </dependencies>
2792 </metamodule>
2793
2794 <metamodule id="xserver">
2795 <dependencies>
2796 <dep package="xserver/xorg-server"/>
2797 </dependencies>
2798 </metamodule>
2799
2800
2801 <!-- everything -->
2802
2803 <!-- Note that data and utils are brought in from dependencies -->
2804 <metamodule id="xorg">
2805 <dependencies>
2806 <dep package="doc"/>
2807 <dep package="proto"/>
2808 <dep package="lib"/>
2809 <dep package="app"/>
2810 <dep package="xserver"/>
2811 <dep package="driver"/>
2812 <dep package="data"/>
2813 <dep package="font"/>
2814 <dep package="util"/>
2815 </dependencies>
2816 </metamodule>
2817
2818
2819 <!-- Extras -->
2820
2821 <tarball id="freetype2" version="2.1.9">
2822 <source href="http://ftp.x.org/pub/X11R7.0/src/extras/freetype-2.1.9.tar.gz"
2823 size="1334560" md5sum="1336a6851753c962495ff02ff7ea71c1"/>
2824 </tarball>
2825 <tarball id="fontconfig" version="2.2.3">
2826 <source href="http://ftp.x.org/pub/X11R7.0/src/extras/fontconfig-2.2.3.tar.gz"
2827 size="750035" md5sum="2466a797d645cda5eb466080fdaec416"/>
2828 </tarball>
2829 <tarball id="drm" version="2.0">
2830 <source href="http://ftp.x.org/pub/X11R7.0/src/extras/libdrm-2.0.tar.gz"
2831 size="370965" md5sum="9d1aab104eb757ceeb2c1a6d38d57411"/>
2832 </tarball>
2833
2834
2835 <!-- Tarball set for X11R7-RC4 -->
2836
2837 <tarball id="app/appres" version="X11R7.0-1.0.0">
2838 <source href="http://ftp.x.org/pub/X11R7.0/src/app/appres-X11R7.0-1.0.0.tar.bz2"
2839 size="74597" md5sum="3327357fc851a49e8e5dc44405e7b862"/>
2840 <dependencies>
2841 <dep package="app-appres"/>
2842 </dependencies>
2843 </tarball>
2844 <tarball id="app/bdftopcf" version="X11R7.0-1.0.0">
2845 <source href="http://ftp.x.org/pub/X11R7.0/src/app/bdftopcf-X11R7.0-1.0.0.tar.bz2"
2846 size="74661" md5sum="f43667fcf613054cae0679f5dc5a1e7a"/>
2847 <dependencies>
2848 <dep package="app-bdftopcf"/>
2849 </dependencies>
2850 </tarball>
2851 <tarball id="app/beforelight" version="X11R7.0-1.0.1">
2852 <source href="http://ftp.x.org/pub/X11R7.0/src/app/beforelight-X11R7.0-1.0.1.tar.bz2"
2853 size="77142" md5sum="e0326eff9d1bd4e3a1af9e615a0048b3"/>
2854 <dependencies>
2855 <dep package="app-beforelight"/>
2856 </dependencies>
2857 </tarball>
2858 <tarball id="app/bitmap" version="X11R7.0-1.0.1">
2859 <source href="http://ftp.x.org/pub/X11R7.0/src/app/bitmap-X11R7.0-1.0.1.tar.bz2"
2860 size="117790" md5sum="bbb3df097821d3edb4d5a4b2ae731de6"/>
2861 <dependencies>
2862 <dep package="app-bitmap"/>
2863 </dependencies>
2864 </tarball>
2865 <tarball id="app/editres" version="X11R7.0-1.0.1">
2866 <source href="http://ftp.x.org/pub/X11R7.0/src/app/editres-X11R7.0-1.0.1.tar.bz2"
2867 size="115967" md5sum="a9dc7f3b0cb59f08ab1e6554a5e60721"/>
2868 <dependencies>
2869 <dep package="app-editres"/>
2870 </dependencies>
2871 </tarball>
2872 <tarball id="app/fonttosfnt" version="X11R7.0-1.0.1">
2873 <source href="http://ftp.x.org/pub/X11R7.0/src/app/fonttosfnt-X11R7.0-1.0.1.tar.bz2"
2874 size="90512" md5sum="89b65e010acaa3c5d370e1cc0ea9fce9"/>
2875 <dependencies>
2876 <dep package="app-fonttosfnt"/>
2877 </dependencies>
2878 </tarball>
2879 <tarball id="app/fslsfonts" version="X11R7.0-1.0.1">
2880 <source href="http://ftp.x.org/pub/X11R7.0/src/app/fslsfonts-X11R7.0-1.0.1.tar.bz2"
2881 size="76899" md5sum="c500b96cfec485e362204a8fc0bdfd44"/>
2882 <dependencies>
2883 <dep package="app-fslsfonts"/>
2884 </dependencies>
2885 </tarball>
2886 <tarball id="app/fstobdf" version="X11R7.0-1.0.1">
2887 <source href="http://ftp.x.org/pub/X11R7.0/src/app/fstobdf-X11R7.0-1.0.1.tar.bz2"
2888 size="78666" md5sum="233615dca862b64c69bc212090a22b4c"/>
2889 <dependencies>
2890 <dep package="app-fstobdf"/>
2891 </dependencies>
2892 </tarball>
2893 <tarball id="app/iceauth" version="X11R7.0-1.0.1">
2894 <source href="http://ftp.x.org/pub/X11R7.0/src/app/iceauth-X11R7.0-1.0.1.tar.bz2"
2895 size="84372" md5sum="92035bd69b4c9aba47607ba0efcc8530"/>
2896 <dependencies>
2897 <dep package="app-iceauth"/>
2898 </dependencies>
2899 </tarball>
2900 <tarball id="app/ico" version="X11R7.0-1.0.1">
2901 <source href="http://ftp.x.org/pub/X11R7.0/src/app/ico-X11R7.0-1.0.1.tar.bz2"
2902 size="85686" md5sum="9c63d68a779819ba79e45d9b15d26b1f"/>
2903 <dependencies>
2904 <dep package="app-ico"/>
2905 </dependencies>
2906 </tarball>
2907 <tarball id="app/lbxproxy" version="X11R7.0-1.0.1">
2908 <source href="http://ftp.x.org/pub/X11R7.0/src/app/lbxproxy-X11R7.0-1.0.1.tar.bz2"
2909 size="179860" md5sum="d9c05283660eae742a77dcbc0091841a"/>
2910 <dependencies>
2911 <dep package="app-lbxproxy"/>
2912 </dependencies>
2913 </tarball>
2914 <tarball id="app/listres" version="X11R7.0-1.0.1">
2915 <source href="http://ftp.x.org/pub/X11R7.0/src/app/listres-X11R7.0-1.0.1.tar.bz2"
2916 size="76647" md5sum="2eeb802272a7910bb8a52b308bf0d5f6"/>
2917 <dependencies>
2918 <dep package="app-listres"/>
2919 </dependencies>
2920 </tarball>
2921 <tarball id="app/luit" version="X11R7.0-1.0.1">
2922 <source href="http://ftp.x.org/pub/X11R7.0/src/app/luit-X11R7.0-1.0.1.tar.bz2"
2923 size="92017" md5sum="30428b8ff783a0cfd61dab05a17cfaa7"/>
2924 <dependencies>
2925 <dep package="app-luit"/>
2926 </dependencies>
2927 </tarball>
2928 <tarball id="app/mkcfm" version="X11R7.0-1.0.1">
2929 <source href="http://ftp.x.org/pub/X11R7.0/src/app/mkcfm-X11R7.0-1.0.1.tar.bz2"
2930 size="75940" md5sum="912e6305998441c26852309403742bec"/>
2931 <dependencies>
2932 <dep package="app-mkcfm"/>
2933 </dependencies>
2934 </tarball>
2935 <tarball id="app/mkfontdir" version="X11R7.0-1.0.1">
2936 <source href="http://ftp.x.org/pub/X11R7.0/src/app/mkfontdir-X11R7.0-1.0.1.tar.bz2"
2937 size="60892" md5sum="29e6e5e8e7a29ed49abf33af192693cb"/>
2938 <dependencies>
2939 <dep package="app-mkfontdir"/>
2940 </dependencies>
2941 </tarball>
2942 <tarball id="app/mkfontscale" version="X11R7.0-1.0.1">
2943 <source href="http://ftp.x.org/pub/X11R7.0/src/app/mkfontscale-X11R7.0-1.0.1.tar.bz2"
2944 size="87485" md5sum="75bbd1dc425849e415a60afd9e74d2ff"/>
2945 <dependencies>
2946 <dep package="app-mkfontscale"/>
2947 </dependencies>
2948 </tarball>
2949 <tarball id="app/oclock" version="X11R7.0-1.0.1">
2950 <source href="http://ftp.x.org/pub/X11R7.0/src/app/oclock-X11R7.0-1.0.1.tar.bz2"
2951 size="83165" md5sum="e35af9699c49f0b77fad45a3b942c3b1"/>
2952 <dependencies>
2953 <dep package="app-oclock"/>
2954 </dependencies>
2955 </tarball>
2956 <tarball id="app/proxymngr" version="X11R7.0-1.0.1">
2957 <source href="http://ftp.x.org/pub/X11R7.0/src/app/proxymngr-X11R7.0-1.0.1.tar.bz2"
2958 size="91718" md5sum="0d2ca6876d84302f966fd105a3b69a8e"/>
2959 <dependencies>
2960 <dep package="app-proxymngr"/>
2961 </dependencies>
2962 </tarball>
2963 <tarball id="app/rgb" version="X11R7.0-1.0.0">
2964 <source href="http://ftp.x.org/pub/X11R7.0/src/app/rgb-X11R7.0-1.0.0.tar.bz2"
2965 size="87271" md5sum="675e72f221714c3db8730daf0b50f69f"/>
2966 <dependencies>
2967 <dep package="app-rgb"/>
2968 </dependencies>
2969 </tarball>
2970 <tarball id="app/rstart" version="X11R7.0-1.0.1">
2971 <source href="http://ftp.x.org/pub/X11R7.0/src/app/rstart-X11R7.0-1.0.1.tar.bz2"
2972 size="88773" md5sum="6f33a1bd8e99372b7544ddfcad456369"/>
2973 <dependencies>
2974 <dep package="app-rstart"/>
2975 </dependencies>
2976 </tarball>
2977 <tarball id="app/scripts" version="X11R7.0-1.0.1">
2978 <source href="http://ftp.x.org/pub/X11R7.0/src/app/scripts-X11R7.0-1.0.1.tar.bz2"
2979 size="72337" md5sum="b5b43aa53372b78f1d67c86301e3dc02"/>
2980 <dependencies>
2981 <dep package="app-scripts"/>
2982 </dependencies>
2983 </tarball>
2984 <tarball id="app/sessreg" version="X11R7.0-1.0.0">
2985 <source href="http://ftp.x.org/pub/X11R7.0/src/app/sessreg-X11R7.0-1.0.0.tar.bz2"
2986 size="82144" md5sum="8289a5b947165449c23bdfad9af02b4c"/>
2987 <dependencies>
2988 <dep package="app-sessreg"/>
2989 </dependencies>
2990 </tarball>
2991 <tarball id="app/setxkbmap" version="X11R7.0-1.0.1">
2992 <source href="http://ftp.x.org/pub/X11R7.0/src/app/setxkbmap-X11R7.0-1.0.1.tar.bz2"
2993 size="80162" md5sum="28b141ab0b1c44a5e90d31ad73bd1078"/>
2994 <dependencies>
2995 <dep package="app-setxkbmap"/>
2996 </dependencies>
2997 </tarball>
2998 <tarball id="app/showfont" version="X11R7.0-1.0.1">
2999 <source href="http://ftp.x.org/pub/X11R7.0/src/app/showfont-X11R7.0-1.0.1.tar.bz2"
3000 size="76966" md5sum="334cb5133960108ac2c24ee27e16bb8e"/>
3001 <dependencies>
3002 <dep package="app-showfont"/>
3003 </dependencies>
3004 </tarball>
3005 <tarball id="app/smproxy" version="X11R7.0-1.0.1">
3006 <source href="http://ftp.x.org/pub/X11R7.0/src/app/smproxy-X11R7.0-1.0.1.tar.bz2"
3007 size="82934" md5sum="60f54881b6fb27a8ba238629e4097c4d"/>
3008 <dependencies>
3009 <dep package="app-smproxy"/>
3010 </dependencies>
3011 </tarball>
3012 <tarball id="app/twm" version="X11R7.0-1.0.1">
3013 <source href="http://ftp.x.org/pub/X11R7.0/src/app/twm-X11R7.0-1.0.1.tar.bz2"
3014 size="220067" md5sum="cd525ca3ac5e29d21a61deebc1e0c376"/>
3015 <dependencies>
3016 <dep package="app-twm"/>
3017 </dependencies>
3018 </tarball>
3019 <tarball id="app/viewres" version="X11R7.0-1.0.1">
3020 <source href="http://ftp.x.org/pub/X11R7.0/src/app/viewres-X11R7.0-1.0.1.tar.bz2"
3021 size="84830" md5sum="004bf8dd4646aca86faf5aa22b0c3f2f"/>
3022 <dependencies>
3023 <dep package="app-viewres"/>
3024 </dependencies>
3025 </tarball>
3026 <tarball id="app/x11perf" version="X11R7.0-1.0.1">
3027 <source href="http://ftp.x.org/pub/X11R7.0/src/app/x11perf-X11R7.0-1.0.1.tar.bz2"
3028 size="127363" md5sum="9986b20301c6a37bb144cb9733bf35a0"/>
3029 <dependencies>
3030 <dep package="app-x11perf"/>
3031 </dependencies>
3032 </tarball>
3033 <tarball id="app/xauth" version="X11R7.0-1.0.1">
3034 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xauth-X11R7.0-1.0.1.tar.bz2"
3035 size="95898" md5sum="ef2359ddaaea6ffaf9072fa342d6eb09"/>
3036 <dependencies>
3037 <dep package="app-xauth"/>
3038 </dependencies>
3039 </tarball>
3040 <tarball id="app/xbiff" version="X11R7.0-1.0.1">
3041 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xbiff-X11R7.0-1.0.1.tar.bz2"
3042 size="83656" md5sum="c4eb71a3187586d02365a67fc1445e54"/>
3043 <dependencies>
3044 <dep package="app-xbiff"/>
3045 </dependencies>
3046 </tarball>
3047 <tarball id="app/xcalc" version="X11R7.0-1.0.1">
3048 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xcalc-X11R7.0-1.0.1.tar.bz2"
3049 size="93681" md5sum="c1ecea85be15f746a59931e288768bdb"/>
3050 <dependencies>
3051 <dep package="app-xcalc"/>
3052 </dependencies>
3053 </tarball>
3054 <tarball id="app/xclipboard" version="X11R7.0-1.0.1">
3055 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xclipboard-X11R7.0-1.0.1.tar.bz2"
3056 size="83692" md5sum="a661b0f922cbdc62514bfd3e700d00fd"/>
3057 <dependencies>
3058 <dep package="app-xclipboard"/>
3059 </dependencies>
3060 </tarball>
3061 <tarball id="app/xclock" version="X11R7.0-1.0.1">
3062 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xclock-X11R7.0-1.0.1.tar.bz2"
3063 size="100013" md5sum="00444fed4bf5cd51624476ee11dd1fab"/>
3064 <dependencies>
3065 <dep package="app-xclock"/>
3066 </dependencies>
3067 </tarball>
3068 <tarball id="app/xcmsdb" version="X11R7.0-1.0.1">
3069 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xcmsdb-X11R7.0-1.0.1.tar.bz2"
3070 size="96468" md5sum="1c8396ed5c416e3a6658394ff6c415ad"/>
3071 <dependencies>
3072 <dep package="app-xcmsdb"/>
3073 </dependencies>
3074 </tarball>
3075 <tarball id="app/xconsole" version="X11R7.0-1.0.1">
3076 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xconsole-X11R7.0-1.0.1.tar.bz2"
3077 size="82259" md5sum="f983b589ba9de198d90abee220a80f81"/>
3078 <dependencies>
3079 <dep package="app-xconsole"/>
3080 </dependencies>
3081 </tarball>
3082 <tarball id="app/xcursorgen" version="X11R7.0-1.0.0">
3083 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xcursorgen-X11R7.0-1.0.0.tar.bz2"
3084 size="78039" md5sum="4d7b26dbb4442e89ec65c4147b31a5f7"/>
3085 <dependencies>
3086 <dep package="app-xcursorgen"/>
3087 </dependencies>
3088 </tarball>
3089 <tarball id="app/xdbedizzy" version="X11R7.0-1.0.1">
3090 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xdbedizzy-X11R7.0-1.0.1.tar.bz2"
3091 size="83105" md5sum="ceaccde801650ffbffc1e5b0657960d2"/>
3092 <dependencies>
3093 <dep package="app-xdbedizzy"/>
3094 </dependencies>
3095 </tarball>
3096 <tarball id="app/xditview" version="X11R7.0-1.0.1">
3097 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xditview-X11R7.0-1.0.1.tar.bz2"
3098 size="103002" md5sum="21887fe4ec1965d637e82b7840650a6f"/>
3099 <dependencies>
3100 <dep package="app-xditview"/>
3101 </dependencies>
3102 </tarball>
3103 <tarball id="app/xdm" version="X11R7.0-1.0.1">
3104 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xdm-X11R7.0-1.0.1.tar.bz2"
3105 size="333977" md5sum="9ac363721dbb8cd39aa1064b260624a6"/>
3106 <dependencies>
3107 <dep package="app-xdm"/>
3108 </dependencies>
3109 </tarball>
3110 <tarball id="app/xdpyinfo" version="X11R7.0-1.0.1">
3111 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xdpyinfo-X11R7.0-1.0.1.tar.bz2"
3112 size="87616" md5sum="2b08e9ca783e3aa91d7fb84fdd716e93"/>
3113 <dependencies>
3114 <dep package="app-xdpyinfo"/>
3115 </dependencies>
3116 </tarball>
3117 <tarball id="app/xdriinfo" version="X11R7.0-1.0.0">
3118 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xdriinfo-X11R7.0-1.0.0.tar.bz2"
3119 size="77365" md5sum="75b8b53e29bb295f7fbae7909e0e9770"/>
3120 <dependencies>
3121 <dep package="app-xdriinfo"/>
3122 </dependencies>
3123 </tarball>
3124 <tarball id="app/xedit" version="X11R7.0-1.0.1">
3125 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xedit-X11R7.0-1.0.1.tar.bz2"
3126 size="440739" md5sum="19f607d033f62fb1ee5965f4236b19d4"/>
3127 <dependencies>
3128 <dep package="app-xedit"/>
3129 </dependencies>
3130 </tarball>
3131 <tarball id="app/xev" version="X11R7.0-1.0.1">
3132 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xev-X11R7.0-1.0.1.tar.bz2"
3133 size="79852" md5sum="5d0d3c13b03e9516eafe536e6bd756c7"/>
3134 <dependencies>
3135 <dep package="app-xev"/>
3136 </dependencies>
3137 </tarball>
3138 <tarball id="app/xeyes" version="X11R7.0-1.0.1">
3139 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xeyes-X11R7.0-1.0.1.tar.bz2"
3140 size="81054" md5sum="3ffafa7f222ea799bcd9fcd85c60ab98"/>
3141 <dependencies>
3142 <dep package="app-xeyes"/>
3143 </dependencies>
3144 </tarball>
3145 <tarball id="app/xf86dga" version="X11R7.0-1.0.1">
3146 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xf86dga-X11R7.0-1.0.1.tar.bz2"
3147 size="75128" md5sum="f518fd7ebef3d9e8dbaa57e50a3e2631"/>
3148 <dependencies>
3149 <dep package="app-xf86dga"/>
3150 </dependencies>
3151 </tarball>
3152 <tarball id="app/xfd" version="X11R7.0-1.0.1">
3153 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfd-X11R7.0-1.0.1.tar.bz2"
3154 size="88900" md5sum="26c83a6fe245906cc05055abf877d0f2"/>
3155 <dependencies>
3156 <dep package="app-xfd"/>
3157 </dependencies>
3158 </tarball>
3159 <tarball id="app/xfindproxy" version="X11R7.0-1.0.1">
3160 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfindproxy-X11R7.0-1.0.1.tar.bz2"
3161 size="77638" md5sum="5ef22b8876bb452f670e0fc425a12504"/>
3162 <dependencies>
3163 <dep package="app-xfindproxy"/>
3164 </dependencies>
3165 </tarball>
3166 <tarball id="app/xfontsel" version="X11R7.0-1.0.1">
3167 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfontsel-X11R7.0-1.0.1.tar.bz2"
3168 size="95794" md5sum="d1df7b8622b7f8ebca4b2463118d7073"/>
3169 <dependencies>
3170 <dep package="app-xfontsel"/>
3171 </dependencies>
3172 </tarball>
3173 <tarball id="app/xfsinfo" version="X11R7.0-1.0.1">
3174 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfsinfo-X11R7.0-1.0.1.tar.bz2"
3175 size="74357" md5sum="55ca0cfd09b1c1555d492d6961d9af46"/>
3176 <dependencies>
3177 <dep package="app-xfsinfo"/>
3178 </dependencies>
3179 </tarball>
3180 <tarball id="app/xfs" version="X11R7.0-1.0.1">
3181 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfs-X11R7.0-1.0.1.tar.bz2"
3182 size="141138" md5sum="a297da3d906110e9c29ec56c5ea578a8"/>
3183 <dependencies>
3184 <dep package="app-xfs"/>
3185 </dependencies>
3186 </tarball>
3187 <tarball id="app/xfwp" version="X11R7.0-1.0.1">
3188 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xfwp-X11R7.0-1.0.1.tar.bz2"
3189 size="104581" md5sum="e1ef3fef10d1f7fbd936794982a8f0be"/>
3190 <dependencies>
3191 <dep package="app-xfwp"/>
3192 </dependencies>
3193 </tarball>
3194 <tarball id="app/xgamma" version="X11R7.0-1.0.1">
3195 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xgamma-X11R7.0-1.0.1.tar.bz2"
3196 size="74972" md5sum="07167da3f6b21985e27174ec70f213c0"/>
3197 <dependencies>
3198 <dep package="app-xgamma"/>
3199 </dependencies>
3200 </tarball>
3201 <tarball id="app/xgc" version="X11R7.0-1.0.1">
3202 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xgc-X11R7.0-1.0.1.tar.bz2"
3203 size="128835" md5sum="8cd01cf558c3eed738115abcf720277d"/>
3204 <dependencies>
3205 <dep package="app-xgc"/>
3206 </dependencies>
3207 </tarball>
3208 <tarball id="app/xhost" version="X11R7.0-1.0.0">
3209 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xhost-X11R7.0-1.0.0.tar.bz2"
3210 size="85776" md5sum="76c44e84aaf4ad8e97cf15f4dbe4a24a"/>
3211 <dependencies>
3212 <dep package="app-xhost"/>
3213 </dependencies>
3214 </tarball>
3215 <tarball id="app/xinit" version="X11R7.0-1.0.1">
3216 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xinit-X11R7.0-1.0.1.tar.bz2"
3217 size="92299" md5sum="6d2df59fa328cbc99c0de98bc2e14597"/>
3218 <dependencies>
3219 <dep package="app-xinit"/>
3220 </dependencies>
3221 </tarball>
3222 <tarball id="app/xkbcomp" version="X11R7.0-1.0.1">
3223 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xkbcomp-X11R7.0-1.0.1.tar.bz2"
3224 size="179839" md5sum="46d1e015897200d4dfed64990abaa8b9"/>
3225 <dependencies>
3226 <dep package="app-xkbcomp"/>
3227 </dependencies>
3228 </tarball>
3229 <tarball id="app/xkbevd" version="X11R7.0-1.0.1">
3230 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xkbevd-X11R7.0-1.0.1.tar.bz2"
3231 size="102145" md5sum="7ba0496f079552d1918d73bd09bde9b2"/>
3232 <dependencies>
3233 <dep package="app-xkbevd"/>
3234 </dependencies>
3235 </tarball>
3236 <tarball id="app/xkbprint" version="X11R7.0-1.0.1">
3237 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xkbprint-X11R7.0-1.0.1.tar.bz2"
3238 size="115152" md5sum="6235c39690968d0a9a4c1b1c16c8905a"/>
3239 <dependencies>
3240 <dep package="app-xkbprint"/>
3241 </dependencies>
3242 </tarball>
3243 <tarball id="app/xkbutils" version="X11R7.0-1.0.1">
3244 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xkbutils-X11R7.0-1.0.1.tar.bz2"
3245 size="65684" md5sum="798502eca0c6c3e8c02d76fabb910532"/>
3246 <dependencies>
3247 <dep package="app-xkbutils"/>
3248 </dependencies>
3249 </tarball>
3250 <tarball id="app/xkill" version="X11R7.0-1.0.1">
3251 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xkill-X11R7.0-1.0.1.tar.bz2"
3252 size="77135" md5sum="35f47fd58d75c1ea5f414b21a10bdbf3"/>
3253 <dependencies>
3254 <dep package="app-xkill"/>
3255 </dependencies>
3256 </tarball>
3257 <tarball id="app/xload" version="X11R7.0-1.0.1">
3258 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xload-X11R7.0-1.0.1.tar.bz2"
3259 size="87441" md5sum="11080456822146ebc0118b15f4b911d9"/>
3260 <dependencies>
3261 <dep package="app-xload"/>
3262 </dependencies>
3263 </tarball>
3264 <tarball id="app/xlogo" version="X11R7.0-1.0.1">
3265 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xlogo-X11R7.0-1.0.1.tar.bz2"
3266 size="87040" md5sum="0314b2f5173da64957031400638fa5f8"/>
3267 <dependencies>
3268 <dep package="app-xlogo"/>
3269 </dependencies>
3270 </tarball>
3271 <tarball id="app/xlsatoms" version="X11R7.0-1.0.1">
3272 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xlsatoms-X11R7.0-1.0.1.tar.bz2"
3273 size="74840" md5sum="737b4d7893aa886e8e4181c94380a421"/>
3274 <dependencies>
3275 <dep package="app-xlsatoms"/>
3276 </dependencies>
3277 </tarball>
3278 <tarball id="app/xlsclients" version="X11R7.0-1.0.1">
3279 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xlsclients-X11R7.0-1.0.1.tar.bz2"
3280 size="75661" md5sum="cc0d64e90eab0b90b38355e841824588"/>
3281 <dependencies>
3282 <dep package="app-xlsclients"/>
3283 </dependencies>
3284 </tarball>
3285 <tarball id="app/xlsfonts" version="X11R7.0-1.0.1">
3286 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xlsfonts-X11R7.0-1.0.1.tar.bz2"
3287 size="87658" md5sum="e8681e5671e7f01922ce6c8f2327e602"/>
3288 <dependencies>
3289 <dep package="app-xlsfonts"/>
3290 </dependencies>
3291 </tarball>
3292 <tarball id="app/xmag" version="X11R7.0-1.0.1">
3293 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xmag-X11R7.0-1.0.1.tar.bz2"
3294 size="93663" md5sum="38ac487ac1b75be0253fe7f973947386"/>
3295 <dependencies>
3296 <dep package="app-xmag"/>
3297 </dependencies>
3298 </tarball>
3299 <tarball id="app/xman" version="X11R7.0-1.0.1">
3300 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xman-X11R7.0-1.0.1.tar.bz2"
3301 size="134005" md5sum="a4f21547120952aeb8e5663ebd72e843"/>
3302 <dependencies>
3303 <dep package="app-xman"/>
3304 </dependencies>
3305 </tarball>
3306 <tarball id="app/xmessage" version="X11R7.0-1.0.1">
3307 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xmessage-X11R7.0-1.0.1.tar.bz2"
3308 size="83378" md5sum="5a17607184fd348c2b36b5499ae9d2e6"/>
3309 <dependencies>
3310 <dep package="app-xmessage"/>
3311 </dependencies>
3312 </tarball>
3313 <tarball id="app/xmh" version="X11R7.0-1.0.1">
3314 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xmh-X11R7.0-1.0.1.tar.bz2"
3315 size="153096" md5sum="53af2f87dc096d84f11ca6fbd6748b34"/>
3316 <dependencies>
3317 <dep package="app-xmh"/>
3318 </dependencies>
3319 </tarball>
3320 <tarball id="app/xmodmap" version="X11R7.0-1.0.0">
3321 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xmodmap-X11R7.0-1.0.0.tar.bz2"
3322 size="89685" md5sum="240ed53111925e005d2f138ea98ef5e1"/>
3323 <dependencies>
3324 <dep package="app-xmodmap"/>
3325 </dependencies>
3326 </tarball>
3327 <tarball id="app/xmore" version="X11R7.0-1.0.1">
3328 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xmore-X11R7.0-1.0.1.tar.bz2"
3329 size="92055" md5sum="99a48c50d486b7c9098b4f5598782cac"/>
3330 <dependencies>
3331 <dep package="app-xmore"/>
3332 </dependencies>
3333 </tarball>
3334 <tarball id="app/xphelloworld" version="X11R7.0-1.0.1">
3335 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xphelloworld-X11R7.0-1.0.1.tar.bz2"
3336 size="73098" md5sum="80c9a23c7efb72b9674d7af6b7346992"/>
3337 <dependencies>
3338 <dep package="app-xphelloworld"/>
3339 </dependencies>
3340 </tarball>
3341 <tarball id="app/xplsprinters" version="X11R7.0-1.0.1">
3342 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xplsprinters-X11R7.0-1.0.1.tar.bz2"
3343 size="77170" md5sum="1d0a68dada5e14ab07d7660abd4d03e3"/>
3344 <dependencies>
3345 <dep package="app-xplsprinters"/>
3346 </dependencies>
3347 </tarball>
3348 <tarball id="app/xprehashprinterlist" version="X11R7.0-1.0.1">
3349 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xprehashprinterlist-X11R7.0-1.0.1.tar.bz2"
3350 size="75554" md5sum="3907bce78d304dedb2a5dd6944bd2ed5"/>
3351 <dependencies>
3352 <dep package="app-xprehashprinterlist"/>
3353 </dependencies>
3354 </tarball>
3355 <tarball id="app/xprop" version="X11R7.0-1.0.1">
3356 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xprop-X11R7.0-1.0.1.tar.bz2"
3357 size="92550" md5sum="6730f0fbad6969825580de46e66b44dd"/>
3358 <dependencies>
3359 <dep package="app-xprop"/>
3360 </dependencies>
3361 </tarball>
3362 <tarball id="app/xpr" version="X11R7.0-1.0.1">
3363 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xpr-X11R7.0-1.0.1.tar.bz2"
3364 size="107488" md5sum="487b5ab96b373acb80808758ce23eb49"/>
3365 <dependencies>
3366 <dep package="app-xpr"/>
3367 </dependencies>
3368 </tarball>
3369 <tarball id="app/xrandr" version="X11R7.0-1.0.1">
3370 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xrandr-X11R7.0-1.0.1.tar.bz2"
3371 size="76130" md5sum="e433ccca3c4f9ab8609dfd1c9c8e36ea"/>
3372 <dependencies>
3373 <dep package="app-xrandr"/>
3374 </dependencies>
3375 </tarball>
3376 <tarball id="app/xrdb" version="X11R7.0-1.0.1">
3377 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xrdb-X11R7.0-1.0.1.tar.bz2"
3378 size="85598" md5sum="a3c1fd6f5391de7f810239a912d39fa5"/>
3379 <dependencies>
3380 <dep package="app-xrdb"/>
3381 </dependencies>
3382 </tarball>
3383 <tarball id="app/xrefresh" version="X11R7.0-1.0.1">
3384 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xrefresh-X11R7.0-1.0.1.tar.bz2"
3385 size="76351" md5sum="5a46d5fb82aeeb4d6aac58c9cc367439"/>
3386 <dependencies>
3387 <dep package="app-xrefresh"/>
3388 </dependencies>
3389 </tarball>
3390 <tarball id="app/xrx" version="X11R7.0-1.0.1">
3391 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xrx-X11R7.0-1.0.1.tar.bz2"
3392 size="260441" md5sum="9de3b04392c98df59c79a34fd51c385f"/>
3393 <dependencies>
3394 <dep package="app-xrx"/>
3395 </dependencies>
3396 </tarball>
3397 <tarball id="app/xsetmode" version="X11R7.0-1.0.0">
3398 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xsetmode-X11R7.0-1.0.0.tar.bz2"
3399 size="73740" md5sum="d83d6ef0b73762feab724aab95d9a4a2"/>
3400 <dependencies>
3401 <dep package="app-xsetmode"/>
3402 </dependencies>
3403 </tarball>
3404 <tarball id="app/xsetpointer" version="X11R7.0-1.0.0">
3405 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xsetpointer-X11R7.0-1.0.0.tar.bz2"
3406 size="73882" md5sum="195614431e2431508e07a42a3b6d4568"/>
3407 <dependencies>
3408 <dep package="app-xsetpointer"/>
3409 </dependencies>
3410 </tarball>
3411 <tarball id="app/xsetroot" version="X11R7.0-1.0.1">
3412 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xsetroot-X11R7.0-1.0.1.tar.bz2"
3413 size="77672" md5sum="e2831b39cd395d6f6f4824b0e25f55ed"/>
3414 <dependencies>
3415 <dep package="app-xsetroot"/>
3416 </dependencies>
3417 </tarball>
3418 <tarball id="app/xset" version="X11R7.0-1.0.1">
3419 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xset-X11R7.0-1.0.1.tar.bz2"
3420 size="88719" md5sum="a0350e334a215829166266e2ce504b1c"/>
3421 <dependencies>
3422 <dep package="app-xset"/>
3423 </dependencies>
3424 </tarball>
3425 <tarball id="app/xsm" version="X11R7.0-1.0.1">
3426 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xsm-X11R7.0-1.0.1.tar.bz2"
3427 size="116842" md5sum="e3588272ce3b7dc21d42ead683135a8a"/>
3428 <dependencies>
3429 <dep package="app-xsm"/>
3430 </dependencies>
3431 </tarball>
3432 <tarball id="app/xstdcmap" version="X11R7.0-1.0.1">
3433 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xstdcmap-X11R7.0-1.0.1.tar.bz2"
3434 size="76275" md5sum="e276aa02d44dcacf5ac13aa0cabd404d"/>
3435 <dependencies>
3436 <dep package="app-xstdcmap"/>
3437 </dependencies>
3438 </tarball>
3439 <tarball id="app/xtrap" version="X11R7.0-1.0.1">
3440 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xtrap-X11R7.0-1.0.1.tar.bz2"
3441 size="91255" md5sum="6d56946322d2875eb33f25f5e5f621a3"/>
3442 <dependencies>
3443 <dep package="app-xtrap"/>
3444 </dependencies>
3445 </tarball>
3446 <tarball id="app/xvidtune" version="X11R7.0-1.0.1">
3447 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xvidtune-X11R7.0-1.0.1.tar.bz2"
3448 size="88178" md5sum="a12e27fb732cb115b6adc4c724c44c5d"/>
3449 <dependencies>
3450 <dep package="app-xvidtune"/>
3451 </dependencies>
3452 </tarball>
3453 <tarball id="app/xvinfo" version="X11R7.0-1.0.1">
3454 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xvinfo-X11R7.0-1.0.1.tar.bz2"
3455 size="74754" md5sum="39d79590345bed51da6df838f6490cbf"/>
3456 <dependencies>
3457 <dep package="app-xvinfo"/>
3458 </dependencies>
3459 </tarball>
3460 <tarball id="app/xwd" version="X11R7.0-1.0.1">
3461 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xwd-X11R7.0-1.0.1.tar.bz2"
3462 size="97002" md5sum="596c443465ab9ab67c59c794261d4571"/>
3463 <dependencies>
3464 <dep package="app-xwd"/>
3465 </dependencies>
3466 </tarball>
3467 <tarball id="app/xwininfo" version="X11R7.0-1.0.1">
3468 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xwininfo-X11R7.0-1.0.1.tar.bz2"
3469 size="87409" md5sum="3ec67e4e1b9f5a1fe7e56b56ab931893"/>
3470 <dependencies>
3471 <dep package="app-xwininfo"/>
3472 </dependencies>
3473 </tarball>
3474 <tarball id="app/xwud" version="X11R7.0-1.0.1">
3475 <source href="http://ftp.x.org/pub/X11R7.0/src/app/xwud-X11R7.0-1.0.1.tar.bz2"
3476 size="83089" md5sum="e08d2ee04abb89a6348f47c84a1ff3ed"/>
3477 <dependencies>
3478 <dep package="app-xwud"/>
3479 </dependencies>
3480 </tarball>
3481 <tarball id="data/xbitmaps" version="X11R7.0-1.0.1">
3482 <source href="http://ftp.x.org/pub/X11R7.0/src/data/xbitmaps-X11R7.0-1.0.1.tar.bz2"
3483 size="55492" md5sum="22c6f4a17220cd6b41d9799905f8e357"/>
3484 <dependencies>
3485 <dep package="data-xbitmaps"/>
3486 </dependencies>
3487 </tarball>
3488 <tarball id="data/xcursor-themes" version="X11R7.0-1.0.1">
3489 <source href="http://ftp.x.org/pub/X11R7.0/src/data/xcursor-themes-X11R7.0-1.0.1.tar.bz2"
3490 size="2219697" md5sum="c39afeae55a7d330297b2fec3d113634"/>
3491 <dependencies>
3492 <dep package="data-xcursor-themes"/>
3493 </dependencies>
3494 </tarball>
3495 <tarball id="data/xkbdata" version="X11R7.0-1.0.1">
3496 <source href="http://ftp.x.org/pub/X11R7.0/src/data/xkbdata-X11R7.0-1.0.1.tar.bz2"
3497 size="285091" md5sum="1f706f92334ee65818512b3b45d7be65"/>
3498 <dependencies>
3499 <dep package="data-xkbdata"/>
3500 </dependencies>
3501 </tarball>
3502 <tarball id="doc/xorg-docs" version="X11R7.0-1.0.1">
3503 <source href="http://ftp.x.org/pub/X11R7.0/src/doc/xorg-docs-X11R7.0-1.0.1.tar.bz2"
3504 size="8339757" md5sum="ac0d76afa46ef5da9e1cf33558f4b303"/>
3505 <dependencies>
3506 <dep package="doc-xorg-docs"/>
3507 </dependencies>
3508 </tarball>
3509 <tarball id="doc/xorg-sgml-doctools" version="X11R7.0-1.0.1">
3510 <source href="http://ftp.x.org/pub/X11R7.0/src/doc/xorg-sgml-doctools-X11R7.0-1.0.1.tar.bz2"
3511 size="37232" md5sum="d08d4fd10ac46d8b4636efe4d8c0de74"/>
3512 <dependencies>
3513 <dep package="doc-xorg-sgml-doctools"/>
3514 </dependencies>
3515 </tarball>
3516 <tarball id="driver/xf86-input-acecad" version="X11R7.0-1.0.0.5">
3517 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-acecad-X11R7.0-1.0.0.5.tar.bz2"
3518 size="213979" md5sum="b35b1756579ebe296801622bdf063ab1"/>
3519 <dependencies>
3520 <dep package="driver-xf86-input-acecad"/>
3521 </dependencies>
3522 </tarball>
3523 <tarball id="driver/xf86-input-aiptek" version="X11R7.0-1.0.0.5">
3524 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-aiptek-X11R7.0-1.0.0.5.tar.bz2"
3525 size="225634" md5sum="9ee5109ef33e281ce0784ad077f26cee"/>
3526 <dependencies>
3527 <dep package="driver-xf86-input-aiptek"/>
3528 </dependencies>
3529 </tarball>
3530 <tarball id="driver/xf86-input-calcomp" version="X11R7.0-1.0.0.5">
3531 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-calcomp-X11R7.0-1.0.0.5.tar.bz2"
3532 size="215168" md5sum="f4199b5df063701462d5a8c84aadd190"/>
3533 <dependencies>
3534 <dep package="driver-xf86-input-calcomp"/>
3535 </dependencies>
3536 </tarball>
3537 <tarball id="driver/xf86-input-citron" version="X11R7.0-2.1.1.5">
3538 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-citron-X11R7.0-2.1.1.5.tar.bz2"
3539 size="233902" md5sum="62b5405d337bc055bc9345565cc0da8c"/>
3540 <dependencies>
3541 <dep package="driver-xf86-input-citron"/>
3542 </dependencies>
3543 </tarball>
3544 <tarball id="driver/xf86-input-digitaledge" version="X11R7.0-1.0.1.3">
3545 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-digitaledge-X11R7.0-1.0.1.3.tar.bz2"
3546 size="216971" md5sum="8342f3a0dcdaa1120af01dd25dabf0d7"/>
3547 <dependencies>
3548 <dep package="driver-xf86-input-digitaledge"/>
3549 </dependencies>
3550 </tarball>
3551 <tarball id="driver/xf86-input-dmc" version="X11R7.0-1.0.0.5">
3552 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-dmc-X11R7.0-1.0.0.5.tar.bz2"
3553 size="212774" md5sum="fdf127a2d419f7c2e02bec27273091d3"/>
3554 <dependencies>
3555 <dep package="driver-xf86-input-dmc"/>
3556 </dependencies>
3557 </tarball>
3558 <tarball id="driver/xf86-input-dynapro" version="X11R7.0-1.0.0.5">
3559 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-dynapro-X11R7.0-1.0.0.5.tar.bz2"
3560 size="212029" md5sum="89dbb839ab4c5fca3dbc3c2805a7efb9"/>
3561 <dependencies>
3562 <dep package="driver-xf86-input-dynapro"/>
3563 </dependencies>
3564 </tarball>
3565 <tarball id="driver/xf86-input-elo2300" version="X11R7.0-1.0.0.5">
3566 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-elo2300-X11R7.0-1.0.0.5.tar.bz2"
3567 size="214388" md5sum="6009a17f13a37bfde8b60c2fba5b0e5b"/>
3568 <dependencies>
3569 <dep package="driver-xf86-input-elo2300"/>
3570 </dependencies>
3571 </tarball>
3572 <tarball id="driver/xf86-input-elographics" version="X11R7.0-1.0.0.5">
3573 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-elographics-X11R7.0-1.0.0.5.tar.bz2"
3574 size="219736" md5sum="24c33f833bb2db72a07c3d28bfc0aae9"/>
3575 <dependencies>
3576 <dep package="driver-xf86-input-elographics"/>
3577 </dependencies>
3578 </tarball>
3579 <tarball id="driver/xf86-input-evdev" version="X11R7.0-1.0.0.5">
3580 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-evdev-X11R7.0-1.0.0.5.tar.bz2"
3581 size="212372" md5sum="d982c6f185f4c75a4b65703ceed7be06"/>
3582 <dependencies>
3583 <dep package="driver-xf86-input-evdev"/>
3584 </dependencies>
3585 </tarball>
3586 <tarball id="driver/xf86-input-fpit" version="X11R7.0-1.0.0.5">
3587 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-fpit-X11R7.0-1.0.0.5.tar.bz2"
3588 size="215828" md5sum="fc0e11fefc322623914a2d819d5b6d51"/>
3589 <dependencies>
3590 <dep package="driver-xf86-input-fpit"/>
3591 </dependencies>
3592 </tarball>
3593 <tarball id="driver/xf86-input-hyperpen" version="X11R7.0-1.0.0.5">
3594 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-hyperpen-X11R7.0-1.0.0.5.tar.bz2"
3595 size="218554" md5sum="0c4f2a6390e3045e4c48a48b47b6332c"/>
3596 <dependencies>
3597 <dep package="driver-xf86-input-hyperpen"/>
3598 </dependencies>
3599 </tarball>
3600 <tarball id="driver/xf86-input-jamstudio" version="X11R7.0-1.0.0.5">
3601 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-jamstudio-X11R7.0-1.0.0.5.tar.bz2"
3602 size="209954" md5sum="49de35ca024be2cb785832ae37ec30d0"/>
3603 <dependencies>
3604 <dep package="driver-xf86-input-jamstudio"/>
3605 </dependencies>
3606 </tarball>
3607 <tarball id="driver/xf86-input-joystick" version="X11R7.0-1.0.0.5">
3608 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-joystick-X11R7.0-1.0.0.5.tar.bz2"
3609 size="212507" md5sum="9e3ba60836f4c1d2e4cebc63a28321b4"/>
3610 <dependencies>
3611 <dep package="driver-xf86-input-joystick"/>
3612 </dependencies>
3613 </tarball>
3614 <tarball id="driver/xf86-input-keyboard" version="X11R7.0-1.0.1.3">
3615 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-keyboard-X11R7.0-1.0.1.3.tar.bz2"
3616 size="215665" md5sum="8fb8a30fd9d7f152a1aef4eb8ef32b3f"/>
3617 <dependencies>
3618 <dep package="driver-xf86-input-keyboard"/>
3619 </dependencies>
3620 </tarball>
3621 <tarball id="driver/xf86-input-magellan" version="X11R7.0-1.0.0.5">
3622 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-magellan-X11R7.0-1.0.0.5.tar.bz2"
3623 size="212433" md5sum="fd7367f467dc3302604274cee59a7c7b"/>
3624 <dependencies>
3625 <dep package="driver-xf86-input-magellan"/>
3626 </dependencies>
3627 </tarball>
3628 <tarball id="driver/xf86-input-magictouch" version="X11R7.0-1.0.0.5">
3629 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-magictouch-X11R7.0-1.0.0.5.tar.bz2"
3630 size="214562" md5sum="a51d84792b8c0079d7c8d13eb17acf31"/>
3631 <dependencies>
3632 <dep package="driver-xf86-input-magictouch"/>
3633 </dependencies>
3634 </tarball>
3635 <tarball id="driver/xf86-input-microtouch" version="X11R7.0-1.0.0.5">
3636 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-microtouch-X11R7.0-1.0.0.5.tar.bz2"
3637 size="215714" md5sum="0c25e0340b6483fb2a600b0e885724a2"/>
3638 <dependencies>
3639 <dep package="driver-xf86-input-microtouch"/>
3640 </dependencies>
3641 </tarball>
3642 <tarball id="driver/xf86-input-mouse" version="X11R7.0-1.0.3.1">
3643 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-mouse-X11R7.0-1.0.3.1.tar.bz2"
3644 size="259054" md5sum="12a908e5a97b1b03e8717abf167f4f27"/>
3645 <dependencies>
3646 <dep package="driver-xf86-input-mouse"/>
3647 </dependencies>
3648 </tarball>
3649 <tarball id="driver/xf86-input-mutouch" version="X11R7.0-1.0.0.5">
3650 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-mutouch-X11R7.0-1.0.0.5.tar.bz2"
3651 size="219973" md5sum="4758e667bfbba517df2a58d51270cfe2"/>
3652 <dependencies>
3653 <dep package="driver-xf86-input-mutouch"/>
3654 </dependencies>
3655 </tarball>
3656 <tarball id="driver/xf86-input-palmax" version="X11R7.0-1.0.0.5">
3657 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-palmax-X11R7.0-1.0.0.5.tar.bz2"
3658 size="213854" md5sum="d138024a20298304af883631d23c5338"/>
3659 <dependencies>
3660 <dep package="driver-xf86-input-palmax"/>
3661 </dependencies>
3662 </tarball>
3663 <tarball id="driver/xf86-input-penmount" version="X11R7.0-1.0.0.5">
3664 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-penmount-X11R7.0-1.0.0.5.tar.bz2"
3665 size="212934" md5sum="065b1cf862864741aebcfefcc7c09539"/>
3666 <dependencies>
3667 <dep package="driver-xf86-input-penmount"/>
3668 </dependencies>
3669 </tarball>
3670 <tarball id="driver/xf86-input-spaceorb" version="X11R7.0-1.0.0.5">
3671 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-spaceorb-X11R7.0-1.0.0.5.tar.bz2"
3672 size="211269" md5sum="193ca7b1e87c3995b86f15a01b63b297"/>
3673 <dependencies>
3674 <dep package="driver-xf86-input-spaceorb"/>
3675 </dependencies>
3676 </tarball>
3677 <tarball id="driver/xf86-input-summa" version="X11R7.0-1.0.0.5">
3678 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-summa-X11R7.0-1.0.0.5.tar.bz2"
3679 size="218264" md5sum="61d780857e5dc139081718c075e74a01"/>
3680 <dependencies>
3681 <dep package="driver-xf86-input-summa"/>
3682 </dependencies>
3683 </tarball>
3684 <tarball id="driver/xf86-input-tek4957" version="X11R7.0-1.0.0.5">
3685 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-tek4957-X11R7.0-1.0.0.5.tar.bz2"
3686 size="213488" md5sum="df633403c91a48c6a316c6a5f48e53e2"/>
3687 <dependencies>
3688 <dep package="driver-xf86-input-tek4957"/>
3689 </dependencies>
3690 </tarball>
3691 <tarball id="driver/xf86-input-ur98" version="X11R7.0-1.0.0.5">
3692 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-ur98-X11R7.0-1.0.0.5.tar.bz2"
3693 size="214459" md5sum="9b1530b3dcbb77690ad0e61f60489899"/>
3694 <dependencies>
3695 <dep package="driver-xf86-input-ur98"/>
3696 </dependencies>
3697 </tarball>
3698 <tarball id="driver/xf86-input-void" version="X11R7.0-1.0.0.5">
3699 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-input-void-X11R7.0-1.0.0.5.tar.bz2"
3700 size="209891" md5sum="c7ae53dee1f3e95fa5ce9659b34d8446"/>
3701 <dependencies>
3702 <dep package="driver-xf86-input-void"/>
3703 </dependencies>
3704 </tarball>
3705 <tarball id="driver/xf86-video-apm" version="X11R7.0-1.0.1.5">
3706 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-apm-X11R7.0-1.0.1.5.tar.bz2"
3707 size="255034" md5sum="323911ab16a6147d3cabceff9336a3d2"/>
3708 <dependencies>
3709 <dep package="driver-xf86-video-apm"/>
3710 </dependencies>
3711 </tarball>
3712 <tarball id="driver/xf86-video-ark" version="X11R7.0-0.5.0.5">
3713 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-ark-X11R7.0-0.5.0.5.tar.bz2"
3714 size="215060" md5sum="342937e275dbc92f437417a3186a8222"/>
3715 <dependencies>
3716 <dep package="driver-xf86-video-ark"/>
3717 </dependencies>
3718 </tarball>
3719 <tarball id="driver/xf86-video-ati" version="X11R7.0-6.5.7.3">
3720 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-ati-X11R7.0-6.5.7.3.tar.bz2"
3721 size="659422" md5sum="92525195a7a36f5ffbffcb4e6a564e50"/>
3722 <dependencies>
3723 <dep package="driver-xf86-video-ati"/>
3724 </dependencies>
3725 </tarball>
3726 <tarball id="driver/xf86-video-chips" version="X11R7.0-1.0.1.3">
3727 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-chips-X11R7.0-1.0.1.3.tar.bz2"
3728 size="302529" md5sum="90f23505faceac30d3f46ab94f7293e1"/>
3729 <dependencies>
3730 <dep package="driver-xf86-video-chips"/>
3731 </dependencies>
3732 </tarball>
3733 <tarball id="driver/xf86-video-cirrus" version="X11R7.0-1.0.0.5">
3734 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-cirrus-X11R7.0-1.0.0.5.tar.bz2"
3735 size="250335" md5sum="7708693ad9d73cd76d4caef7c644a46f"/>
3736 <dependencies>
3737 <dep package="driver-xf86-video-cirrus"/>
3738 </dependencies>
3739 </tarball>
3740 <tarball id="driver/xf86-video-cyrix" version="X11R7.0-1.0.0.5">
3741 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-cyrix-X11R7.0-1.0.0.5.tar.bz2"
3742 size="230817" md5sum="14f868d16554b19fef4f30398a7b9cf1"/>
3743 <dependencies>
3744 <dep package="driver-xf86-video-cyrix"/>
3745 </dependencies>
3746 </tarball>
3747 <tarball id="driver/xf86-video-dummy" version="X11R7.0-0.1.0.5">
3748 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-dummy-X11R7.0-0.1.0.5.tar.bz2"
3749 size="212668" md5sum="462654f9be7e3022f97147e3390db97a"/>
3750 <dependencies>
3751 <dep package="driver-xf86-video-dummy"/>
3752 </dependencies>
3753 </tarball>
3754 <tarball id="driver/xf86-video-fbdev" version="X11R7.0-0.1.0.5">
3755 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-fbdev-X11R7.0-0.1.0.5.tar.bz2"
3756 size="215158" md5sum="1cf374eeb9151ac16a7ec2cd38048737"/>
3757 <dependencies>
3758 <dep package="driver-xf86-video-fbdev"/>
3759 </dependencies>
3760 </tarball>
3761 <tarball id="driver/xf86-video-glint" version="X11R7.0-1.0.1.3">
3762 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-glint-X11R7.0-1.0.1.3.tar.bz2"
3763 size="320027" md5sum="f14c2f1696c05760207adcaac856e5e5"/>
3764 <dependencies>
3765 <dep package="driver-xf86-video-glint"/>
3766 </dependencies>
3767 </tarball>
3768 <tarball id="driver/xf86-video-i128" version="X11R7.0-1.1.0.5">
3769 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-i128-X11R7.0-1.1.0.5.tar.bz2"
3770 size="250215" md5sum="078eed8c3673488ee618dfc7a3ef101b"/>
3771 <dependencies>
3772 <dep package="driver-xf86-video-i128"/>
3773 </dependencies>
3774 </tarball>
3775 <tarball id="driver/xf86-video-i740" version="X11R7.0-1.0.0.5">
3776 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-i740-X11R7.0-1.0.0.5.tar.bz2"
3777 size="240418" md5sum="625448b13ebe2a13b7defad1efec05c4"/>
3778 <dependencies>
3779 <dep package="driver-xf86-video-i740"/>
3780 </dependencies>
3781 </tarball>
3782 <tarball id="driver/xf86-video-i810" version="X11R7.0-1.4.1.3">
3783 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-i810-X11R7.0-1.4.1.3.tar.bz2"
3784 size="356294" md5sum="fe6bec726fc1657b537508bbe8c2005b"/>
3785 <dependencies>
3786 <dep package="driver-xf86-video-i810"/>
3787 </dependencies>
3788 </tarball>
3789 <tarball id="driver/xf86-video-imstt" version="X11R7.0-1.0.0.5">
3790 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-imstt-X11R7.0-1.0.0.5.tar.bz2"
3791 size="217637" md5sum="cc949688918b78f830d78a9613e6896b"/>
3792 <dependencies>
3793 <dep package="driver-xf86-video-imstt"/>
3794 </dependencies>
3795 </tarball>
3796 <tarball id="driver/xf86-video-mga" version="X11R7.0-1.2.1.3">
3797 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-mga-X11R7.0-1.2.1.3.tar.bz2"
3798 size="335360" md5sum="cb0409782020b5cc7edc273624ffdd17"/>
3799 <dependencies>
3800 <dep package="driver-xf86-video-mga"/>
3801 </dependencies>
3802 </tarball>
3803 <tarball id="driver/xf86-video-neomagic" version="X11R7.0-1.0.0.5">
3804 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-neomagic-X11R7.0-1.0.0.5.tar.bz2"
3805 size="250327" md5sum="ffe9015678a41e97bdbd2825066bb47b"/>
3806 <dependencies>
3807 <dep package="driver-xf86-video-neomagic"/>
3808 </dependencies>
3809 </tarball>
3810 <tarball id="driver/xf86-video-newport" version="X11R7.0-0.1.4.1">
3811 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-newport-X11R7.0-0.1.4.1.tar.bz2"
3812 size="233693" md5sum="d74d9896d57c3caf224ba3472630d874"/>
3813 <dependencies>
3814 <dep package="driver-xf86-video-newport"/>
3815 </dependencies>
3816 </tarball>
3817 <tarball id="driver/xf86-video-nsc" version="X11R7.0-2.7.6.5">
3818 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-nsc-X11R7.0-2.7.6.5.tar.bz2"
3819 size="453051" md5sum="ab16611b3ec7d21503b16b0a31addae0"/>
3820 <dependencies>
3821 <dep package="driver-xf86-video-nsc"/>
3822 </dependencies>
3823 </tarball>
3824 <tarball id="driver/xf86-video-nv" version="X11R7.0-1.0.1.5">
3825 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-nv-X11R7.0-1.0.1.5.tar.bz2"
3826 size="267738" md5sum="9a88547fe550e20edcc5a938d31e22b1"/>
3827 <dependencies>
3828 <dep package="driver-xf86-video-nv"/>
3829 </dependencies>
3830 </tarball>
3831 <tarball id="driver/xf86-video-rendition" version="X11R7.0-4.0.1.3">
3832 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-rendition-X11R7.0-4.0.1.3.tar.bz2"
3833 size="278961" md5sum="f1a25db74a148dea45115e813027b932"/>
3834 <dependencies>
3835 <dep package="driver-xf86-video-rendition"/>
3836 </dependencies>
3837 </tarball>
3838 <tarball id="driver/xf86-video-s3virge" version="X11R7.0-1.8.6.5">
3839 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-s3virge-X11R7.0-1.8.6.5.tar.bz2"
3840 size="270294" md5sum="d0164c37749ab5f565db9813487e1900"/>
3841 <dependencies>
3842 <dep package="driver-xf86-video-s3virge"/>
3843 </dependencies>
3844 </tarball>
3845 <tarball id="driver/xf86-video-s3" version="X11R7.0-0.3.5.5">
3846 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-s3-X11R7.0-0.3.5.5.tar.bz2"
3847 size="234539" md5sum="83b9e8a9b8fc1c49bda2811358e5007c"/>
3848 <dependencies>
3849 <dep package="driver-xf86-video-s3"/>
3850 </dependencies>
3851 </tarball>
3852 <tarball id="driver/xf86-video-savage" version="X11R7.0-2.0.2.3">
3853 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-savage-X11R7.0-2.0.2.3.tar.bz2"
3854 size="282811" md5sum="6b638dd500d10dba1822d3ea5061fc65"/>
3855 <dependencies>
3856 <dep package="driver-xf86-video-savage"/>
3857 </dependencies>
3858 </tarball>
3859 <tarball id="driver/xf86-video-siliconmotion" version="X11R7.0-1.3.1.5">
3860 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-siliconmotion-X11R7.0-1.3.1.5.tar.bz2"
3861 size="257549" md5sum="957de4e2a3c687dbb2e9e18582397804"/>
3862 <dependencies>
3863 <dep package="driver-xf86-video-siliconmotion"/>
3864 </dependencies>
3865 </tarball>
3866 <tarball id="driver/xf86-video-sisusb" version="X11R7.0-0.7.1.3">
3867 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-sisusb-X11R7.0-0.7.1.3.tar.bz2"
3868 size="282820" md5sum="781d726a0ca54b65521e383ab99043c8"/>
3869 <dependencies>
3870 <dep package="driver-xf86-video-sisusb"/>
3871 </dependencies>
3872 </tarball>
3873 <tarball id="driver/xf86-video-sis" version="X11R7.0-0.8.1.3">
3874 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-sis-X11R7.0-0.8.1.3.tar.bz2"
3875 size="585512" md5sum="e3bac5a208b8bacfbec236b5a5b0ef40"/>
3876 <dependencies>
3877 <dep package="driver-xf86-video-sis"/>
3878 </dependencies>
3879 </tarball>
3880 <tarball id="driver/xf86-video-sunbw2" version="X11R7.0-1.0.0.5">
3881 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-sunbw2-X11R7.0-1.0.0.5.tar.bz2"
3882 size="211092" md5sum="0cdda1ab939ea1190c142aa8aabfaf83"/>
3883 <dependencies>
3884 <dep package="driver-xf86-video-sunbw2"/>
3885 </dependencies>
3886 </tarball>
3887 <tarball id="driver/xf86-video-suncg14" version="X11R7.0-1.0.0.5">
3888 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-suncg14-X11R7.0-1.0.0.5.tar.bz2"
3889 size="212377" md5sum="8f3a734d02ae716415f9c6344fa661bd"/>
3890 <dependencies>
3891 <dep package="driver-xf86-video-suncg14"/>
3892 </dependencies>
3893 </tarball>
3894 <tarball id="driver/xf86-video-suncg3" version="X11R7.0-1.0.0.5">
3895 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-suncg3-X11R7.0-1.0.0.5.tar.bz2"
3896 size="210725" md5sum="799a54cef1f4435e00fa94a1d97d056f"/>
3897 <dependencies>
3898 <dep package="driver-xf86-video-suncg3"/>
3899 </dependencies>
3900 </tarball>
3901 <tarball id="driver/xf86-video-suncg6" version="X11R7.0-1.0.0.5">
3902 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-suncg6-X11R7.0-1.0.0.5.tar.bz2"
3903 size="215040" md5sum="2227f3fb86b02148f347e002662e53c8"/>
3904 <dependencies>
3905 <dep package="driver-xf86-video-suncg6"/>
3906 </dependencies>
3907 </tarball>
3908 <tarball id="driver/xf86-video-sunffb" version="X11R7.0-1.0.1.3">
3909 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-sunffb-X11R7.0-1.0.1.3.tar.bz2"
3910 size="278439" md5sum="bb5182e3b74b3baa6fee245ac8bbf09a"/>
3911 <dependencies>
3912 <dep package="driver-xf86-video-sunffb"/>
3913 </dependencies>
3914 </tarball>
3915 <tarball id="driver/xf86-video-sunleo" version="X11R7.0-1.0.0.5">
3916 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-sunleo-X11R7.0-1.0.0.5.tar.bz2"
3917 size="220890" md5sum="deb17a74ba68ee9593ac774206bd3612"/>
3918 <dependencies>
3919 <dep package="driver-xf86-video-sunleo"/>
3920 </dependencies>
3921 </tarball>
3922 <tarball id="driver/xf86-video-suntcx" version="X11R7.0-1.0.0.5">
3923 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-suntcx-X11R7.0-1.0.0.5.tar.bz2"
3924 size="214253" md5sum="74d6ba5e55afdfebff84db08b6589e26"/>
3925 <dependencies>
3926 <dep package="driver-xf86-video-suntcx"/>
3927 </dependencies>
3928 </tarball>
3929 <tarball id="driver/xf86-video-tdfx" version="X11R7.0-1.1.1.3">
3930 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-tdfx-X11R7.0-1.1.1.3.tar.bz2"
3931 size="257113" md5sum="0201415230bf0454384c3bad099520d2"/>
3932 <dependencies>
3933 <dep package="driver-xf86-video-tdfx"/>
3934 </dependencies>
3935 </tarball>
3936 <tarball id="driver/xf86-video-tga" version="X11R7.0-1.0.0.5">
3937 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-tga-X11R7.0-1.0.0.5.tar.bz2"
3938 size="244810" md5sum="fa67bf34454888d38e15708395cfed87"/>
3939 <dependencies>
3940 <dep package="driver-xf86-video-tga"/>
3941 </dependencies>
3942 </tarball>
3943 <tarball id="driver/xf86-video-trident" version="X11R7.0-1.0.1.2">
3944 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-trident-X11R7.0-1.0.1.2.tar.bz2"
3945 size="261260" md5sum="69f28afc7b585d01bb06b1e2f872f8ea"/>
3946 <dependencies>
3947 <dep package="driver-xf86-video-trident"/>
3948 </dependencies>
3949 </tarball>
3950 <tarball id="driver/xf86-video-tseng" version="X11R7.0-1.0.0.5">
3951 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-tseng-X11R7.0-1.0.0.5.tar.bz2"
3952 size="260944" md5sum="981f46914c1e54742418f0444ea2e092"/>
3953 <dependencies>
3954 <dep package="driver-xf86-video-tseng"/>
3955 </dependencies>
3956 </tarball>
3957 <tarball id="driver/xf86-video-v4l" version="X11R7.0-0.0.1.5">
3958 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-v4l-X11R7.0-0.0.1.5.tar.bz2"
3959 size="218210" md5sum="e422c63bc83717ecd0686aef2036802b"/>
3960 <dependencies>
3961 <dep package="driver-xf86-video-v4l"/>
3962 </dependencies>
3963 </tarball>
3964 <tarball id="driver/xf86-video-vesa" version="X11R7.0-1.0.1.3">
3965 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-vesa-X11R7.0-1.0.1.3.tar.bz2"
3966 size="218918" md5sum="049ada4df1abb5aa2b6633ba90353e78"/>
3967 <dependencies>
3968 <dep package="driver-xf86-video-vesa"/>
3969 </dependencies>
3970 </tarball>
3971 <tarball id="driver/xf86-video-vga" version="X11R7.0-4.0.0.5">
3972 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-vga-X11R7.0-4.0.0.5.tar.bz2"
3973 size="216215" md5sum="24437857707acc337cab331cc56f64e2"/>
3974 <dependencies>
3975 <dep package="driver-xf86-video-vga"/>
3976 </dependencies>
3977 </tarball>
3978 <tarball id="driver/xf86-video-via" version="X11R7.0-0.1.33.2">
3979 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-via-X11R7.0-0.1.33.2.tar.bz2"
3980 size="355172" md5sum="4d3268d226a40f580ab105796bfed1f5"/>
3981 <dependencies>
3982 <dep package="driver-xf86-video-via"/>
3983 </dependencies>
3984 </tarball>
3985 <tarball id="driver/xf86-video-vmware" version="X11R7.0-10.11.1.3">
3986 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-vmware-X11R7.0-10.11.1.3.tar.bz2"
3987 size="239037" md5sum="4df79349e26add4c23f6be8bec347ad4"/>
3988 <dependencies>
3989 <dep package="driver-xf86-video-vmware"/>
3990 </dependencies>
3991 </tarball>
3992 <tarball id="driver/xf86-video-voodoo" version="X11R7.0-1.0.0.5">
3993 <source href="http://ftp.x.org/pub/X11R7.0/src/driver/xf86-video-voodoo-X11R7.0-1.0.0.5.tar.bz2"
3994 size="226952" md5sum="e00cc814ebdb3f3067e075bc93b26199"/>
3995 <dependencies>
3996 <dep package="driver-xf86-video-voodoo"/>
3997 </dependencies>
3998 </tarball>
3999 <tarball id="font/encodings" version="X11R7.0-1.0.0">
4000 <source href="http://ftp.x.org/pub/X11R7.0/src/font/encodings-X11R7.0-1.0.0.tar.bz2"
4001 size="594892" md5sum="385cbd4093b610610ca54c06cbb0f497"/>
4002 <dependencies>
4003 <dep package="font-encodings"/>
4004 </dependencies>
4005 </tarball>
4006 <tarball id="font/font-adobe-100dpi" version="X11R7.0-1.0.0">
4007 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-adobe-100dpi-X11R7.0-1.0.0.tar.bz2"
4008 size="1007038" md5sum="f5de34fa63976de9263f032453348f6c"/>
4009 <dependencies>
4010 <dep package="font-font-adobe-100dpi"/>
4011 </dependencies>
4012 </tarball>
4013 <tarball id="font/font-adobe-75dpi" version="X11R7.0-1.0.0">
4014 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-adobe-75dpi-X11R7.0-1.0.0.tar.bz2"
4015 size="789768" md5sum="361fc4c9da3c34c5105df4f4688029d0"/>
4016 <dependencies>
4017 <dep package="font-font-adobe-75dpi"/>
4018 </dependencies>
4019 </tarball>
4020 <tarball id="font/font-adobe-utopia-100dpi" version="X11R7.0-1.0.1">
4021 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-adobe-utopia-100dpi-X11R7.0-1.0.1.tar.bz2"
4022 size="284406" md5sum="b720eed8eba0e4c5bcb9fdf6c2003355"/>
4023 <dependencies>
4024 <dep package="font-font-adobe-utopia-100dpi"/>
4025 </dependencies>
4026 </tarball>
4027 <tarball id="font/font-adobe-utopia-75dpi" version="X11R7.0-1.0.1">
4028 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-adobe-utopia-75dpi-X11R7.0-1.0.1.tar.bz2"
4029 size="206053" md5sum="a6d5d355b92a7e640698c934b0b79b53"/>
4030 <dependencies>
4031 <dep package="font-font-adobe-utopia-75dpi"/>
4032 </dependencies>
4033 </tarball>
4034 <tarball id="font/font-adobe-utopia-type1" version="X11R7.0-1.0.1">
4035 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-adobe-utopia-type1-X11R7.0-1.0.1.tar.bz2"
4036 size="208787" md5sum="db1cc2f707cffd08a461f093b55ced5e"/>
4037 <dependencies>
4038 <dep package="font-font-adobe-utopia-type1"/>
4039 </dependencies>
4040 </tarball>
4041 <tarball id="font/font-alias" version="X11R7.0-1.0.1">
4042 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-alias-X11R7.0-1.0.1.tar.bz2"
4043 size="42497" md5sum="de7035b15ba7edc36f8685ab3c17a9cf"/>
4044 <dependencies>
4045 <dep package="font-font-alias"/>
4046 </dependencies>
4047 </tarball>
4048 <tarball id="font/font-arabic-misc" version="X11R7.0-1.0.0">
4049 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-arabic-misc-X11R7.0-1.0.0.tar.bz2"
4050 size="52842" md5sum="b95dc750ddc7d511e1f570034d9e1b27"/>
4051 <dependencies>
4052 <dep package="font-font-arabic-misc"/>
4053 </dependencies>
4054 </tarball>
4055 <tarball id="font/font-bh-100dpi" version="X11R7.0-1.0.0">
4056 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-100dpi-X11R7.0-1.0.0.tar.bz2"
4057 size="642898" md5sum="29eeed0ad42653f27b929119581deb3e"/>
4058 <dependencies>
4059 <dep package="font-font-bh-100dpi"/>
4060 </dependencies>
4061 </tarball>
4062 <tarball id="font/font-bh-75dpi" version="X11R7.0-1.0.0">
4063 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-75dpi-X11R7.0-1.0.0.tar.bz2"
4064 size="475715" md5sum="7546c97560eb325400365adbc426308b"/>
4065 <dependencies>
4066 <dep package="font-font-bh-75dpi"/>
4067 </dependencies>
4068 </tarball>
4069 <tarball id="font/font-bh-lucidatypewriter-100dpi" version="X11R7.0-1.0.0">
4070 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-lucidatypewriter-100dpi-X11R7.0-1.0.0.tar.bz2"
4071 size="179267" md5sum="8a56f4cbea74f4dbbf9bdac95686dca8"/>
4072 <dependencies>
4073 <dep package="font-font-bh-lucidatypewriter-100dpi"/>
4074 </dependencies>
4075 </tarball>
4076 <tarball id="font/font-bh-lucidatypewriter-75dpi" version="X11R7.0-1.0.0">
4077 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-lucidatypewriter-75dpi-X11R7.0-1.0.0.tar.bz2"
4078 size="151564" md5sum="e5cccf93f4f1f793cd32adfa81cc1b40"/>
4079 <dependencies>
4080 <dep package="font-font-bh-lucidatypewriter-75dpi"/>
4081 </dependencies>
4082 </tarball>
4083 <tarball id="font/font-bh-ttf" version="X11R7.0-1.0.0">
4084 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-ttf-X11R7.0-1.0.0.tar.bz2"
4085 size="370568" md5sum="53b984889aec3c0c2eb07f8aaa49dba9"/>
4086 <dependencies>
4087 <dep package="font-font-bh-ttf"/>
4088 </dependencies>
4089 </tarball>
4090 <tarball id="font/font-bh-type1" version="X11R7.0-1.0.0">
4091 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bh-type1-X11R7.0-1.0.0.tar.bz2"
4092 size="571692" md5sum="302111513d1e94303c0ec0139d5ae681"/>
4093 <dependencies>
4094 <dep package="font-font-bh-type1"/>
4095 </dependencies>
4096 </tarball>
4097 <tarball id="font/font-bitstream-100dpi" version="X11R7.0-1.0.0">
4098 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bitstream-100dpi-X11R7.0-1.0.0.tar.bz2"
4099 size="129846" md5sum="dc595e77074de890974726769f25e123"/>
4100 <dependencies>
4101 <dep package="font-font-bitstream-100dpi"/>
4102 </dependencies>
4103 </tarball>
4104 <tarball id="font/font-bitstream-75dpi" version="X11R7.0-1.0.0">
4105 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bitstream-75dpi-X11R7.0-1.0.0.tar.bz2"
4106 size="103866" md5sum="408515646743d14e1e2e240da4fffdc2"/>
4107 <dependencies>
4108 <dep package="font-font-bitstream-75dpi"/>
4109 </dependencies>
4110 </tarball>
4111 <tarball id="font/font-bitstream-speedo" version="X11R7.0-1.0.0">
4112 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bitstream-speedo-X11R7.0-1.0.0.tar.bz2"
4113 size="337301" md5sum="068c78ce48e5e6c4f25e0bba839a6b7a"/>
4114 <dependencies>
4115 <dep package="font-font-bitstream-speedo"/>
4116 </dependencies>
4117 </tarball>
4118 <tarball id="font/font-bitstream-type1" version="X11R7.0-1.0.0">
4119 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-bitstream-type1-X11R7.0-1.0.0.tar.bz2"
4120 size="352053" md5sum="f4881a7e28eaeb7580d5eaf0f09239da"/>
4121 <dependencies>
4122 <dep package="font-font-bitstream-type1"/>
4123 </dependencies>
4124 </tarball>
4125 <tarball id="font/font-cronyx-cyrillic" version="X11R7.0-1.0.0">
4126 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-cronyx-cyrillic-X11R7.0-1.0.0.tar.bz2"
4127 size="182134" md5sum="447163fff74b57968fc5139d8b2ad988"/>
4128 <dependencies>
4129 <dep package="font-font-cronyx-cyrillic"/>
4130 </dependencies>
4131 </tarball>
4132 <tarball id="font/font-cursor-misc" version="X11R7.0-1.0.0">
4133 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-cursor-misc-X11R7.0-1.0.0.tar.bz2"
4134 size="42627" md5sum="82e89de0e1b9c95f32b0fc12f5131d2c"/>
4135 <dependencies>
4136 <dep package="font-font-cursor-misc"/>
4137 </dependencies>
4138 </tarball>
4139 <tarball id="font/font-daewoo-misc" version="X11R7.0-1.0.0">
4140 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-daewoo-misc-X11R7.0-1.0.0.tar.bz2"
4141 size="668277" md5sum="2fd7e6c8c21990ad906872efd02f3873"/>
4142 <dependencies>
4143 <dep package="font-font-daewoo-misc"/>
4144 </dependencies>
4145 </tarball>
4146 <tarball id="font/font-dec-misc" version="X11R7.0-1.0.0">
4147 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-dec-misc-X11R7.0-1.0.0.tar.bz2"
4148 size="40713" md5sum="7ff9aba4c65aa226bda7528294c7998c"/>
4149 <dependencies>
4150 <dep package="font-font-dec-misc"/>
4151 </dependencies>
4152 </tarball>
4153 <tarball id="font/font-ibm-type1" version="X11R7.0-1.0.0">
4154 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-ibm-type1-X11R7.0-1.0.0.tar.bz2"
4155 size="315301" md5sum="fab2c49cb0f9fcee0bc0ac77e510d4e5"/>
4156 <dependencies>
4157 <dep package="font-font-ibm-type1"/>
4158 </dependencies>
4159 </tarball>
4160 <tarball id="font/font-isas-misc" version="X11R7.0-1.0.0">
4161 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-isas-misc-X11R7.0-1.0.0.tar.bz2"
4162 size="781027" md5sum="c0981507c9276c22956c7bfe932223d9"/>
4163 <dependencies>
4164 <dep package="font-font-isas-misc"/>
4165 </dependencies>
4166 </tarball>
4167 <tarball id="font/font-jis-misc" version="X11R7.0-1.0.0">
4168 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-jis-misc-X11R7.0-1.0.0.tar.bz2"
4169 size="555563" md5sum="3732ca6c34d03e44c73f0c103512ef26"/>
4170 <dependencies>
4171 <dep package="font-font-jis-misc"/>
4172 </dependencies>
4173 </tarball>
4174 <tarball id="font/font-micro-misc" version="X11R7.0-1.0.0">
4175 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-micro-misc-X11R7.0-1.0.0.tar.bz2"
4176 size="38802" md5sum="eb0050d73145c5b9fb6b9035305edeb6"/>
4177 <dependencies>
4178 <dep package="font-font-micro-misc"/>
4179 </dependencies>
4180 </tarball>
4181 <tarball id="font/font-misc-cyrillic" version="X11R7.0-1.0.0">
4182 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-misc-cyrillic-X11R7.0-1.0.0.tar.bz2"
4183 size="65603" md5sum="58d31311e8e51efbe16517adaf1a239d"/>
4184 <dependencies>
4185 <dep package="font-font-misc-cyrillic"/>
4186 </dependencies>
4187 </tarball>
4188 <tarball id="font/font-misc-ethiopic" version="X11R7.0-1.0.0">
4189 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-misc-ethiopic-X11R7.0-1.0.0.tar.bz2"
4190 size="184289" md5sum="190738980705826a27fbf4685650d3b9"/>
4191 <dependencies>
4192 <dep package="font-font-misc-ethiopic"/>
4193 </dependencies>
4194 </tarball>
4195 <tarball id="font/font-misc-meltho" version="X11R7.0-1.0.0">
4196 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-misc-meltho-X11R7.0-1.0.0.tar.bz2"
4197 size="1446293" md5sum="8812c57220bcd139b4ba6266eafbd712"/>
4198 <dependencies>
4199 <dep package="font-font-misc-meltho"/>
4200 </dependencies>
4201 </tarball>
4202 <tarball id="font/font-misc-misc" version="X11R7.0-1.0.0">
4203 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-misc-misc-X11R7.0-1.0.0.tar.bz2"
4204 size="1831073" md5sum="4a5a7987183a9e1ea232c8391ae4c244"/>
4205 <dependencies>
4206 <dep package="font-font-misc-misc"/>
4207 </dependencies>
4208 </tarball>
4209 <tarball id="font/font-mutt-misc" version="X11R7.0-1.0.0">
4210 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-mutt-misc-X11R7.0-1.0.0.tar.bz2"
4211 size="199237" md5sum="139b368edecf8185d16a33b4a7c09657"/>
4212 <dependencies>
4213 <dep package="font-font-mutt-misc"/>
4214 </dependencies>
4215 </tarball>
4216 <tarball id="font/font-schumacher-misc" version="X11R7.0-1.0.0">
4217 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-schumacher-misc-X11R7.0-1.0.0.tar.bz2"
4218 size="78036" md5sum="d51808138ef63b84363f7d82ed8bb681"/>
4219 <dependencies>
4220 <dep package="font-font-schumacher-misc"/>
4221 </dependencies>
4222 </tarball>
4223 <tarball id="font/font-screen-cyrillic" version="X11R7.0-1.0.0">
4224 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-screen-cyrillic-X11R7.0-1.0.0.tar.bz2"
4225 size="42859" md5sum="c08da585feb173e1b27c3fbf8f90ba45"/>
4226 <dependencies>
4227 <dep package="font-font-screen-cyrillic"/>
4228 </dependencies>
4229 </tarball>
4230 <tarball id="font/font-sony-misc" version="X11R7.0-1.0.0">
4231 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-sony-misc-X11R7.0-1.0.0.tar.bz2"
4232 size="48447" md5sum="014725f97635da9e5e9b303ab796817e"/>
4233 <dependencies>
4234 <dep package="font-font-sony-misc"/>
4235 </dependencies>
4236 </tarball>
4237 <tarball id="font/font-sun-misc" version="X11R7.0-1.0.0">
4238 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-sun-misc-X11R7.0-1.0.0.tar.bz2"
4239 size="56437" md5sum="0259436c430034f24f3b239113c9630e"/>
4240 <dependencies>
4241 <dep package="font-font-sun-misc"/>
4242 </dependencies>
4243 </tarball>
4244 <tarball id="font/font-util" version="X11R7.0-1.0.0">
4245 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-util-X11R7.0-1.0.0.tar.bz2"
4246 size="94683" md5sum="73cc445cb20a658037ad3a7ac571f525"/>
4247 <dependencies>
4248 <dep package="font-font-util"/>
4249 </dependencies>
4250 </tarball>
4251 <tarball id="font/font-winitzki-cyrillic" version="X11R7.0-1.0.0">
4252 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-winitzki-cyrillic-X11R7.0-1.0.0.tar.bz2"
4253 size="41002" md5sum="6dc447609609e4e2454ad7da29873501"/>
4254 <dependencies>
4255 <dep package="font-font-winitzki-cyrillic"/>
4256 </dependencies>
4257 </tarball>
4258 <tarball id="font/font-xfree86-type1" version="X11R7.0-1.0.0">
4259 <source href="http://ftp.x.org/pub/X11R7.0/src/font/font-xfree86-type1-X11R7.0-1.0.0.tar.bz2"
4260 size="66041" md5sum="27a6bbf5c8bbe998ff7e8537929ccbc8"/>
4261 <dependencies>
4262 <dep package="font-font-xfree86-type1"/>
4263 </dependencies>
4264 </tarball>
4265 <tarball id="lib/libAppleWM" version="X11R7.0-1.0.0">
4266 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libAppleWM-X11R7.0-1.0.0.tar.bz2"
4267 size="208693" md5sum="8af30932ebc278835375fca34a2790f5"/>
4268 <dependencies>
4269 <dep package="lib-libAppleWM"/>
4270 </dependencies>
4271 </tarball>
4272 <tarball id="lib/libdmx" version="X11R7.0-1.0.1">
4273 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libdmx-X11R7.0-1.0.1.tar.bz2"
4274 size="213045" md5sum="ae6b3c48f1349fc5dfa7d7c4b9cf4718"/>
4275 <dependencies>
4276 <dep package="lib-libdmx"/>
4277 </dependencies>
4278 </tarball>
4279 <tarball id="lib/libfontenc" version="X11R7.0-1.0.1">
4280 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libfontenc-X11R7.0-1.0.1.tar.bz2"
4281 size="211589" md5sum="d7971cbb2d1000737bba86a4bd70b900"/>
4282 <dependencies>
4283 <dep package="lib-libfontenc"/>
4284 </dependencies>
4285 </tarball>
4286 <tarball id="lib/libFS" version="X11R7.0-1.0.0">
4287 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libFS-X11R7.0-1.0.0.tar.bz2"
4288 size="229218" md5sum="12d2d89e7eb6ab0eb5823c3296f4e7a5"/>
4289 <dependencies>
4290 <dep package="lib-libFS"/>
4291 </dependencies>
4292 </tarball>
4293 <tarball id="lib/libICE" version="X11R7.0-1.0.0">
4294 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libICE-X11R7.0-1.0.0.tar.bz2"
4295 size="239843" md5sum="c778084b135311726da8dc74a16b3555"/>
4296 <dependencies>
4297 <dep package="lib-libICE"/>
4298 </dependencies>
4299 </tarball>
4300 <tarball id="lib/liblbxutil" version="X11R7.0-1.0.0">
4301 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/liblbxutil-X11R7.0-1.0.0.tar.bz2"
4302 size="222016" md5sum="1bcffde85723f78243d1ba60e1ebaef6"/>
4303 <dependencies>
4304 <dep package="lib-liblbxutil"/>
4305 </dependencies>
4306 </tarball>
4307 <tarball id="lib/liboldX" version="X11R7.0-1.0.1">
4308 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/liboldX-X11R7.0-1.0.1.tar.bz2"
4309 size="210365" md5sum="a443a2dc15aa96a3d18340a1617d1bae"/>
4310 <dependencies>
4311 <dep package="lib-liboldX"/>
4312 </dependencies>
4313 </tarball>
4314 <tarball id="lib/libSM" version="X11R7.0-1.0.0">
4315 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libSM-X11R7.0-1.0.0.tar.bz2"
4316 size="220369" md5sum="8a4eec299e8f14e26200718af7b2dcfc"/>
4317 <dependencies>
4318 <dep package="lib-libSM"/>
4319 </dependencies>
4320 </tarball>
4321 <tarball id="lib/libWindowsWM" version="X11R7.0-1.0.0">
4322 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libWindowsWM-X11R7.0-1.0.0.tar.bz2"
4323 size="211133" md5sum="d94f0389cd655b50e2987d5b988b82a5"/>
4324 <dependencies>
4325 <dep package="lib-libWindowsWM"/>
4326 </dependencies>
4327 </tarball>
4328 <tarball id="lib/libX11" version="X11R7.0-1.0.0">
4329 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libX11-X11R7.0-1.0.0.tar.bz2"
4330 size="1344417" md5sum="dcf59f148c978816ebbe3fbc5c9ef0e1"/>
4331 <dependencies>
4332 <dep package="lib-libX11"/>
4333 </dependencies>
4334 </tarball>
4335 <tarball id="lib/libXau" version="X11R7.0-1.0.0">
4336 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXau-X11R7.0-1.0.0.tar.bz2"
4337 size="213408" md5sum="51ceac78ae0eaf40ffb77b3cccc028cc"/>
4338 <dependencies>
4339 <dep package="lib-libXau"/>
4340 </dependencies>
4341 </tarball>
4342 <tarball id="lib/libXaw" version="X11R7.0-1.0.1">
4343 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXaw-X11R7.0-1.0.1.tar.bz2"
4344 size="502016" md5sum="ded3c7ed6d6ca2c5e257f60079a1a824"/>
4345 <dependencies>
4346 <dep package="lib-libXaw"/>
4347 </dependencies>
4348 </tarball>
4349 <tarball id="lib/libXcomposite" version="X11R7.0-0.2.2.2">
4350 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXcomposite-X11R7.0-0.2.2.2.tar.bz2"
4351 size="200827" md5sum="5773fe74d0f44b7264bd37c874efc7b1"/>
4352 <dependencies>
4353 <dep package="lib-libXcomposite"/>
4354 </dependencies>
4355 </tarball>
4356 <tarball id="lib/libXcursor" version="X11R7.0-1.1.5.2">
4357 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXcursor-X11R7.0-1.1.5.2.tar.bz2"
4358 size="225765" md5sum="048e15b725d8e081ac520e021af9a62c"/>
4359 <dependencies>
4360 <dep package="lib-libXcursor"/>
4361 </dependencies>
4362 </tarball>
4363 <tarball id="lib/libXdamage" version="X11R7.0-1.0.2.2">
4364 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXdamage-X11R7.0-1.0.2.2.tar.bz2"
4365 size="205151" md5sum="e98c6cc1075db5f6e7e6c8aef303c562"/>
4366 <dependencies>
4367 <dep package="lib-libXdamage"/>
4368 </dependencies>
4369 </tarball>
4370 <tarball id="lib/libXdmcp" version="X11R7.0-1.0.0">
4371 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXdmcp-X11R7.0-1.0.0.tar.bz2"
4372 size="211397" md5sum="509390dc46af61e3a6d07656fc5ad0ec"/>
4373 <dependencies>
4374 <dep package="lib-libXdmcp"/>
4375 </dependencies>
4376 </tarball>
4377 <tarball id="lib/libXevie" version="X11R7.0-1.0.0">
4378 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXevie-X11R7.0-1.0.0.tar.bz2"
4379 size="207641" md5sum="70b1787315d8d5f961edac05fef95fd6"/>
4380 <dependencies>
4381 <dep package="lib-libXevie"/>
4382 </dependencies>
4383 </tarball>
4384 <tarball id="lib/libXext" version="X11R7.0-1.0.0">
4385 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXext-X11R7.0-1.0.0.tar.bz2"
4386 size="250668" md5sum="9e47f574ac747446ac58ff9f6f402ceb"/>
4387 <dependencies>
4388 <dep package="lib-libXext"/>
4389 </dependencies>
4390 </tarball>
4391 <tarball id="lib/libXfixes" version="X11R7.0-3.0.1.2">
4392 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXfixes-X11R7.0-3.0.1.2.tar.bz2"
4393 size="209960" md5sum="5a027e5959dae32b69dce42118938544"/>
4394 <dependencies>
4395 <dep package="lib-libXfixes"/>
4396 </dependencies>
4397 </tarball>
4398 <tarball id="lib/libXfontcache" version="X11R7.0-1.0.1">
4399 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXfontcache-X11R7.0-1.0.1.tar.bz2"
4400 size="204829" md5sum="1e3c7718ffaf4f617d3f67ada5a7601e"/>
4401 <dependencies>
4402 <dep package="lib-libXfontcache"/>
4403 </dependencies>
4404 </tarball>
4405 <tarball id="lib/libXfont" version="X11R7.0-1.0.0">
4406 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXfont-X11R7.0-1.0.0.tar.bz2"
4407 size="586748" md5sum="955c41694772c9fd214e3e206f5d2178"/>
4408 <dependencies>
4409 <dep package="lib-libXfont"/>
4410 </dependencies>
4411 </tarball>
4412 <tarball id="lib/libXft" version="X11R7.0-2.1.8.2">
4413 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXft-X11R7.0-2.1.8.2.tar.bz2"
4414 size="248233" md5sum="c42292b35325a9eeb24eb0f8d3a6ec52"/>
4415 <dependencies>
4416 <dep package="lib-libXft"/>
4417 </dependencies>
4418 </tarball>
4419 <tarball id="lib/libXinerama" version="X11R7.0-1.0.1">
4420 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXinerama-X11R7.0-1.0.1.tar.bz2"
4421 size="201413" md5sum="1a1be870bb106193a4acc73c8c584dbc"/>
4422 <dependencies>
4423 <dep package="lib-libXinerama"/>
4424 </dependencies>
4425 </tarball>
4426 <tarball id="lib/libXi" version="X11R7.0-1.0.0">
4427 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXi-X11R7.0-1.0.0.tar.bz2"
4428 size="239015" md5sum="99503799b4d52ec0cac8e203341bb7b3"/>
4429 <dependencies>
4430 <dep package="lib-libXi"/>
4431 </dependencies>
4432 </tarball>
4433 <tarball id="lib/libxkbfile" version="X11R7.0-1.0.1">
4434 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libxkbfile-X11R7.0-1.0.1.tar.bz2"
4435 size="255310" md5sum="0b1bb70a1df474c26dd83feab52e733d"/>
4436 <dependencies>
4437 <dep package="lib-libxkbfile"/>
4438 </dependencies>
4439 </tarball>
4440 <tarball id="lib/libxkbui" version="X11R7.0-1.0.1">
4441 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libxkbui-X11R7.0-1.0.1.tar.bz2"
4442 size="203717" md5sum="1992547d377b510517fc7681207eead5"/>
4443 <dependencies>
4444 <dep package="lib-libxkbui"/>
4445 </dependencies>
4446 </tarball>
4447 <tarball id="lib/libXmu" version="X11R7.0-1.0.0">
4448 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXmu-X11R7.0-1.0.0.tar.bz2"
4449 size="279996" md5sum="df62f44da82c6780f07dc475a68dd9fa"/>
4450 <dependencies>
4451 <dep package="lib-libXmu"/>
4452 </dependencies>
4453 </tarball>
4454 <tarball id="lib/libXpm" version="X11R7.0-3.5.4.2">
4455 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXpm-X11R7.0-3.5.4.2.tar.bz2"
4456 size="329956" md5sum="f3b3b6e687f567bbff7688d60edc81ba"/>
4457 <dependencies>
4458 <dep package="lib-libXpm"/>
4459 </dependencies>
4460 </tarball>
4461 <tarball id="lib/libXprintAppUtil" version="X11R7.0-1.0.1">
4462 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXprintAppUtil-X11R7.0-1.0.1.tar.bz2"
4463 size="202104" md5sum="6d3f5d8d1f6c2c380bfc739128f41909"/>
4464 <dependencies>
4465 <dep package="lib-libXprintAppUtil"/>
4466 </dependencies>
4467 </tarball>
4468 <tarball id="lib/libXprintUtil" version="X11R7.0-1.0.1">
4469 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXprintUtil-X11R7.0-1.0.1.tar.bz2"
4470 size="215208" md5sum="47f1863042a53a48b40c2fb0aa55a8f7"/>
4471 <dependencies>
4472 <dep package="lib-libXprintUtil"/>
4473 </dependencies>
4474 </tarball>
4475 <tarball id="lib/libXp" version="X11R7.0-1.0.0">
4476 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXp-X11R7.0-1.0.0.tar.bz2"
4477 size="237834" md5sum="63c3048e06da4f6a033c5ce25217b0c3"/>
4478 <dependencies>
4479 <dep package="lib-libXp"/>
4480 </dependencies>
4481 </tarball>
4482 <tarball id="lib/libXrandr" version="X11R7.0-1.1.0.2">
4483 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXrandr-X11R7.0-1.1.0.2.tar.bz2"
4484 size="214724" md5sum="e10aed44c2e1e5d9e6848a62ff2c90c7"/>
4485 <dependencies>
4486 <dep package="lib-libXrandr"/>
4487 </dependencies>
4488 </tarball>
4489 <tarball id="lib/libXrender" version="X11R7.0-0.9.0.2">
4490 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXrender-X11R7.0-0.9.0.2.tar.bz2"
4491 size="221203" md5sum="3f0fa590dd84df07568631c91fbe68ab"/>
4492 <dependencies>
4493 <dep package="lib-libXrender"/>
4494 </dependencies>
4495 </tarball>
4496 <tarball id="lib/libXres" version="X11R7.0-1.0.0">
4497 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXres-X11R7.0-1.0.0.tar.bz2"
4498 size="209322" md5sum="cc5c4f130c9305e5bd973fbb7c56a254"/>
4499 <dependencies>
4500 <dep package="lib-libXres"/>
4501 </dependencies>
4502 </tarball>
4503 <tarball id="lib/libXScrnSaver" version="X11R7.0-1.0.1">
4504 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXScrnSaver-X11R7.0-1.0.1.tar.bz2"
4505 size="209914" md5sum="b9deb6ac3194aeab15d8f6220481af6d"/>
4506 <dependencies>
4507 <dep package="lib-libXScrnSaver"/>
4508 </dependencies>
4509 </tarball>
4510 <tarball id="lib/libXTrap" version="X11R7.0-1.0.0">
4511 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXTrap-X11R7.0-1.0.0.tar.bz2"
4512 size="214200" md5sum="8f2f1cc3b35f005e9030e162d89e2bdd"/>
4513 <dependencies>
4514 <dep package="lib-libXTrap"/>
4515 </dependencies>
4516 </tarball>
4517 <tarball id="lib/libXtst" version="X11R7.0-1.0.1">
4518 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXtst-X11R7.0-1.0.1.tar.bz2"
4519 size="207156" md5sum="3a3a3b88b4bc2a82f0b6de8ff526cc8c"/>
4520 <dependencies>
4521 <dep package="lib-libXtst"/>
4522 </dependencies>
4523 </tarball>
4524 <tarball id="lib/libXt" version="X11R7.0-1.0.0">
4525 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXt-X11R7.0-1.0.0.tar.bz2"
4526 size="482948" md5sum="d9c1c161f086a4d6c7510a924ee35c94"/>
4527 <dependencies>
4528 <dep package="lib-libXt"/>
4529 </dependencies>
4530 </tarball>
4531 <tarball id="lib/libXvMC" version="X11R7.0-1.0.1">
4532 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXvMC-X11R7.0-1.0.1.tar.bz2"
4533 size="212613" md5sum="c3eb4f526f08862489355a99e3eda1bd"/>
4534 <dependencies>
4535 <dep package="lib-libXvMC"/>
4536 </dependencies>
4537 </tarball>
4538 <tarball id="lib/libXv" version="X11R7.0-1.0.1">
4539 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXv-X11R7.0-1.0.1.tar.bz2"
4540 size="217511" md5sum="9f0075619fc8d8df460be8aaa9d9ab5d"/>
4541 <dependencies>
4542 <dep package="lib-libXv"/>
4543 </dependencies>
4544 </tarball>
4545 <tarball id="lib/libXxf86dga" version="X11R7.0-1.0.0">
4546 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXxf86dga-X11R7.0-1.0.0.tar.bz2"
4547 size="214036" md5sum="d2154a588953d8db4ae6252ebc7db439"/>
4548 <dependencies>
4549 <dep package="lib-libXxf86dga"/>
4550 </dependencies>
4551 </tarball>
4552 <tarball id="lib/libXxf86misc" version="X11R7.0-1.0.0">
4553 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXxf86misc-X11R7.0-1.0.0.tar.bz2"
4554 size="205438" md5sum="338568c9ca48b801f314c89c97327397"/>
4555 <dependencies>
4556 <dep package="lib-libXxf86misc"/>
4557 </dependencies>
4558 </tarball>
4559 <tarball id="lib/libXxf86vm" version="X11R7.0-1.0.0">
4560 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/libXxf86vm-X11R7.0-1.0.0.tar.bz2"
4561 size="210002" md5sum="ed59db622581b33ec2a62e12b2f9c274"/>
4562 <dependencies>
4563 <dep package="lib-libXxf86vm"/>
4564 </dependencies>
4565 </tarball>
4566 <tarball id="lib/xtrans" version="X11R7.0-1.0.0">
4567 <source href="http://ftp.x.org/pub/X11R7.0/src/lib/xtrans-X11R7.0-1.0.0.tar.bz2"
4568 size="88972" md5sum="153642136a003871a9093c8103d6ac5a"/>
4569 <dependencies>
4570 <dep package="lib-xtrans"/>
4571 </dependencies>
4572 </tarball>
4573 <tarball id="proto/applewmproto" version="X11R7.0-1.0.3">
4574 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/applewmproto-X11R7.0-1.0.3.tar.bz2"
4575 size="38932" md5sum="2acf46c814a27c40acd3e448ed17fee3"/>
4576 <dependencies>
4577 <dep package="proto-applewmproto"/>
4578 </dependencies>
4579 </tarball>
4580 <tarball id="proto/bigreqsproto" version="X11R7.0-1.0.2">
4581 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/bigreqsproto-X11R7.0-1.0.2.tar.bz2"
4582 size="36662" md5sum="ec15d17e3f04ddb5870ef7239b4ab367"/>
4583 <dependencies>
4584 <dep package="proto-bigreqsproto"/>
4585 </dependencies>
4586 </tarball>
4587 <tarball id="proto/compositeproto" version="X11R7.0-0.2.2">
4588 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/compositeproto-X11R7.0-0.2.2.tar.bz2"
4589 size="37336" md5sum="4de13ee64fdfd409134dfee9b184e6a9"/>
4590 <dependencies>
4591 <dep package="proto-compositeproto"/>
4592 </dependencies>
4593 </tarball>
4594 <tarball id="proto/damageproto" version="X11R7.0-1.0.3">
4595 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/damageproto-X11R7.0-1.0.3.tar.bz2"
4596 size="37637" md5sum="b906344d68e09a5639deb0097bd74224"/>
4597 <dependencies>
4598 <dep package="proto-damageproto"/>
4599 </dependencies>
4600 </tarball>
4601 <tarball id="proto/dmxproto" version="X11R7.0-2.2.2">
4602 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/dmxproto-X11R7.0-2.2.2.tar.bz2"
4603 size="39332" md5sum="21c79302beb868a078490549f558cdcf"/>
4604 <dependencies>
4605 <dep package="proto-dmxproto"/>
4606 </dependencies>
4607 </tarball>
4608 <tarball id="proto/evieext" version="X11R7.0-1.0.2">
4609 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/evieext-X11R7.0-1.0.2.tar.bz2"
4610 size="37487" md5sum="411c0d4f9eaa7d220a8d13edc790e3de"/>
4611 <dependencies>
4612 <dep package="proto-evieext"/>
4613 </dependencies>
4614 </tarball>
4615 <tarball id="proto/fixesproto" version="X11R7.0-3.0.2">
4616 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/fixesproto-X11R7.0-3.0.2.tar.bz2"
4617 size="38756" md5sum="ff8899d2325ed8a5787cde372ca8f80f"/>
4618 <dependencies>
4619 <dep package="proto-fixesproto"/>
4620 </dependencies>
4621 </tarball>
4622 <tarball id="proto/fontcacheproto" version="X11R7.0-0.1.2">
4623 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/fontcacheproto-X11R7.0-0.1.2.tar.bz2"
4624 size="38175" md5sum="116997d63cf6f65b75593ff5ae7afecb"/>
4625 <dependencies>
4626 <dep package="proto-fontcacheproto"/>
4627 </dependencies>
4628 </tarball>
4629 <tarball id="proto/fontsproto" version="X11R7.0-2.0.2">
4630 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/fontsproto-X11R7.0-2.0.2.tar.bz2"
4631 size="45141" md5sum="e2ca22df3a20177f060f04f15b8ce19b"/>
4632 <dependencies>
4633 <dep package="proto-fontsproto"/>
4634 </dependencies>
4635 </tarball>
4636 <tarball id="proto/glproto" version="X11R7.0-1.4.3">
4637 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/glproto-X11R7.0-1.4.3.tar.bz2"
4638 size="53730" md5sum="0ecb98487d7457f0592298fe9b8688f0"/>
4639 <dependencies>
4640 <dep package="proto-glproto"/>
4641 </dependencies>
4642 </tarball>
4643 <tarball id="proto/inputproto" version="X11R7.0-1.3.2">
4644 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/inputproto-X11R7.0-1.3.2.tar.bz2"
4645 size="46316" md5sum="0da271f396bede5b8d09a61f6d1c4484"/>
4646 <dependencies>
4647 <dep package="proto-inputproto"/>
4648 </dependencies>
4649 </tarball>
4650 <tarball id="proto/kbproto" version="X11R7.0-1.0.2">
4651 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/kbproto-X11R7.0-1.0.2.tar.bz2"
4652 size="57988" md5sum="403f56d717b3fefe465ddd03d9c7bc81"/>
4653 <dependencies>
4654 <dep package="proto-kbproto"/>
4655 </dependencies>
4656 </tarball>
4657 <tarball id="proto/printproto" version="X11R7.0-1.0.3">
4658 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/printproto-X11R7.0-1.0.3.tar.bz2"
4659 size="43464" md5sum="15c629a109b074d669886b1c6b7b319e"/>
4660 <dependencies>
4661 <dep package="proto-printproto"/>
4662 </dependencies>
4663 </tarball>
4664 <tarball id="proto/randrproto" version="X11R7.0-1.1.2">
4665 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/randrproto-X11R7.0-1.1.2.tar.bz2"
4666 size="38331" md5sum="bcf36d524f6f50aa16ee8e183350f7b8"/>
4667 <dependencies>
4668 <dep package="proto-randrproto"/>
4669 </dependencies>
4670 </tarball>
4671 <tarball id="proto/recordproto" version="X11R7.0-1.13.2">
4672 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/recordproto-X11R7.0-1.13.2.tar.bz2"
4673 size="39255" md5sum="6f41a40e8cf4452f1c1725d46b08eb2e"/>
4674 <dependencies>
4675 <dep package="proto-recordproto"/>
4676 </dependencies>
4677 </tarball>
4678 <tarball id="proto/renderproto" version="X11R7.0-0.9.2">
4679 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/renderproto-X11R7.0-0.9.2.tar.bz2"
4680 size="40003" md5sum="a7f3be0960c92ecb6a06a1022fe957df"/>
4681 <dependencies>
4682 <dep package="proto-renderproto"/>
4683 </dependencies>
4684 </tarball>
4685 <tarball id="proto/resourceproto" version="X11R7.0-1.0.2">
4686 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/resourceproto-X11R7.0-1.0.2.tar.bz2"
4687 size="36828" md5sum="e13d7b0aa5c591224f073bbbd9d1b038"/>
4688 <dependencies>
4689 <dep package="proto-resourceproto"/>
4690 </dependencies>
4691 </tarball>
4692 <tarball id="proto/scrnsaverproto" version="X11R7.0-1.0.2">
4693 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/scrnsaverproto-X11R7.0-1.0.2.tar.bz2"
4694 size="38353" md5sum="3185971597710d8843d986da3271b83f"/>
4695 <dependencies>
4696 <dep package="proto-scrnsaverproto"/>
4697 </dependencies>
4698 </tarball>
4699 <tarball id="proto/trapproto" version="X11R7.0-3.4.3">
4700 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/trapproto-X11R7.0-3.4.3.tar.bz2"
4701 size="48801" md5sum="84ab290758d2c177df5924e10bff4835"/>
4702 <dependencies>
4703 <dep package="proto-trapproto"/>
4704 </dependencies>
4705 </tarball>
4706 <tarball id="proto/videoproto" version="X11R7.0-2.2.2">
4707 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/videoproto-X11R7.0-2.2.2.tar.bz2"
4708 size="42721" md5sum="de9e16a8a464531a54a36211d2f983bd"/>
4709 <dependencies>
4710 <dep package="proto-videoproto"/>
4711 </dependencies>
4712 </tarball>
4713 <tarball id="proto/windowswmproto" version="X11R7.0-1.0.3">
4714 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/windowswmproto-X11R7.0-1.0.3.tar.bz2"
4715 size="38828" md5sum="ea2f71075f68371fec22eb98a6af8074"/>
4716 <dependencies>
4717 <dep package="proto-windowswmproto"/>
4718 </dependencies>
4719 </tarball>
4720 <tarball id="proto/xcmiscproto" version="X11R7.0-1.1.2">
4721 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xcmiscproto-X11R7.0-1.1.2.tar.bz2"
4722 size="36766" md5sum="77f3ba0cbef119e0230d235507a1d916"/>
4723 <dependencies>
4724 <dep package="proto-xcmiscproto"/>
4725 </dependencies>
4726 </tarball>
4727 <tarball id="proto/xextproto" version="X11R7.0-7.0.2">
4728 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xextproto-X11R7.0-7.0.2.tar.bz2"
4729 size="68316" md5sum="c0e88fc3483d90a7fea6a399298d90ea"/>
4730 <dependencies>
4731 <dep package="proto-xextproto"/>
4732 </dependencies>
4733 </tarball>
4734 <tarball id="proto/xf86bigfontproto" version="X11R7.0-1.1.2">
4735 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86bigfontproto-X11R7.0-1.1.2.tar.bz2"
4736 size="37360" md5sum="5509d420a2bc898ca7d817cd8bf1b2a7"/>
4737 <dependencies>
4738 <dep package="proto-xf86bigfontproto"/>
4739 </dependencies>
4740 </tarball>
4741 <tarball id="proto/xf86dgaproto" version="X11R7.0-2.0.2">
4742 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86dgaproto-X11R7.0-2.0.2.tar.bz2"
4743 size="40016" md5sum="48ddcc6b764dba7e711f8e25596abdb0"/>
4744 <dependencies>
4745 <dep package="proto-xf86dgaproto"/>
4746 </dependencies>
4747 </tarball>
4748 <tarball id="proto/xf86driproto" version="X11R7.0-2.0.3">
4749 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86driproto-X11R7.0-2.0.3.tar.bz2"
4750 size="42797" md5sum="839a70dfb8d5b02bcfc24996ab99a618"/>
4751 <dependencies>
4752 <dep package="proto-xf86driproto"/>
4753 </dependencies>
4754 </tarball>
4755 <tarball id="proto/xf86miscproto" version="X11R7.0-0.9.2">
4756 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86miscproto-X11R7.0-0.9.2.tar.bz2"
4757 size="38412" md5sum="1cc082d8a6da5177ede354bedbacd4ed"/>
4758 <dependencies>
4759 <dep package="proto-xf86miscproto"/>
4760 </dependencies>
4761 </tarball>
4762 <tarball id="proto/xf86rushproto" version="X11R7.0-1.1.2">
4763 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86rushproto-X11R7.0-1.1.2.tar.bz2"
4764 size="37679" md5sum="1a6b258d72c3c3baccfd695d278e847c"/>
4765 <dependencies>
4766 <dep package="proto-xf86rushproto"/>
4767 </dependencies>
4768 </tarball>
4769 <tarball id="proto/xf86vidmodeproto" version="X11R7.0-2.2.2">
4770 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xf86vidmodeproto-X11R7.0-2.2.2.tar.bz2"
4771 size="39489" md5sum="475f19a2ffbfab9a0886791c5f89c978"/>
4772 <dependencies>
4773 <dep package="proto-xf86vidmodeproto"/>
4774 </dependencies>
4775 </tarball>
4776 <tarball id="proto/xineramaproto" version="X11R7.0-1.1.2">
4777 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xineramaproto-X11R7.0-1.1.2.tar.bz2"
4778 size="38362" md5sum="80516ad305063f4e6c6c3ccf42ea2142"/>
4779 <dependencies>
4780 <dep package="proto-xineramaproto"/>
4781 </dependencies>
4782 </tarball>
4783 <tarball id="proto/xproto" version="X11R7.0-7.0.4">
4784 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xproto-X11R7.0-7.0.4.tar.bz2"
4785 size="127645" md5sum="643259d00e02db8e9a6f4c047281b5d9"/>
4786 <dependencies>
4787 <dep package="proto-xproto"/>
4788 </dependencies>
4789 </tarball>
4790 <tarball id="proto/xproxymanagementprotocol" version="X11R7.0-1.0.2">
4791 <source href="http://ftp.x.org/pub/X11R7.0/src/proto/xproxymanagementprotocol-X11R7.0-1.0.2.tar.bz2"
4792 size="36984" md5sum="977ee3fd1525418aaa8bfc55ffbf6fc9"/>
4793 <dependencies>
4794 <dep package="proto-xproxymanagementprotocol"/>
4795 </dependencies>
4796 </tarball>
4797 <tarball id="util/gccmakedep" version="X11R7.0-1.0.1">
4798 <source href="http://ftp.x.org/pub/X11R7.0/src/util/gccmakedep-X11R7.0-1.0.1.tar.bz2"
4799 size="66964" md5sum="328eea864d27b2d3a88ceb2fa66eca6d"/>
4800 <dependencies>
4801 <dep package="util-gccmakedep"/>
4802 </dependencies>
4803 </tarball>
4804 <tarball id="util/imake" version="X11R7.0-1.0.1">
4805 <source href="http://ftp.x.org/pub/X11R7.0/src/util/imake-X11R7.0-1.0.1.tar.bz2"
4806 size="108622" md5sum="487b4b86b2bd0c09e6d220a85d94efae"/>
4807 <dependencies>
4808 <dep package="util-imake"/>
4809 </dependencies>
4810 </tarball>
4811 <tarball id="util/lndir" version="X11R7.0-1.0.1">
4812 <source href="http://ftp.x.org/pub/X11R7.0/src/util/lndir-X11R7.0-1.0.1.tar.bz2"
4813 size="75972" md5sum="aa3616b9795e2445c85b2c79b0f94f7b"/>
4814 <dependencies>
4815 <dep package="util-lndir"/>
4816 </dependencies>
4817 </tarball>
4818 <tarball id="util/makedepend" version="X11R7.0-1.0.0">
4819 <source href="http://ftp.x.org/pub/X11R7.0/src/util/makedepend-X11R7.0-1.0.0.tar.bz2"
4820 size="103203" md5sum="7494c7ff65d8c31ef8db13661487b54c"/>
4821 <dependencies>
4822 <dep package="util-makedepend"/>
4823 </dependencies>
4824 </tarball>
4825 <tarball id="util/util-macros" version="X11R7.0-1.0.1">
4826 <source href="http://ftp.x.org/pub/X11R7.0/src/util/util-macros-X11R7.0-1.0.1.tar.bz2"
4827 size="38475" md5sum="bc6be634532d4936eb753de54e1663d3"/>
4828 <dependencies>
4829 <dep package="util-util-macros"/>
4830 </dependencies>
4831 </tarball>
4832 <tarball id="util/xorg-cf-files" version="X11R7.0-1.0.1">
4833 <source href="http://ftp.x.org/pub/X11R7.0/src/util/xorg-cf-files-X11R7.0-1.0.1.tar.bz2"
4834 size="252075" md5sum="f2dd453c37386293fb207431b4a073dd"/>
4835 <dependencies>
4836 <dep package="util-xorg-cf-files"/>
4837 </dependencies>
4838 </tarball>
4839 <tarball id="xserver/xorg-server" version="X11R7.0-1.0.1">
4840 <source href="http://ftp.x.org/pub/X11R7.0/src/xserver/xorg-server-X11R7.0-1.0.1.tar.bz2"
4841 size="5849840" md5sum="0e7527480fb845a3c2e333bd0f47ff50"/>
4842 <dependencies>
4843 <dep package="xserver-xorg-server"/>
4844 </dependencies>
4845 </tarball>
4846
4847</moduleset>
diff --git a/scripts/jhbuild/modulesets/xorg.modules b/scripts/jhbuild/modulesets/xorg.modules
new file mode 100644
index 0000000000..1429cf09e3
--- /dev/null
+++ b/scripts/jhbuild/modulesets/xorg.modules
@@ -0,0 +1,2201 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: nxml -*-->
2<!-- TODO: what to do about AppleWM and WindowsWM? -->
3<!-- TODO: what to do about doc/sgml-tools? -->
4<!-- TODO: util/cf has problems, commented out -->
5
6<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
7<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
8<moduleset>
9 <repository type="git" name="git.freedesktop.org"
10 href="git://anongit.freedesktop.org/git/"/>
11
12 <cvsroot name="fontconfig.freedesktop.org"
13 root=":pserver:anoncvs@cvs.freedesktop.org:/cvs/fontconfig"
14 password="" />
15
16 <autotools id="macros">
17 <branch repo="git.freedesktop.org" module="xorg/util/macros" checkoutdir="xorg/util/macros" />
18 </autotools>
19 <autotools id="makedepend">
20 <branch repo="git.freedesktop.org" module="xorg/util/makedepend" checkoutdir="xorg/util/makedepend" />
21 </autotools>
22 <autotools id="cf">
23 <branch repo="git.freedesktop.org" module="xorg/util/cf" checkoutdir="xorg/util/cf" />
24 </autotools>
25 <autotools id="imake">
26 <branch repo="git.freedesktop.org" module="xorg/util/imake" checkoutdir="xorg/util/imake" />
27 <dependencies>
28 <!-- <dep package="util/cf"/> -->
29 </dependencies>
30 </autotools>
31
32 <autotools id="bigreqsproto">
33 <branch repo="git.freedesktop.org" module="xorg/proto/bigreqsproto" checkoutdir="xorg/proto/bigreqsproto" />
34 </autotools>
35 <autotools id="compositeproto">
36 <branch repo="git.freedesktop.org" module="xorg/proto/compositeproto" checkoutdir="xorg/proto/compositeproto" />
37 </autotools>
38 <autotools id="damageproto">
39 <branch repo="git.freedesktop.org" module="xorg/proto/damageproto" checkoutdir="xorg/proto/damageproto" />
40 </autotools>
41 <autotools id="dmxproto">
42 <branch repo="git.freedesktop.org" module="xorg/proto/dmxproto" checkoutdir="xorg/proto/dmxproto" />
43 </autotools>
44 <autotools id="evieproto">
45 <branch repo="git.freedesktop.org" module="xorg/proto/evieproto" checkoutdir="xorg/proto/evieproto" />
46 </autotools>
47 <autotools id="fixesproto">
48 <branch repo="git.freedesktop.org" module="xorg/proto/fixesproto" checkoutdir="xorg/proto/fixesproto" />
49 </autotools>
50 <autotools id="fontcacheproto">
51 <branch repo="git.freedesktop.org" module="xorg/proto/fontcacheproto" checkoutdir="xorg/proto/fontcacheproto" />
52 </autotools>
53 <autotools id="fontsproto">
54 <branch repo="git.freedesktop.org" module="xorg/proto/fontsproto" checkoutdir="xorg/proto/fontsproto" />
55 </autotools>
56 <autotools id="glproto">
57 <branch repo="git.freedesktop.org" module="xorg/proto/glproto" checkoutdir="xorg/proto/glproto" />
58 </autotools>
59 <autotools id="inputproto">
60 <branch repo="git.freedesktop.org" module="xorg/proto/inputproto" checkoutdir="xorg/proto/inputproto" />
61 </autotools>
62 <autotools id="kbproto">
63 <branch repo="git.freedesktop.org" module="xorg/proto/kbproto" checkoutdir="xorg/proto/kbproto" />
64 </autotools>
65 <autotools id="pmproto">
66 <branch repo="git.freedesktop.org" module="xorg/proto/pmproto" checkoutdir="xorg/proto/pmproto" />
67 </autotools>
68 <autotools id="printproto">
69 <branch repo="git.freedesktop.org" module="xorg/proto/printproto" checkoutdir="xorg/proto/printproto" />
70 </autotools>
71 <autotools id="randrproto">
72 <branch repo="git.freedesktop.org" module="xorg/proto/randrproto" checkoutdir="xorg/proto/randrproto" />
73 </autotools>
74 <autotools id="recordproto">
75 <branch repo="git.freedesktop.org" module="xorg/proto/recordproto" checkoutdir="xorg/proto/recordproto" />
76 </autotools>
77 <autotools id="renderproto">
78 <branch repo="git.freedesktop.org" module="xorg/proto/renderproto" checkoutdir="xorg/proto/renderproto" />
79 </autotools>
80 <autotools id="resourceproto">
81 <branch repo="git.freedesktop.org" module="xorg/proto/resourceproto" checkoutdir="xorg/proto/resourceproto" />
82 </autotools>
83 <autotools id="scrnsaverproto">
84 <branch repo="git.freedesktop.org" module="xorg/proto/scrnsaverproto" checkoutdir="xorg/proto/scrnsaverproto" />
85 </autotools>
86 <autotools id="trapproto">
87 <branch repo="git.freedesktop.org" module="xorg/proto/trapproto" checkoutdir="xorg/proto/trapproto" />
88 </autotools>
89 <autotools id="videoproto">
90 <branch repo="git.freedesktop.org" module="xorg/proto/videoproto" checkoutdir="xorg/proto/videoproto" />
91 </autotools>
92 <autotools id="windowswmproto">
93 <branch repo="git.freedesktop.org" module="xorg/proto/windowswmproto" checkoutdir="xorg/proto/windowswmproto" />
94 </autotools>
95 <autotools id="xcmiscproto">
96 <branch repo="git.freedesktop.org" module="xorg/proto/xcmiscproto" checkoutdir="xorg/proto/xcmiscproto" />
97 </autotools>
98 <autotools id="xextproto">
99 <branch repo="git.freedesktop.org" module="xorg/proto/xextproto" checkoutdir="xorg/proto/xextproto" />
100 </autotools>
101 <autotools id="xf86bigfontproto">
102 <branch repo="git.freedesktop.org" module="xorg/proto/xf86bigfontproto" checkoutdir="xorg/proto/xf86bigfontproto" />
103 </autotools>
104 <autotools id="xf86dgaproto">
105 <branch repo="git.freedesktop.org" module="xorg/proto/xf86dgaproto" checkoutdir="xorg/proto/xf86dgaproto" />
106 </autotools>
107 <autotools id="xf86driproto">
108 <branch repo="git.freedesktop.org" module="xorg/proto/xf86driproto" checkoutdir="xorg/proto/xf86driproto" />
109 </autotools>
110 <autotools id="xf86miscproto">
111 <branch repo="git.freedesktop.org" module="xorg/proto/xf86miscproto" checkoutdir="xorg/proto/xf86miscproto" />
112 </autotools>
113 <autotools id="xf86rushproto">
114 <branch repo="git.freedesktop.org" module="xorg/proto/xf86rushproto" checkoutdir="xorg/proto/xf86rushproto" />
115 </autotools>
116 <autotools id="xf86vidmodeproto">
117 <branch repo="git.freedesktop.org" module="xorg/proto/xf86vidmodeproto" checkoutdir="xorg/proto/xf86vidmodeproto" />
118 </autotools>
119 <autotools id="xineramaproto">
120 <branch repo="git.freedesktop.org" module="xorg/proto/xineramaproto" checkoutdir="xorg/proto/xineramaproto" />
121 </autotools>
122 <autotools id="x11proto">
123 <branch repo="git.freedesktop.org" module="xorg/proto/x11proto" checkoutdir="xorg/proto/x11proto" />
124 </autotools>
125
126 <metamodule id="xorg-protos">
127 <dependencies>
128 <dep package="bigreqsproto"/>
129 <dep package="compositeproto"/>
130 <dep package="damageproto"/>
131 <dep package="dmxproto"/>
132 <dep package="evieproto"/>
133 <dep package="fixesproto"/>
134 <dep package="fontcacheproto"/>
135 <dep package="fontsproto"/>
136 <dep package="glproto"/>
137 <dep package="inputproto"/>
138 <dep package="kbproto"/>
139 <dep package="xineramaproto"/>
140 <dep package="printproto"/>
141 <dep package="randrproto"/>
142 <dep package="recordproto"/>
143 <dep package="renderproto"/>
144 <dep package="resourceproto"/>
145 <dep package="scrnsaverproto"/>
146 <dep package="trapproto"/>
147 <dep package="videoproto"/>
148 <dep package="xcmiscproto"/>
149 <dep package="xextproto"/>
150 <dep package="xf86bigfontproto"/>
151 <dep package="xf86dgaproto"/>
152 <dep package="xf86driproto"/>
153 <dep package="xf86miscproto"/>
154 <dep package="xf86rushproto"/>
155 <dep package="xf86vidmodeproto"/>
156 <dep package="x11proto"/>
157 <dep package="pmproto"/>
158 </dependencies>
159 </metamodule>
160
161 <!-- libs -->
162
163 <autotools id="libFS">
164 <branch repo="git.freedesktop.org" module="xorg/lib/libFS" checkoutdir="xorg/lib/libFS" />
165 <dependencies>
166 <dep package="macros"/>
167 <dep package="x11proto"/>
168 <dep package="fontsproto"/>
169 <dep package="libxtrans"/>
170 </dependencies>
171 </autotools>
172
173 <autotools id="libICE">
174 <branch repo="git.freedesktop.org" module="xorg/lib/libICE" checkoutdir="xorg/lib/libICE" />
175 <dependencies>
176 <dep package="macros"/>
177 <dep package="x11proto"/>
178 <dep package="libxtrans"/>
179 </dependencies>
180 </autotools>
181
182 <autotools id="libSM">
183 <branch repo="git.freedesktop.org" module="xorg/lib/libSM" checkoutdir="xorg/lib/libSM" />
184 <dependencies>
185 <dep package="macros"/>
186 <dep package="x11proto"/>
187 <dep package="libICE"/>
188 <dep package="libxtrans"/>
189 </dependencies>
190 </autotools>
191
192 <autotools id="libX11">
193 <branch repo="git.freedesktop.org" module="xorg/lib/libX11" checkoutdir="xorg/lib/libX11" />
194 <dependencies>
195 <dep package="macros"/>
196 <dep package="x11proto"/>
197 <dep package="bigreqsproto"/>
198 <dep package="xextproto"/>
199 <dep package="libxtrans"/>
200 <dep package="libXau"/>
201 <dep package="xcmiscproto"/>
202 <dep package="libXdmcp"/>
203 <dep package="kbproto"/>
204 <dep package="inputproto"/>
205 </dependencies>
206 </autotools>
207
208 <autotools id="libXScrnSaver">
209 <branch repo="git.freedesktop.org" module="xorg/lib/libXScrnSaver" checkoutdir="xorg/lib/libXScrnSaver" />
210 <dependencies>
211 <dep package="macros"/>
212 <dep package="libX11"/>
213 <dep package="libXext"/>
214 <dep package="xextproto"/>
215 <dep package="scrnsaverproto"/>
216 </dependencies>
217 </autotools>
218
219 <autotools id="libXTrap">
220 <branch repo="git.freedesktop.org" module="xorg/lib/libXTrap" checkoutdir="xorg/lib/libXTrap" />
221 <dependencies>
222 <dep package="macros"/>
223 <dep package="libX11"/>
224 <dep package="libXt"/>
225 <dep package="trapproto"/>
226 <dep package="libXext"/>
227 <dep package="xextproto"/>
228 </dependencies>
229 </autotools>
230
231 <autotools id="libXau">
232 <branch repo="git.freedesktop.org" module="xorg/lib/libXau" checkoutdir="xorg/lib/libXau" />
233 <dependencies>
234 <dep package="macros"/>
235 <dep package="x11proto"/>
236 </dependencies>
237 </autotools>
238
239 <autotools id="libXaw">
240 <branch repo="git.freedesktop.org" module="xorg/lib/libXaw" checkoutdir="xorg/lib/libXaw" />
241 <dependencies>
242 <dep package="macros"/>
243 <dep package="x11proto"/>
244 <dep package="libX11"/>
245 <dep package="libXt"/>
246 <dep package="libXmu"/>
247 <dep package="libXpm"/>
248 </dependencies>
249 </autotools>
250
251 <autotools id="libXcomposite">
252 <branch repo="git.freedesktop.org" module="xorg/lib/libXcomposite" checkoutdir="xorg/lib/libXcomposite" />
253 <dependencies>
254 <dep package="macros"/>
255 <dep package="compositeproto"/>
256 <dep package="libX11"/>
257 <dep package="libXfixes"/>
258 <dep package="libXext"/>
259 </dependencies>
260 </autotools>
261
262 <autotools id="libXcursor">
263 <branch repo="git.freedesktop.org" module="xorg/lib/libXcursor" checkoutdir="xorg/lib/libXcursor" />
264 <dependencies>
265 <dep package="macros"/>
266 <dep package="libXrender"/>
267 <dep package="libX11"/>
268 <dep package="libXfixes"/>
269 </dependencies>
270 </autotools>
271
272 <autotools id="libXdamage">
273 <branch repo="git.freedesktop.org" module="xorg/lib/libXdamage" checkoutdir="xorg/lib/libXdamage" />
274 <dependencies>
275 <dep package="macros"/>
276 <dep package="libX11"/>
277 <dep package="damageproto"/>
278 <dep package="libXfixes"/>
279 </dependencies>
280 </autotools>
281
282 <autotools id="libXdmcp">
283 <branch repo="git.freedesktop.org" module="xorg/lib/libXdmcp" checkoutdir="xorg/lib/libXdmcp" />
284 <dependencies>
285 <dep package="macros"/>
286 <dep package="x11proto"/>
287 </dependencies>
288 </autotools>
289
290 <autotools id="libXevie">
291 <branch repo="git.freedesktop.org" module="xorg/lib/libXevie" checkoutdir="xorg/lib/libXevie" />
292 <dependencies>
293 <dep package="macros"/>
294 <dep package="x11proto"/>
295 <dep package="libX11"/>
296 <dep package="xextproto"/>
297 <dep package="libXext"/>
298 <dep package="evieproto"/>
299 </dependencies>
300 </autotools>
301
302 <autotools id="libXext">
303 <branch repo="git.freedesktop.org" module="xorg/lib/libXext" checkoutdir="xorg/lib/libXext" />
304 <dependencies>
305 <dep package="macros"/>
306 <dep package="x11proto"/>
307 <dep package="libX11"/>
308 <dep package="xextproto"/>
309 </dependencies>
310 </autotools>
311
312 <autotools id="libXfixes">
313 <branch repo="git.freedesktop.org" module="xorg/lib/libXfixes" checkoutdir="xorg/lib/libXfixes" />
314 <dependencies>
315 <dep package="macros"/>
316 <dep package="libX11"/>
317 <dep package="fixesproto"/>
318 </dependencies>
319 </autotools>
320
321 <autotools id="libXfont">
322 <branch repo="git.freedesktop.org" module="xorg/lib/libXfont" checkoutdir="xorg/lib/libXfont" />
323 <dependencies>
324 <dep package="macros"/>
325 <dep package="x11proto"/>
326 <dep package="libxtrans"/>
327 <dep package="fontsproto"/>
328 <dep package="libfontenc"/>
329 <dep package="fontcacheproto"/>
330 </dependencies>
331 </autotools>
332
333 <autotools id="libXfontcache">
334 <branch repo="git.freedesktop.org" module="xorg/lib/libXfontcache" checkoutdir="xorg/lib/libXfontcache" />
335 <dependencies>
336 <dep package="macros"/>
337 <dep package="libX11"/>
338 <dep package="libXext"/>
339 <dep package="xextproto"/>
340 <dep package="fontcacheproto"/>
341 </dependencies>
342 </autotools>
343
344 <cvsmodule id="fontconfig" cvsroot="fontconfig.freedesktop.org" />
345
346 <autotools id="libXft">
347 <branch repo="git.freedesktop.org" module="xorg/lib/libXft" checkoutdir="xorg/lib/libXft" />
348 <dependencies>
349 <dep package="macros"/>
350 <dep package="libXrender"/>
351 <dep package="fontconfig"/>
352 </dependencies>
353 </autotools>
354
355 <autotools id="libXi">
356 <branch repo="git.freedesktop.org" module="xorg/lib/libXi" checkoutdir="xorg/lib/libXi" />
357 <dependencies>
358 <dep package="macros"/>
359 <dep package="x11proto"/>
360 <dep package="libX11"/>
361 <dep package="xextproto"/>
362 <dep package="libXext"/>
363 <dep package="inputproto"/>
364 </dependencies>
365 </autotools>
366
367 <autotools id="libXinerama">
368 <branch repo="git.freedesktop.org" module="xorg/lib/libXinerama" checkoutdir="xorg/lib/libXinerama" />
369 <dependencies>
370 <dep package="macros"/>
371 <dep package="libX11"/>
372 <dep package="libXext"/>
373 <dep package="xextproto"/>
374 <dep package="xineramaproto"/>
375 </dependencies>
376 </autotools>
377
378 <autotools id="libXmu">
379 <branch repo="git.freedesktop.org" module="xorg/lib/libXmu" checkoutdir="xorg/lib/libXmu" />
380 <dependencies>
381 <dep package="macros"/>
382 <dep package="libX11"/>
383 <dep package="libXt"/>
384 <dep package="libXext"/>
385 </dependencies>
386 </autotools>
387
388 <autotools id="libXp">
389 <branch repo="git.freedesktop.org" module="xorg/lib/libXp" checkoutdir="xorg/lib/libXp" />
390 <dependencies>
391 <dep package="macros"/>
392 <dep package="libX11"/>
393 <dep package="libXext"/>
394 <dep package="libXau"/>
395 <dep package="printproto"/>
396 </dependencies>
397 </autotools>
398
399 <autotools id="libXpm">
400 <branch repo="git.freedesktop.org" module="xorg/lib/libXpm" checkoutdir="xorg/lib/libXpm" />
401 <dependencies>
402 <dep package="macros"/>
403 <dep package="libX11"/>
404 <dep package="x11proto"/>
405 <dep package="libXt"/>
406 <dep package="libXext"/>
407 </dependencies>
408 </autotools>
409
410 <autotools id="libXprintAppUtil">
411 <branch repo="git.freedesktop.org" module="xorg/lib/libXprintAppUtil" checkoutdir="xorg/lib/libXprintAppUtil" />
412 <dependencies>
413 <dep package="macros"/>
414 <dep package="libX11"/>
415 <dep package="libXp"/>
416 <dep package="libXprintUtil"/>
417 </dependencies>
418 </autotools>
419
420 <autotools id="libXprintUtil">
421 <branch repo="git.freedesktop.org" module="xorg/lib/libXprintUtil" checkoutdir="xorg/lib/libXprintUtil" />
422 <dependencies>
423 <dep package="macros"/>
424 <dep package="libX11"/>
425 <dep package="libXp"/>
426 </dependencies>
427 </autotools>
428
429 <autotools id="libXrandr">
430 <branch repo="git.freedesktop.org" module="xorg/lib/libXrandr" checkoutdir="xorg/lib/libXrandr" />
431 <dependencies>
432 <dep package="macros"/>
433 <dep package="libX11"/>
434 <dep package="randrproto"/>
435 </dependencies>
436 </autotools>
437
438 <autotools id="libXrender">
439 <branch repo="git.freedesktop.org" module="xorg/lib/libXrender" checkoutdir="xorg/lib/libXrender" />
440 <dependencies>
441 <dep package="macros"/>
442 <dep package="renderproto"/>
443 <dep package="libX11"/>
444 </dependencies>
445 </autotools>
446
447 <autotools id="libXRes">
448 <branch repo="git.freedesktop.org" module="xorg/lib/libXRes" checkoutdir="xorg/lib/libXRes" />
449 <dependencies>
450 <dep package="macros"/>
451 <dep package="libX11"/>
452 <dep package="libXext"/>
453 <dep package="resourceproto"/>
454 </dependencies>
455 </autotools>
456
457 <autotools id="libXt">
458 <branch repo="git.freedesktop.org" module="xorg/lib/libXt" checkoutdir="xorg/lib/libXt" />
459 <dependencies>
460 <dep package="macros"/>
461 <dep package="libSM"/>
462 <dep package="libX11"/>
463 <dep package="x11proto"/>
464 </dependencies>
465 </autotools>
466
467 <autotools id="libXtst">
468 <branch repo="git.freedesktop.org" module="xorg/lib/libXtst" checkoutdir="xorg/lib/libXtst" />
469 <dependencies>
470 <dep package="macros"/>
471 <dep package="libX11"/>
472 <dep package="libXext"/>
473 <dep package="recordproto"/>
474 <dep package="xextproto"/>
475 </dependencies>
476 </autotools>
477
478 <autotools id="libXv">
479 <branch repo="git.freedesktop.org" module="xorg/lib/libXv" checkoutdir="xorg/lib/libXv" />
480 <dependencies>
481 <dep package="macros"/>
482 <dep package="libX11"/>
483 <dep package="libXext"/>
484 <dep package="xextproto"/>
485 <dep package="videoproto"/>
486 </dependencies>
487 </autotools>
488
489 <autotools id="libXvMC">
490 <branch repo="git.freedesktop.org" module="xorg/lib/libXvMC" checkoutdir="xorg/lib/libXvMC" />
491 <dependencies>
492 <dep package="macros"/>
493 <dep package="libX11"/>
494 <dep package="libXext"/>
495 <dep package="libXv"/>
496 <dep package="xextproto"/>
497 <dep package="videoproto"/>
498 </dependencies>
499 </autotools>
500
501 <autotools id="libXxf86dga">
502 <branch repo="git.freedesktop.org" module="xorg/lib/libXxf86dga" checkoutdir="xorg/lib/libXxf86dga" />
503 <dependencies>
504 <dep package="macros"/>
505 <dep package="x11proto"/>
506 <dep package="libX11"/>
507 <dep package="libXext"/>
508 <dep package="xextproto"/>
509 <dep package="xf86dgaproto"/>
510 </dependencies>
511 </autotools>
512
513 <autotools id="libXxf86misc">
514 <branch repo="git.freedesktop.org" module="xorg/lib/libXxf86misc" checkoutdir="xorg/lib/libXxf86misc" />
515 <dependencies>
516 <dep package="macros"/>
517 <dep package="x11proto"/>
518 <dep package="libX11"/>
519 <dep package="libXext"/>
520 <dep package="xextproto"/>
521 <dep package="xf86miscproto"/>
522 </dependencies>
523 </autotools>
524
525 <autotools id="libXxf86vm">
526 <branch repo="git.freedesktop.org" module="xorg/lib/libXxf86vm" checkoutdir="xorg/lib/libXxf86vm" />
527 <dependencies>
528 <dep package="macros"/>
529 <dep package="x11proto"/>
530 <dep package="libX11"/>
531 <dep package="libXext"/>
532 <dep package="xextproto"/>
533 <dep package="xf86vidmodeproto"/>
534 </dependencies>
535 </autotools>
536
537 <autotools id="libdmx">
538 <branch repo="git.freedesktop.org" module="xorg/lib/libdmx" checkoutdir="xorg/lib/libdmx" />
539 <dependencies>
540 <dep package="macros"/>
541 <dep package="libX11"/>
542 <dep package="libXext"/>
543 <dep package="xextproto"/>
544 <dep package="dmxproto"/>
545 </dependencies>
546 </autotools>
547
548 <autotools id="libfontenc">
549 <branch repo="git.freedesktop.org" module="xorg/lib/libfontenc" checkoutdir="xorg/lib/libfontenc" />
550 <dependencies>
551 <dep package="macros"/>
552 <dep package="x11proto"/>
553 </dependencies>
554 </autotools>
555
556 <autotools id="liblbxutil">
557 <branch repo="git.freedesktop.org" module="xorg/lib/liblbxutil" checkoutdir="xorg/lib/liblbxutil" />
558 <dependencies>
559 <dep package="macros"/>
560 <dep package="xextproto"/>
561 </dependencies>
562 </autotools>
563
564 <autotools id="liboldX">
565 <branch repo="git.freedesktop.org" module="xorg/lib/liboldX" checkoutdir="xorg/lib/liboldX" />
566 <dependencies>
567 <dep package="macros"/>
568 <dep package="libX11"/>
569 </dependencies>
570 </autotools>
571
572 <autotools id="libxkbfile">
573 <branch repo="git.freedesktop.org" module="xorg/lib/libxkbfile" checkoutdir="xorg/lib/libxkbfile" />
574 <dependencies>
575 <dep package="macros"/>
576 <dep package="libX11"/>
577 <dep package="kbproto"/>
578 </dependencies>
579 </autotools>
580
581 <autotools id="libxkbui">
582 <branch repo="git.freedesktop.org" module="xorg/lib/libxkbui" checkoutdir="xorg/lib/libxkbui" />
583 <dependencies>
584 <dep package="macros"/>
585 <dep package="libX11"/>
586 <dep package="libXt"/>
587 <dep package="libxkbfile"/>
588 </dependencies>
589 </autotools>
590
591 <autotools id="libxtrans">
592 <branch repo="git.freedesktop.org" module="xorg/lib/libxtrans" checkoutdir="xorg/lib/libxtrans"/>
593 <dependencies>
594 <dep package="macros"/>
595 </dependencies>
596 </autotools>
597
598 <autotools id="libdrm">
599 <branch repo="git.freedesktop.org" module="mesa/drm"/>
600 <dependencies>
601 <dep package="macros"/>
602 </dependencies>
603 </autotools>
604
605 <metamodule id="xorg-libs">
606 <dependencies>
607 <dep package="libFS"/>
608 <dep package="libICE"/>
609 <dep package="libSM"/>
610 <dep package="libX11"/>
611 <dep package="libXScrnSaver"/>
612 <dep package="libXTrap"/>
613 <dep package="libXau"/>
614 <dep package="libXaw"/>
615 <dep package="libXcomposite"/>
616 <dep package="libXcursor"/>
617 <dep package="libXdamage"/>
618 <dep package="libXdmcp"/>
619 <dep package="libXevie"/>
620 <dep package="libXext"/>
621 <dep package="libXfixes"/>
622 <dep package="libXfont"/>
623 <dep package="libXfontcache"/>
624 <dep package="libXft"/>
625 <dep package="libXi"/>
626 <dep package="libXinerama"/>
627 <dep package="libXmu"/>
628 <dep package="libXp"/>
629 <dep package="libXpm"/>
630 <dep package="libXprintAppUtil"/>
631 <dep package="libXprintUtil"/>
632 <dep package="libXrandr"/>
633 <dep package="libXrender"/>
634 <dep package="libXRes"/>
635 <dep package="libXt"/>
636 <dep package="libXtst"/>
637 <dep package="libXv"/>
638 <dep package="libXvMC"/>
639 <dep package="libXxf86dga"/>
640 <dep package="libXxf86misc"/>
641 <dep package="libXxf86vm"/>
642 <dep package="libdmx"/>
643 <dep package="libfontenc"/>
644 <dep package="liblbxutil"/>
645 <dep package="liboldX"/>
646 <dep package="libxkbfile"/>
647 <dep package="libxkbui"/>
648 <dep package="libxtrans"/>
649 <dep package="libdrm"/>
650 </dependencies>
651 </metamodule>
652
653 <autotools id="xtrans">
654 <branch repo="git.freedesktop.org" module="xorg/lib/libxtrans" checkoutdir="xorg/lib/libxtrans" />
655 </autotools>
656
657 <autotools id="100dpi">
658 <branch repo="git.freedesktop.org" module="xorg/font/100dpi" checkoutdir="xorg/font/100dpi" />
659 <dependencies>
660 <dep package="util"/>
661 </dependencies>
662 </autotools>
663
664 <autotools id="adobe-100dpi">
665 <branch repo="git.freedesktop.org" module="xorg/font/adobe-100dpi" checkoutdir="xorg/font/adobe-100dpi" />
666 <dependencies>
667 <dep package="util"/>
668 </dependencies>
669 </autotools>
670
671 <autotools id="adobe-75dpi">
672 <branch repo="git.freedesktop.org" module="xorg/font/adobe-75dpi" checkoutdir="xorg/font/adobe-75dpi" />
673 <dependencies>
674 <dep package="util"/>
675 </dependencies>
676 </autotools>
677
678 <autotools id="adobe-utopia-100dpi">
679 <branch repo="git.freedesktop.org" module="xorg/font/adobe-utopia-100dpi" checkoutdir="xorg/font/adobe-utopia-100dpi" />
680 <dependencies>
681 <dep package="util"/>
682 </dependencies>
683 </autotools>
684
685 <autotools id="adobe-utopia-75dpi">
686 <branch repo="git.freedesktop.org" module="xorg/font/adobe-utopia-75dpi" checkoutdir="xorg/font/adobe-utopia-75dpi" />
687 <dependencies>
688 <dep package="util"/>
689 </dependencies>
690 </autotools>
691
692 <autotools id="adobe-utopia-type1">
693 <branch repo="git.freedesktop.org" module="xorg/font/adobe-utopia-type1" checkoutdir="xorg/font/adobe-utopia-type1" />
694 <dependencies>
695 <dep package="util"/>
696 </dependencies>
697 </autotools>
698
699 <autotools id="alias">
700 <branch repo="git.freedesktop.org" module="xorg/font/alias" checkoutdir="xorg/font/alias" />
701 <dependencies>
702 <dep package="util"/>
703 </dependencies>
704 </autotools>
705
706 <autotools id="arabic-misc">
707 <branch repo="git.freedesktop.org" module="xorg/font/arabic-misc" checkoutdir="xorg/font/arabic-misc" />
708 <dependencies>
709 <dep package="util"/>
710 </dependencies>
711 </autotools>
712
713 <autotools id="bh-100dpi">
714 <branch repo="git.freedesktop.org" module="xorg/font/bh-100dpi" checkoutdir="xorg/font/bh-100dpi" />
715 <dependencies>
716 <dep package="util"/>
717 </dependencies>
718 </autotools>
719
720 <autotools id="bh-75dpi">
721 <branch repo="git.freedesktop.org" module="xorg/font/bh-75dpi" checkoutdir="xorg/font/bh-75dpi" />
722 <dependencies>
723 <dep package="util"/>
724 </dependencies>
725 </autotools>
726
727 <autotools id="bh-lucidatypewriter-100dpi">
728 <branch repo="git.freedesktop.org" module="xorg/font/bh-lucidatypewriter-100dpi" checkoutdir="xorg/font/bh-lucidatypewriter-100dpi" />
729 <dependencies>
730 <dep package="util"/>
731 </dependencies>
732 </autotools>
733
734 <autotools id="bh-lucidatypewriter-75dpi">
735 <branch repo="git.freedesktop.org" module="xorg/font/bh-lucidatypewriter-75dpi" checkoutdir="xorg/font/bh-lucidatypewriter-75dpi" />
736 <dependencies>
737 <dep package="util"/>
738 </dependencies>
739 </autotools>
740
741 <autotools id="bh-ttf">
742 <branch repo="git.freedesktop.org" module="xorg/font/bh-ttf" checkoutdir="xorg/font/bh-ttf" />
743 <dependencies>
744 <dep package="util"/>
745 </dependencies>
746 </autotools>
747
748 <autotools id="bh-type1">
749 <branch repo="git.freedesktop.org" module="xorg/font/bh-type1" checkoutdir="xorg/font/bh-type1" />
750 <dependencies>
751 <dep package="util"/>
752 </dependencies>
753 </autotools>
754
755 <autotools id="bitstream-100dpi">
756 <branch repo="git.freedesktop.org" module="xorg/font/bitstream-100dpi" checkoutdir="xorg/font/bitstream-100dpi" />
757 <dependencies>
758 <dep package="util"/>
759 </dependencies>
760 </autotools>
761
762 <autotools id="bitstream-75dpi">
763 <branch repo="git.freedesktop.org" module="xorg/font/bitstream-75dpi" checkoutdir="xorg/font/bitstream-75dpi" />
764 <dependencies>
765 <dep package="util"/>
766 </dependencies>
767 </autotools>
768
769 <autotools id="bitstream-speedo">
770 <branch repo="git.freedesktop.org" module="xorg/font/bitstream-speedo" checkoutdir="xorg/font/bitstream-speedo" />
771 <dependencies>
772 <dep package="util"/>
773 </dependencies>
774 </autotools>
775
776 <autotools id="bitstream-type1">
777 <branch repo="git.freedesktop.org" module="xorg/font/bitstream-type1" checkoutdir="xorg/font/bitstream-type1" />
778 <dependencies>
779 <dep package="util"/>
780 </dependencies>
781 </autotools>
782
783 <autotools id="cronyx-cyrillic">
784 <branch repo="git.freedesktop.org" module="xorg/font/cronyx-cyrillic" checkoutdir="xorg/font/cronyx-cyrillic" />
785 <dependencies>
786 <dep package="util"/>
787 </dependencies>
788 </autotools>
789
790 <autotools id="cursor-misc">
791 <branch repo="git.freedesktop.org" module="xorg/font/cursor-misc" checkoutdir="xorg/font/cursor-misc" />
792 <dependencies>
793 <dep package="util"/>
794 </dependencies>
795 </autotools>
796
797 <autotools id="CVS">
798 <branch repo="git.freedesktop.org" module="xorg/font/CVS" checkoutdir="xorg/font/CVS" />
799 <dependencies>
800 <dep package="util"/>
801 </dependencies>
802 </autotools>
803
804 <autotools id="daewoo-misc">
805 <branch repo="git.freedesktop.org" module="xorg/font/daewoo-misc" checkoutdir="xorg/font/daewoo-misc" />
806 <dependencies>
807 <dep package="util"/>
808 </dependencies>
809 </autotools>
810
811 <autotools id="dec-misc">
812 <branch repo="git.freedesktop.org" module="xorg/font/dec-misc" checkoutdir="xorg/font/dec-misc" />
813 <dependencies>
814 <dep package="util"/>
815 </dependencies>
816 </autotools>
817
818 <autotools id="encodings">
819 <branch repo="git.freedesktop.org" module="xorg/font/encodings" checkoutdir="xorg/font/encodings" />
820 <dependencies>
821 <dep package="util"/>
822 </dependencies>
823 </autotools>
824
825 <autotools id="ibm-type1">
826 <branch repo="git.freedesktop.org" module="xorg/font/ibm-type1" checkoutdir="xorg/font/ibm-type1" />
827 <dependencies>
828 <dep package="util"/>
829 </dependencies>
830 </autotools>
831
832 <autotools id="isas-misc">
833 <branch repo="git.freedesktop.org" module="xorg/font/isas-misc" checkoutdir="xorg/font/isas-misc" />
834 <dependencies>
835 <dep package="util"/>
836 </dependencies>
837 </autotools>
838
839 <autotools id="jis-misc">
840 <branch repo="git.freedesktop.org" module="xorg/font/jis-misc" checkoutdir="xorg/font/jis-misc" />
841 <dependencies>
842 <dep package="util"/>
843 </dependencies>
844 </autotools>
845
846 <autotools id="micro-misc">
847 <branch repo="git.freedesktop.org" module="xorg/font/micro-misc" checkoutdir="xorg/font/micro-misc" />
848 <dependencies>
849 <dep package="util"/>
850 </dependencies>
851 </autotools>
852
853 <autotools id="misc-cyrillic">
854 <branch repo="git.freedesktop.org" module="xorg/font/misc-cyrillic" checkoutdir="xorg/font/misc-cyrillic" />
855 <dependencies>
856 <dep package="util"/>
857 </dependencies>
858 </autotools>
859
860 <autotools id="misc-ethiopic">
861 <branch repo="git.freedesktop.org" module="xorg/font/misc-ethiopic" checkoutdir="xorg/font/misc-ethiopic" />
862 <dependencies>
863 <dep package="util"/>
864 </dependencies>
865 </autotools>
866
867 <autotools id="misc-meltho">
868 <branch repo="git.freedesktop.org" module="xorg/font/misc-meltho" checkoutdir="xorg/font/misc-meltho" />
869 <dependencies>
870 <dep package="util"/>
871 </dependencies>
872 </autotools>
873
874 <autotools id="misc-misc">
875 <branch repo="git.freedesktop.org" module="xorg/font/misc-misc" checkoutdir="xorg/font/misc-misc" />
876 <dependencies>
877 <dep package="util"/>
878 </dependencies>
879 </autotools>
880
881 <autotools id="mutt-misc">
882 <branch repo="git.freedesktop.org" module="xorg/font/mutt-misc" checkoutdir="xorg/font/mutt-misc" />
883 <dependencies>
884 <dep package="util"/>
885 </dependencies>
886 </autotools>
887
888 <autotools id="schumacher-misc">
889 <branch repo="git.freedesktop.org" module="xorg/font/schumacher-misc" checkoutdir="xorg/font/schumacher-misc" />
890 <dependencies>
891 <dep package="util"/>
892 </dependencies>
893 </autotools>
894
895 <autotools id="screen-cyrillic">
896 <branch repo="git.freedesktop.org" module="xorg/font/screen-cyrillic" checkoutdir="xorg/font/screen-cyrillic" />
897 <dependencies>
898 <dep package="util"/>
899 </dependencies>
900 </autotools>
901
902 <autotools id="sony-misc">
903 <branch repo="git.freedesktop.org" module="xorg/font/sony-misc" checkoutdir="xorg/font/sony-misc" />
904 <dependencies>
905 <dep package="util"/>
906 </dependencies>
907 </autotools>
908
909 <autotools id="sun-misc">
910 <branch repo="git.freedesktop.org" module="xorg/font/sun-misc" checkoutdir="xorg/font/sun-misc" />
911 <dependencies>
912 <dep package="util"/>
913 </dependencies>
914 </autotools>
915
916 <autotools id="util">
917 <branch repo="git.freedesktop.org" module="xorg/font/util" checkoutdir="xorg/font/util" />
918 <dependencies>
919 <dep package="util"/>
920 </dependencies>
921 </autotools>
922
923 <autotools id="winitzki-cyrillic">
924 <branch repo="git.freedesktop.org" module="xorg/font/winitzki-cyrillic" checkoutdir="xorg/font/winitzki-cyrillic" />
925 <dependencies>
926 <dep package="util"/>
927 </dependencies>
928 </autotools>
929
930 <autotools id="xfree86-type1">
931 <branch repo="git.freedesktop.org" module="xorg/font/xfree86-type1" checkoutdir="xorg/font/xfree86-type1" />
932 <dependencies>
933 <dep package="util"/>
934 </dependencies>
935 </autotools>
936
937 <metamodule id="xorg-fonts">
938 <dependencies>
939 <dep package="encodings"/>
940 <dep package="adobe-75dpi"/>
941 <dep package="adobe-100dpi"/>
942 <dep package="adobe-utopia-75dpi"/>
943 <dep package="adobe-utopia-100dpi"/>
944 <dep package="adobe-utopia-type1"/>
945 <dep package="alias"/>
946 <dep package="arabic-misc"/>
947 <dep package="bh-75dpi"/>
948 <dep package="bh-100dpi"/>
949 <dep package="bh-lucidatypewriter-75dpi"/>
950 <dep package="bh-lucidatypewriter-100dpi"/>
951 <dep package="bh-ttf"/>
952 <dep package="bh-type1"/>
953 <dep package="bitstream-75dpi"/>
954 <dep package="bitstream-100dpi"/>
955 <dep package="bitstream-type1"/>
956 <dep package="cronyx-cyrillic"/>
957 <dep package="cursor-misc"/>
958 <dep package="daewoo-misc"/>
959 <dep package="dec-misc"/>
960 <dep package="ibm-type1"/>
961 <dep package="isas-misc"/>
962 <dep package="jis-misc"/>
963 <dep package="micro-misc"/>
964 <dep package="misc-cyrillic"/>
965 <dep package="misc-misc"/>
966 <dep package="mutt-misc"/>
967 </dependencies>
968 </metamodule>
969
970 <!-- data -->
971 <autotools id="bitmaps">
972 <branch repo="git.freedesktop.org" module="xorg/data/bitmaps" checkoutdir="xorg/data/bitmaps" />
973 <dependencies>
974 <dep package="macros"/>
975 </dependencies>
976 </autotools>
977
978 <autotools id="cursors">
979 <branch repo="git.freedesktop.org" module="xorg/data/cursors" checkoutdir="xorg/data/cursors" />
980 <dependencies>
981 <dep package="app/xcursorgen"/>
982 </dependencies>
983 </autotools>
984
985 <autotools id="xkbdata">
986 <branch repo="git.freedesktop.org" module="xorg/data/xkbdata" checkoutdir="xorg/data/xkbdata" />
987 <dependencies>
988 <dep package="app/xkbcomp"/>
989 </dependencies>
990 </autotools>
991
992 <!-- apps -->
993
994 <autotools id="appres">
995 <branch repo="git.freedesktop.org" module="xorg/app/appres" checkoutdir="xorg/app/appres" />
996 <dependencies>
997 <dep package="libXt"/>
998 </dependencies>
999 </autotools>
1000
1001 <autotools id="bdftopcf">
1002 <branch repo="git.freedesktop.org" module="xorg/app/bdftopcf" checkoutdir="xorg/app/bdftopcf" />
1003 <dependencies>
1004 <dep package="libXfont"/>
1005 </dependencies>
1006 </autotools>
1007
1008 <autotools id="beforelight">
1009 <branch repo="git.freedesktop.org" module="xorg/app/beforelight" checkoutdir="xorg/app/beforelight" />
1010 <dependencies>
1011 <dep package="libXScrnSaver"/>
1012 <dep package="libXt"/>
1013 </dependencies>
1014 </autotools>
1015
1016 <autotools id="bitmap">
1017 <branch repo="git.freedesktop.org" module="xorg/app/bitmap" checkoutdir="xorg/app/bitmap" />
1018 <dependencies>
1019 <dep package="libXaw"/>
1020 <dep package="libXmu"/>
1021 <dep package="bitmaps"/>
1022 </dependencies>
1023 </autotools>
1024
1025 <autotools id="editres">
1026 <branch repo="git.freedesktop.org" module="xorg/app/editres" checkoutdir="xorg/app/editres" />
1027 <dependencies>
1028 <dep package="libXaw"/>
1029 </dependencies>
1030 </autotools>
1031
1032 <autotools id="fonttosfnt">
1033 <branch repo="git.freedesktop.org" module="xorg/app/fonttosfnt" checkoutdir="xorg/app/fonttosfnt" />
1034 <dependencies>
1035 <dep package="libX11"/>
1036 <dep package="libfontenc"/>
1037 <!-- <dep package="freetype2"/> -->
1038 </dependencies>
1039 </autotools>
1040
1041 <autotools id="fslsfonts">
1042 <branch repo="git.freedesktop.org" module="xorg/app/fslsfonts" checkoutdir="xorg/app/fslsfonts" />
1043 <dependencies>
1044 <dep package="libX11"/>
1045 <dep package="libFS"/>
1046 </dependencies>
1047 </autotools>
1048
1049 <autotools id="fstobdf">
1050 <branch repo="git.freedesktop.org" module="xorg/app/fstobdf" checkoutdir="xorg/app/fstobdf" />
1051 <dependencies>
1052 <dep package="libX11"/>
1053 <dep package="libFS"/>
1054 </dependencies>
1055 </autotools>
1056
1057 <autotools id="iceauth">
1058 <branch repo="git.freedesktop.org" module="xorg/app/iceauth" checkoutdir="xorg/app/iceauth" />
1059 <dependencies>
1060 <dep package="libX11"/>
1061 <dep package="libICE"/>
1062 </dependencies>
1063 </autotools>
1064
1065 <autotools id="ico">
1066 <branch repo="git.freedesktop.org" module="xorg/app/ico" checkoutdir="xorg/app/ico" />
1067 <dependencies>
1068 <dep package="libX11"/>
1069 </dependencies>
1070 </autotools>
1071
1072 <autotools id="lbxproxy">
1073 <branch repo="git.freedesktop.org" module="xorg/app/lbxproxy" checkoutdir="xorg/app/lbxproxy" />
1074 <dependencies>
1075 <dep package="libxtrans"/>
1076 <dep package="libXext"/>
1077 <dep package="liblbxutil"/>
1078 <dep package="libX11"/>
1079 <dep package="libICE"/>
1080 <dep package="pmproto"/>
1081 </dependencies>
1082 </autotools>
1083
1084 <autotools id="listres">
1085 <branch repo="git.freedesktop.org" module="xorg/app/listres" checkoutdir="xorg/app/listres" />
1086 <dependencies>
1087 <dep package="libXaw"/>
1088 </dependencies>
1089 </autotools>
1090
1091 <autotools id="luit">
1092 <branch repo="git.freedesktop.org" module="xorg/app/luit" checkoutdir="xorg/app/luit" />
1093 <dependencies>
1094 <dep package="libX11"/>
1095 <dep package="libfontenc"/>
1096 </dependencies>
1097 </autotools>
1098
1099 <autotools id="mkcfm">
1100 <branch repo="git.freedesktop.org" module="xorg/app/mkcfm" checkoutdir="xorg/app/mkcfm" />
1101 </autotools>
1102
1103 <autotools id="mkfontdir">
1104 <branch repo="git.freedesktop.org" module="xorg/app/mkfontdir" checkoutdir="xorg/app/mkfontdir" />
1105 </autotools>
1106
1107 <autotools id="mkfontscale">
1108 <branch repo="git.freedesktop.org" module="xorg/app/mkfontscale" checkoutdir="xorg/app/mkfontscale" />
1109 <dependencies>
1110 <dep package="libfontenc"/>
1111 <!-- <dep package="freetype2"/> -->
1112 </dependencies>
1113 </autotools>
1114
1115 <autotools id="oclock">
1116 <branch repo="git.freedesktop.org" module="xorg/app/oclock" checkoutdir="xorg/app/oclock" />
1117 <dependencies>
1118 <dep package="libX11"/>
1119 <dep package="libXmu"/>
1120 <dep package="libXext"/>
1121 </dependencies>
1122 </autotools>
1123
1124 <autotools id="proxymngr">
1125 <branch repo="git.freedesktop.org" module="xorg/app/proxymngr" checkoutdir="xorg/app/proxymngr" />
1126 <dependencies>
1127 <dep package="libX11"/>
1128 <dep package="libXt"/>
1129 <dep package="pmproto"/>
1130 <dep package="libICE"/>
1131 </dependencies>
1132 </autotools>
1133
1134 <autotools id="rgb">
1135 <branch repo="git.freedesktop.org" module="xorg/app/rgb" checkoutdir="xorg/app/rgb" />
1136 <dependencies>
1137 <dep package="x11proto"/>
1138 </dependencies>
1139 </autotools>
1140
1141 <autotools id="rstart">
1142 <branch repo="git.freedesktop.org" module="xorg/app/rstart" checkoutdir="xorg/app/rstart" />
1143 </autotools>
1144 <autotools id="scripts">
1145 <branch repo="git.freedesktop.org" module="xorg/app/scripts" checkoutdir="xorg/app/scripts" />
1146 </autotools>
1147
1148 <!-- <branch repo="git.freedesktop.org" module="xorg/app/sessreg"/> -->
1149
1150 <autotools id="setxkbmap">
1151 <branch repo="git.freedesktop.org" module="xorg/app/setxkbmap" checkoutdir="xorg/app/setxkbmap" />
1152 </autotools>
1153 <autotools id="showfont">
1154 <branch repo="git.freedesktop.org" module="xorg/app/showfont" checkoutdir="xorg/app/showfont" />
1155 </autotools>
1156 <autotools id="smproxy">
1157 <branch repo="git.freedesktop.org" module="xorg/app/smproxy" checkoutdir="xorg/app/smproxy" />
1158 </autotools>
1159 <autotools id="twm">
1160 <branch repo="git.freedesktop.org" module="xorg/app/twm" checkoutdir="xorg/app/twm" />
1161 </autotools>
1162
1163 <autotools id="viewres">
1164 <branch repo="git.freedesktop.org" module="xorg/app/viewres" checkoutdir="xorg/app/viewres" />
1165 <dependencies>
1166 <dep package="libXaw"/>
1167 </dependencies>
1168 </autotools>
1169
1170 <autotools id="x11perf">
1171 <branch repo="git.freedesktop.org" module="xorg/app/x11perf" checkoutdir="xorg/app/x11perf" />
1172 </autotools>
1173 <autotools id="xauth">
1174 <branch repo="git.freedesktop.org" module="xorg/app/xauth" checkoutdir="xorg/app/xauth" />
1175 </autotools>
1176 <autotools id="xbiff">
1177 <branch repo="git.freedesktop.org" module="xorg/app/xbiff" checkoutdir="xorg/app/xbiff" />
1178 <dependencies>
1179 <dep package="libXaw"/>
1180 </dependencies>
1181 </autotools>
1182
1183 <autotools id="xcalc">
1184 <branch repo="git.freedesktop.org" module="xorg/app/xcalc" checkoutdir="xorg/app/xcalc" />
1185 <dependencies>
1186 <dep package="libXaw"/>
1187 </dependencies>
1188 </autotools>
1189
1190 <autotools id="xclipboard">
1191 <branch repo="git.freedesktop.org" module="xorg/app/xclipboard" checkoutdir="xorg/app/xclipboard" />
1192 <dependencies>
1193 <dep package="libXaw"/>
1194 </dependencies>
1195 </autotools>
1196
1197 <autotools id="xclock">
1198 <branch repo="git.freedesktop.org" module="xorg/app/xclock" checkoutdir="xorg/app/xclock" />
1199 <dependencies>
1200 <dep package="libXaw"/>
1201 </dependencies>
1202 </autotools>
1203
1204 <autotools id="xcmsdb">
1205 <branch repo="git.freedesktop.org" module="xorg/app/xcmsdb" checkoutdir="xorg/app/xcmsdb" />
1206 </autotools>
1207 <autotools id="xconsole">
1208 <branch repo="git.freedesktop.org" module="xorg/app/xconsole" checkoutdir="xorg/app/xconsole" />
1209 <dependencies>
1210 <dep package="libXaw"/>
1211 </dependencies>
1212 </autotools>
1213
1214 <autotools id="xcursorgen">
1215 <branch repo="git.freedesktop.org" module="xorg/app/xcursorgen" checkoutdir="xorg/app/xcursorgen" />
1216 </autotools>
1217 <autotools id="xdbedizzy">
1218 <branch repo="git.freedesktop.org" module="xorg/app/xdbedizzy" checkoutdir="xorg/app/xdbedizzy" />
1219 </autotools>
1220 <autotools id="xditview">
1221 <branch repo="git.freedesktop.org" module="xorg/app/xditview" checkoutdir="xorg/app/xditview" />
1222 <dependencies>
1223 <dep package="libXaw"/>
1224 </dependencies>
1225 </autotools>
1226
1227 <autotools id="xdm">
1228 <branch repo="git.freedesktop.org" module="xorg/app/xdm" checkoutdir="xorg/app/xdm" />
1229 <dependencies>
1230 <dep package="libXaw"/>
1231 </dependencies>
1232 </autotools>
1233
1234 <autotools id="xdpyinfo">
1235 <branch repo="git.freedesktop.org" module="xorg/app/xdpyinfo" checkoutdir="xorg/app/xdpyinfo" />
1236 <dependencies>
1237 <dep package="libX11"/>
1238 <dep package="libXext"/>
1239 <dep package="libXtst"/>
1240 </dependencies>
1241 </autotools>
1242
1243 <autotools id="xdriinfo">
1244 <branch repo="git.freedesktop.org" module="xorg/app/xdriinfo" checkoutdir="xorg/app/xdriinfo" />
1245 <dependencies>
1246 <dep package="glproto"/>
1247 </dependencies>
1248 </autotools>
1249
1250 <autotools id="xedit">
1251 <branch repo="git.freedesktop.org" module="xorg/app/xedit" checkoutdir="xorg/app/xedit" />
1252 </autotools>
1253 <autotools id="xev">
1254 <branch repo="git.freedesktop.org" module="xorg/app/xev" checkoutdir="xorg/app/xev" />
1255 </autotools>
1256 <autotools id="xeyes">
1257 <branch repo="git.freedesktop.org" module="xorg/app/xeyes" checkoutdir="xorg/app/xeyes" />
1258 </autotools>
1259 <autotools id="xf86dga">
1260 <branch repo="git.freedesktop.org" module="xorg/app/xf86dga" checkoutdir="xorg/app/xf86dga" />
1261 </autotools>
1262 <autotools id="xfd">
1263 <branch repo="git.freedesktop.org" module="xorg/app/xfd" checkoutdir="xorg/app/xfd" />
1264 <dependencies>
1265 <dep package="libXaw"/>
1266 </dependencies>
1267 </autotools>
1268
1269 <autotools id="xfindproxy">
1270 <branch repo="git.freedesktop.org" module="xorg/app/xfindproxy" checkoutdir="xorg/app/xfindproxy" />
1271 </autotools>
1272 <autotools id="xfontsel">
1273 <branch repo="git.freedesktop.org" module="xorg/app/xfontsel" checkoutdir="xorg/app/xfontsel" />
1274 </autotools>
1275 <autotools id="xfs">
1276 <branch repo="git.freedesktop.org" module="xorg/app/xfs" checkoutdir="xorg/app/xfs" />
1277 </autotools>
1278 <autotools id="xfsinfo">
1279 <branch repo="git.freedesktop.org" module="xorg/app/xfsinfo" checkoutdir="xorg/app/xfsinfo" />
1280 </autotools>
1281 <autotools id="xfwp">
1282 <branch repo="git.freedesktop.org" module="xorg/app/xfwp" checkoutdir="xorg/app/xfwp" />
1283 </autotools>
1284 <autotools id="xgamma">
1285 <branch repo="git.freedesktop.org" module="xorg/app/xgamma" checkoutdir="xorg/app/xgamma" />
1286 </autotools>
1287 <autotools id="xgc">
1288 <branch repo="git.freedesktop.org" module="xorg/app/xgc" checkoutdir="xorg/app/xgc" />
1289 <dependencies>
1290 <dep package="libXaw"/>
1291 </dependencies>
1292 </autotools>
1293
1294 <autotools id="xhost">
1295 <branch repo="git.freedesktop.org" module="xorg/app/xhost" checkoutdir="xorg/app/xhost" />
1296 </autotools>
1297 <autotools id="xinit">
1298 <branch repo="git.freedesktop.org" module="xorg/app/xinit" checkoutdir="xorg/app/xinit" />
1299 </autotools>
1300 <autotools id="xkbcomp">
1301 <branch repo="git.freedesktop.org" module="xorg/app/xkbcomp" checkoutdir="xorg/app/xkbcomp" />
1302 </autotools>
1303 <autotools id="xkbevd">
1304 <branch repo="git.freedesktop.org" module="xorg/app/xkbevd" checkoutdir="xorg/app/xkbevd" />
1305 </autotools>
1306 <autotools id="xkbprint">
1307 <branch repo="git.freedesktop.org" module="xorg/app/xkbprint" checkoutdir="xorg/app/xkbprint" />
1308 </autotools>
1309 <autotools id="xkbutils">
1310 <branch repo="git.freedesktop.org" module="xorg/app/xkbutils" checkoutdir="xorg/app/xkbutils" />
1311 <dependencies>
1312 <dep package="libXaw"/>
1313 </dependencies>
1314 </autotools>
1315
1316 <autotools id="xkill">
1317 <branch repo="git.freedesktop.org" module="xorg/app/xkill" checkoutdir="xorg/app/xkill" />
1318 </autotools>
1319 <autotools id="xload">
1320 <branch repo="git.freedesktop.org" module="xorg/app/xload" checkoutdir="xorg/app/xload" />
1321 <dependencies>
1322 <dep package="libXaw"/>
1323 </dependencies>
1324 </autotools>
1325
1326 <autotools id="xlogo">
1327 <branch repo="git.freedesktop.org" module="xorg/app/xlogo" checkoutdir="xorg/app/xlogo" />
1328 <dependencies>
1329 <dep package="libXaw"/>
1330 </dependencies>
1331 </autotools>
1332
1333 <autotools id="xlsatoms">
1334 <branch repo="git.freedesktop.org" module="xorg/app/xlsatoms" checkoutdir="xorg/app/xlsatoms" />
1335 </autotools>
1336 <autotools id="xlsclients">
1337 <branch repo="git.freedesktop.org" module="xorg/app/xlsclients" checkoutdir="xorg/app/xlsclients" />
1338 </autotools>
1339 <autotools id="xlsfonts">
1340 <branch repo="git.freedesktop.org" module="xorg/app/xlsfonts" checkoutdir="xorg/app/xlsfonts" />
1341 </autotools>
1342 <autotools id="xmag">
1343 <branch repo="git.freedesktop.org" module="xorg/app/xmag" checkoutdir="xorg/app/xmag" />
1344 <dependencies>
1345 <dep package="libXaw"/>
1346 </dependencies>
1347 </autotools>
1348
1349 <autotools id="xman">
1350 <branch repo="git.freedesktop.org" module="xorg/app/xman" checkoutdir="xorg/app/xman" />
1351 <dependencies>
1352 <dep package="libXaw"/>
1353 </dependencies>
1354 </autotools>
1355
1356 <autotools id="xmessage">
1357 <branch repo="git.freedesktop.org" module="xorg/app/xmessage" checkoutdir="xorg/app/xmessage" />
1358 <dependencies>
1359 <dep package="libXaw"/>
1360 </dependencies>
1361 </autotools>
1362
1363 <autotools id="xmh">
1364 <branch repo="git.freedesktop.org" module="xorg/app/xmh" checkoutdir="xorg/app/xmh" />
1365 <dependencies>
1366 <dep package="libXaw"/>
1367 </dependencies>
1368 </autotools>
1369
1370 <autotools id="xmodmap">
1371 <branch repo="git.freedesktop.org" module="xorg/app/xmodmap" checkoutdir="xorg/app/xmodmap" />
1372 </autotools>
1373 <autotools id="xmore">
1374 <branch repo="git.freedesktop.org" module="xorg/app/xmore" checkoutdir="xorg/app/xmore" />
1375 <dependencies>
1376 <dep package="libXaw"/>
1377 </dependencies>
1378 </autotools>
1379
1380 <!--
1381 <autotools id="xphelloworld">
1382 <branch repo="git.freedesktop.org" module="xorg/app/xphelloworld" checkoutdir="xorg/app/xphelloworld" />
1383 </autotools>
1384 <autotools id="xplsprinters">
1385 <branch repo="git.freedesktop.org" module="xorg/app/xplsprinters" checkoutdir="xorg/app/xplsprinters" />
1386 </autotools>
1387 <autotools id="xpr">
1388 <branch repo="git.freedesktop.org" module="xorg/app/xpr" checkoutdir="xorg/app/xpr" />
1389 </autotools>
1390 <autotools id="xprehashprinterlist">
1391 <branch repo="git.freedesktop.org" module="xorg/app/xprehashprinterlist" checkoutdir="xorg/app/xprehashprinterlist" />
1392 </autotools>
1393 -->
1394
1395 <autotools id="xprop">
1396 <branch repo="git.freedesktop.org" module="xorg/app/xprop" checkoutdir="xorg/app/xprop" />
1397 </autotools>
1398 <autotools id="xrandr">
1399 <branch repo="git.freedesktop.org" module="xorg/app/xrandr" checkoutdir="xorg/app/xrandr" />
1400 </autotools>
1401 <autotools id="xrdb">
1402 <branch repo="git.freedesktop.org" module="xorg/app/xrdb" checkoutdir="xorg/app/xrdb" />
1403 </autotools>
1404 <autotools id="xrefresh">
1405 <branch repo="git.freedesktop.org" module="xorg/app/xrefresh" checkoutdir="xorg/app/xrefresh" />
1406 </autotools>
1407
1408 <autotools id="xrx">
1409 <branch repo="git.freedesktop.org" module="xorg/app/xrx" checkoutdir="xorg/app/xrx" />
1410 <dependencies>
1411 <dep package="libXext"/>
1412 </dependencies>
1413 </autotools>
1414
1415 <autotools id="xset">
1416 <branch repo="git.freedesktop.org" module="xorg/app/xset" checkoutdir="xorg/app/xset" />
1417 <dependencies>
1418 <dep package="libXext"/>
1419 </dependencies>
1420 </autotools>
1421
1422 <autotools id="xsetmode">
1423 <branch repo="git.freedesktop.org" module="xorg/app/xsetmode" checkoutdir="xorg/app/xsetmode" />
1424 </autotools>
1425 <autotools id="xsetpointer">
1426 <branch repo="git.freedesktop.org" module="xorg/app/xsetpointer" checkoutdir="xorg/app/xsetpointer" />
1427 </autotools>
1428
1429 <autotools id="xsetroot">
1430 <branch repo="git.freedesktop.org" module="xorg/app/xsetroot" checkoutdir="xorg/app/xsetroot" />
1431 <dependencies>
1432 <dep package="libX11"/>
1433 <dep package="libXmu"/>
1434 <dep package="bitmaps"/>
1435 </dependencies>
1436 </autotools>
1437
1438 <autotools id="xsm">
1439 <branch repo="git.freedesktop.org" module="xorg/app/xsm" checkoutdir="xorg/app/xsm" />
1440 <dependencies>
1441 <dep package="libXaw"/>
1442 </dependencies>
1443 </autotools>
1444
1445 <autotools id="xstdcmap">
1446 <branch repo="git.freedesktop.org" module="xorg/app/xstdcmap" checkoutdir="xorg/app/xstdcmap" />
1447 </autotools>
1448 <autotools id="xtrap">
1449 <branch repo="git.freedesktop.org" module="xorg/app/xtrap" checkoutdir="xorg/app/xtrap" />
1450 </autotools>
1451
1452 <autotools id="xvidtune">
1453 <branch repo="git.freedesktop.org" module="xorg/app/xvidtune" checkoutdir="xorg/app/xvidtune" />
1454 <dependencies>
1455 <dep package="libXaw"/>
1456 </dependencies>
1457 </autotools>
1458
1459 <autotools id="xvinfo">
1460 <branch repo="git.freedesktop.org" module="xorg/app/xvinfo" checkoutdir="xorg/app/xvinfo" />
1461 </autotools>
1462 <autotools id="xwd">
1463 <branch repo="git.freedesktop.org" module="xorg/app/xwd" checkoutdir="xorg/app/xwd" />
1464 </autotools>
1465 <autotools id="xwininfo">
1466 <branch repo="git.freedesktop.org" module="xorg/app/xwininfo" checkoutdir="xorg/app/xwininfo" />
1467 </autotools>
1468 <autotools id="xwud">
1469 <branch repo="git.freedesktop.org" module="xorg/app/xwud" checkoutdir="xorg/app/xwud" />
1470 </autotools>
1471
1472 <metamodule id="xorg-apps">
1473 <dependencies>
1474 <dep package="appres"/>
1475 <dep package="bdftopcf"/>
1476 <dep package="beforelight"/>
1477 <dep package="bitmap"/>
1478 <dep package="editres"/>
1479 <dep package="fonttosfnt"/>
1480 <dep package="fslsfonts"/>
1481 <dep package="fstobdf"/>
1482 <dep package="iceauth"/>
1483 <dep package="ico"/>
1484 <dep package="lbxproxy"/>
1485 <dep package="listres"/>
1486 <dep package="luit"/>
1487 <dep package="mkcfm"/>
1488 <dep package="mkfontdir"/>
1489 <dep package="mkfontscale"/>
1490 <dep package="oclock"/>
1491 <dep package="proxymngr"/>
1492 <dep package="rgb"/>
1493 <dep package="rstart"/>
1494 <dep package="scripts"/>
1495 <dep package="setxkbmap"/>
1496 <dep package="showfont"/>
1497 <dep package="smproxy"/>
1498 <dep package="twm"/>
1499 <dep package="viewres"/>
1500 <dep package="x11perf"/>
1501 <dep package="xauth"/>
1502 <dep package="xbiff"/>
1503 <dep package="xcalc"/>
1504 <dep package="xclipboard"/>
1505 <dep package="xclock"/>
1506 <dep package="xcmsdb"/>
1507 <dep package="xconsole"/>
1508 <dep package="xcursorgen"/>
1509 <dep package="xdbedizzy"/>
1510 <dep package="xditview"/>
1511 <dep package="xdm"/>
1512 <dep package="xdpyinfo"/>
1513 <dep package="xdriinfo"/>
1514 <dep package="xedit"/>
1515 <dep package="xev"/>
1516 <dep package="xeyes"/>
1517 <dep package="xf86dga"/>
1518 <dep package="xfd"/>
1519 <dep package="xfindproxy"/>
1520 <dep package="xfontsel"/>
1521 <dep package="xfs"/>
1522 <dep package="xfsinfo"/>
1523 <dep package="xfwp"/>
1524 <dep package="xgamma"/>
1525 <dep package="xgc"/>
1526 <dep package="xhost"/>
1527 <dep package="xinit"/>
1528 <dep package="xkbcomp"/>
1529 <dep package="xkbevd"/>
1530 <dep package="xkbprint"/>
1531 <dep package="xkbutils"/>
1532 <dep package="xkill"/>
1533 <dep package="xload"/>
1534 <dep package="xlogo"/>
1535 <dep package="xfontsel"/>
1536 <dep package="xlsatoms"/>
1537 <dep package="xlsclients"/>
1538 <dep package="xlsfonts"/>
1539 <dep package="xmag"/>
1540 <dep package="xman"/>
1541 <dep package="xmessage"/>
1542 <dep package="xmh"/>
1543 <dep package="xmodmap"/>
1544 <dep package="xmore"/>
1545
1546 <!--
1547 <dep package="xphelloworld"/>
1548 <dep package="xplsprinters"/>
1549 <dep package="xpr"/>
1550 <dep package="xprehashprinterlist"/>
1551 -->
1552
1553 <dep package="xprop"/>
1554 <dep package="xrandr"/>
1555 <dep package="xrdb"/>
1556 <dep package="xrefresh"/>
1557 <dep package="xrx"/>
1558 <dep package="xset"/>
1559 <dep package="xsetmode"/>
1560 <dep package="xsetpointer"/>
1561 <dep package="xsetroot"/>
1562 <dep package="xsm"/>
1563 <dep package="xstdcmap"/>
1564 <dep package="xtrap"/>
1565 <dep package="xvidtune"/>
1566 <dep package="xvinfo"/>
1567 <dep package="xwd"/>
1568 <dep package="xwininfo"/>
1569 <dep package="xwud"/>
1570 </dependencies>
1571 </metamodule>
1572
1573 <!-- input drivers -->
1574
1575 <autotools id="xf86-input-acecad">
1576 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-acecad" checkoutdir="xorg/driver/xf86-input-acecad" />
1577 <dependencies>
1578 <dep package="xserver"/>
1579 </dependencies>
1580 </autotools>
1581
1582 <autotools id="xf86-input-aiptek">
1583 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-aiptek" checkoutdir="xorg/driver/xf86-input-aiptek" />
1584 <dependencies>
1585 <dep package="xserver"/>
1586 </dependencies>
1587 </autotools>
1588
1589 <autotools id="xf86-input-calcomp">
1590 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-calcomp" checkoutdir="xorg/driver/xf86-input-calcomp" />
1591 <dependencies>
1592 <dep package="xserver"/>
1593 </dependencies>
1594 </autotools>
1595
1596 <autotools id="xf86-input-citron">
1597 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-citron" checkoutdir="xorg/driver/xf86-input-citron" />
1598 <dependencies>
1599 <dep package="xserver"/>
1600 </dependencies>
1601 </autotools>
1602
1603 <autotools id="xf86-input-digitaledge">
1604 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-digitaledge" checkoutdir="xorg/driver/xf86-input-digitaledge" />
1605 <dependencies>
1606 <dep package="xserver"/>
1607 </dependencies>
1608 </autotools>
1609
1610 <autotools id="xf86-input-dmc">
1611 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-dmc" checkoutdir="xorg/driver/xf86-input-dmc" />
1612 <dependencies>
1613 <dep package="xserver"/>
1614 </dependencies>
1615 </autotools>
1616
1617 <autotools id="xf86-input-dynapro">
1618 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-dynapro" checkoutdir="xorg/driver/xf86-input-dynapro" />
1619 <dependencies>
1620 <dep package="xserver"/>
1621 </dependencies>
1622 </autotools>
1623
1624 <autotools id="xf86-input-elo2300">
1625 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-elo2300" checkoutdir="xorg/driver/xf86-input-elo2300" />
1626 <dependencies>
1627 <dep package="xserver"/>
1628 </dependencies>
1629 </autotools>
1630
1631 <autotools id="xf86-input-elographics">
1632 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-elographics" checkoutdir="xorg/driver/xf86-input-elographics" />
1633 <dependencies>
1634 <dep package="xserver"/>
1635 </dependencies>
1636 </autotools>
1637
1638 <autotools id="xf86-input-evdev">
1639 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-evdev" checkoutdir="xorg/driver/xf86-input-evdev" />
1640 <dependencies>
1641 <dep package="xserver"/>
1642 </dependencies>
1643 </autotools>
1644
1645 <autotools id="xf86-input-fpit">
1646 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-fpit" checkoutdir="xorg/driver/xf86-input-fpit" />
1647 <dependencies>
1648 <dep package="xserver"/>
1649 </dependencies>
1650 </autotools>
1651
1652 <autotools id="xf86-input-hyperpen">
1653 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-hyperpen" checkoutdir="xorg/driver/xf86-input-hyperpen" />
1654 <dependencies>
1655 <dep package="xserver"/>
1656 </dependencies>
1657 </autotools>
1658
1659 <autotools id="xf86-input-jamstudio">
1660 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-jamstudio" checkoutdir="xorg/driver/xf86-input-jamstudio" />
1661 <dependencies>
1662 <dep package="xserver"/>
1663 </dependencies>
1664 </autotools>
1665
1666 <autotools id="xf86-input-joystick">
1667 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-joystick" checkoutdir="xorg/driver/xf86-input-joystick" />
1668 <dependencies>
1669 <dep package="xserver"/>
1670 </dependencies>
1671 </autotools>
1672
1673 <autotools id="xf86-input-keyboard">
1674 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-keyboard" checkoutdir="xorg/driver/xf86-input-keyboard" />
1675 <dependencies>
1676 <dep package="xserver"/>
1677 </dependencies>
1678 </autotools>
1679
1680 <autotools id="xf86-input-magellan">
1681 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-magellan" checkoutdir="xorg/driver/xf86-input-magellan" />
1682 <dependencies>
1683 <dep package="xserver"/>
1684 </dependencies>
1685 </autotools>
1686
1687 <autotools id="xf86-input-magictouch">
1688 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-magictouch" checkoutdir="xorg/driver/xf86-input-magictouch" />
1689 <dependencies>
1690 <dep package="xserver"/>
1691 </dependencies>
1692 </autotools>
1693
1694 <autotools id="xf86-input-microtouch">
1695 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-microtouch" checkoutdir="xorg/driver/xf86-input-microtouch" />
1696 <dependencies>
1697 <dep package="xserver"/>
1698 </dependencies>
1699 </autotools>
1700
1701 <autotools id="xf86-input-mouse">
1702 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-mouse" checkoutdir="xorg/driver/xf86-input-mouse" />
1703 <dependencies>
1704 <dep package="xserver"/>
1705 </dependencies>
1706 </autotools>
1707
1708 <autotools id="xf86-input-mutouch">
1709 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-mutouch" checkoutdir="xorg/driver/xf86-input-mutouch" />
1710 <dependencies>
1711 <dep package="xserver"/>
1712 </dependencies>
1713 </autotools>
1714
1715 <autotools id="xf86-input-palmax">
1716 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-palmax" checkoutdir="xorg/driver/xf86-input-palmax" />
1717 <dependencies>
1718 <dep package="xserver"/>
1719 </dependencies>
1720 </autotools>
1721
1722 <autotools id="xf86-input-penmount">
1723 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-penmount" checkoutdir="xorg/driver/xf86-input-penmount" />
1724 <dependencies>
1725 <dep package="xserver"/>
1726 </dependencies>
1727 </autotools>
1728
1729 <autotools id="xf86-input-spaceorb">
1730 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-spaceorb" checkoutdir="xorg/driver/xf86-input-spaceorb" />
1731 <dependencies>
1732 <dep package="xserver"/>
1733 </dependencies>
1734 </autotools>
1735
1736 <autotools id="xf86-input-summa">
1737 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-summa" checkoutdir="xorg/driver/xf86-input-summa" />
1738 <dependencies>
1739 <dep package="xserver"/>
1740 </dependencies>
1741 </autotools>
1742
1743 <autotools id="xf86-input-tek4957">
1744 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-tek4957" checkoutdir="xorg/driver/xf86-input-tek4957" />
1745 <dependencies>
1746 <dep package="xserver"/>
1747 </dependencies>
1748 </autotools>
1749
1750 <autotools id="xf86-input-ur98">
1751 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-ur98" checkoutdir="xorg/driver/xf86-input-ur98" />
1752 <dependencies>
1753 <dep package="xserver"/>
1754 </dependencies>
1755 </autotools>
1756
1757 <autotools id="xf86-input-vmmouse">
1758 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-vmmouse" checkoutdir="xorg/driver/xf86-input-vmmouse" />
1759 <dependencies>
1760 <dep package="xserver"/>
1761 </dependencies>
1762 </autotools>
1763
1764 <autotools id="xf86-input-void">
1765 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-input-void" checkoutdir="xorg/driver/xf86-input-void" />
1766 <dependencies>
1767 <dep package="xserver"/>
1768 </dependencies>
1769 </autotools>
1770
1771 <autotools id="xf86-video-apm">
1772 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-apm" checkoutdir="xorg/driver/xf86-video-apm" />
1773 <dependencies>
1774 <dep package="xserver"/>
1775 </dependencies>
1776 </autotools>
1777
1778 <autotools id="xf86-video-ark">
1779 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-ark" checkoutdir="xorg/driver/xf86-video-ark" />
1780 <dependencies>
1781 <dep package="xserver"/>
1782 </dependencies>
1783 </autotools>
1784
1785 <autotools id="xf86-video-ati">
1786 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-ati" checkoutdir="xorg/driver/xf86-video-ati" />
1787 <dependencies>
1788 <dep package="xserver"/>
1789 </dependencies>
1790 </autotools>
1791
1792 <autotools id="xf86-video-chips">
1793 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-chips" checkoutdir="xorg/driver/xf86-video-chips" />
1794 <dependencies>
1795 <dep package="xserver"/>
1796 </dependencies>
1797 </autotools>
1798
1799 <autotools id="xf86-video-cirrus">
1800 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-cirrus" checkoutdir="xorg/driver/xf86-video-cirrus" />
1801 <dependencies>
1802 <dep package="xserver"/>
1803 </dependencies>
1804 </autotools>
1805
1806 <autotools id="xf86-video-cyrix">
1807 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-cyrix" checkoutdir="xorg/driver/xf86-video-cyrix" />
1808 <dependencies>
1809 <dep package="xserver"/>
1810 </dependencies>
1811 </autotools>
1812
1813 <autotools id="xf86-video-dummy">
1814 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-dummy" checkoutdir="xorg/driver/xf86-video-dummy" />
1815 <dependencies>
1816 <dep package="xserver"/>
1817 </dependencies>
1818 </autotools>
1819
1820 <autotools id="xf86-video-fbdev">
1821 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-fbdev" checkoutdir="xorg/driver/xf86-video-fbdev" />
1822 <dependencies>
1823 <dep package="xserver"/>
1824 </dependencies>
1825 </autotools>
1826
1827 <autotools id="xf86-video-glint">
1828 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-glint" checkoutdir="xorg/driver/xf86-video-glint" />
1829 <dependencies>
1830 <dep package="xserver"/>
1831 </dependencies>
1832 </autotools>
1833
1834 <autotools id="xf86-video-i128">
1835 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-i128" checkoutdir="xorg/driver/xf86-video-i128" />
1836 <dependencies>
1837 <dep package="xserver"/>
1838 </dependencies>
1839 </autotools>
1840
1841 <autotools id="xf86-video-i740">
1842 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-i740" checkoutdir="xorg/driver/xf86-video-i740" />
1843 <dependencies>
1844 <dep package="xserver"/>
1845 </dependencies>
1846 </autotools>
1847
1848 <autotools id="xf86-video-imstt">
1849 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-imstt" checkoutdir="xorg/driver/xf86-video-imstt" />
1850 <dependencies>
1851 <dep package="xserver"/>
1852 </dependencies>
1853 </autotools>
1854
1855 <autotools id="xf86-video-intel">
1856 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-intel" checkoutdir="xorg/driver/xf86-video-intel" />
1857 <dependencies>
1858 <dep package="xserver"/>
1859 <dep package="x11proto"/>
1860 <dep package="libXvMC"/>
1861 </dependencies>
1862 </autotools>
1863
1864 <autotools id="xf86-video-mga">
1865 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-mga" checkoutdir="xorg/driver/xf86-video-mga" />
1866 <dependencies>
1867 <dep package="xserver"/>
1868 </dependencies>
1869 </autotools>
1870
1871 <autotools id="xf86-video-neomagic">
1872 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-neomagic" checkoutdir="xorg/driver/xf86-video-neomagic" />
1873 <dependencies>
1874 <dep package="xserver"/>
1875 </dependencies>
1876 </autotools>
1877
1878 <autotools id="xf86-video-newport">
1879 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-newport" checkoutdir="xorg/driver/xf86-video-newport" />
1880 <dependencies>
1881 <dep package="xserver"/>
1882 </dependencies>
1883 </autotools>
1884
1885 <autotools id="xf86-video-nsc">
1886 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-nsc" checkoutdir="xorg/driver/xf86-video-nsc" />
1887 <dependencies>
1888 <dep package="xserver"/>
1889 </dependencies>
1890 </autotools>
1891
1892 <autotools id="xf86-video-nv">
1893 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-nv" checkoutdir="xorg/driver/xf86-video-nv" />
1894 <dependencies>
1895 <dep package="xserver"/>
1896 </dependencies>
1897 </autotools>
1898
1899 <autotools id="xf86-video-rendition">
1900 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-rendition" checkoutdir="xorg/driver/xf86-video-rendition" />
1901 <dependencies>
1902 <dep package="xserver"/>
1903 </dependencies>
1904 </autotools>
1905
1906 <autotools id="xf86-video-s3">
1907 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-s3" checkoutdir="xorg/driver/xf86-video-s3" />
1908 <dependencies>
1909 <dep package="xserver"/>
1910 </dependencies>
1911 </autotools>
1912
1913 <autotools id="xf86-video-s3virge">
1914 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-s3virge" checkoutdir="xorg/driver/xf86-video-s3virge" />
1915 <dependencies>
1916 <dep package="xserver"/>
1917 </dependencies>
1918 </autotools>
1919
1920 <autotools id="xf86-video-savage">
1921 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-savage" checkoutdir="xorg/driver/xf86-video-savage" />
1922 <dependencies>
1923 <dep package="xserver"/>
1924 </dependencies>
1925 </autotools>
1926
1927 <autotools id="xf86-video-siliconmotion">
1928 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-siliconmotion" checkoutdir="xorg/driver/xf86-video-siliconmotion" />
1929 <dependencies>
1930 <dep package="xserver"/>
1931 </dependencies>
1932 </autotools>
1933
1934 <autotools id="xf86-video-sis">
1935 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-sis" checkoutdir="xorg/driver/xf86-video-sis" />
1936 <dependencies>
1937 <dep package="xserver"/>
1938 </dependencies>
1939 </autotools>
1940
1941 <autotools id="xf86-video-sisusb">
1942 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-sisusb" checkoutdir="xorg/driver/xf86-video-sisusb" />
1943 <dependencies>
1944 <dep package="xserver"/>
1945 </dependencies>
1946 </autotools>
1947
1948 <autotools id="xf86-video-sunbw2">
1949 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-sunbw2" checkoutdir="xorg/driver/xf86-video-sunbw2" />
1950 <dependencies>
1951 <dep package="xserver"/>
1952 </dependencies>
1953 </autotools>
1954
1955 <autotools id="xf86-video-suncg14">
1956 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-suncg14" checkoutdir="xorg/driver/xf86-video-suncg14" />
1957 <dependencies>
1958 <dep package="xserver"/>
1959 </dependencies>
1960 </autotools>
1961
1962 <autotools id="xf86-video-suncg3">
1963 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-suncg3" checkoutdir="xorg/driver/xf86-video-suncg3" />
1964 <dependencies>
1965 <dep package="xserver"/>
1966 </dependencies>
1967 </autotools>
1968
1969 <autotools id="xf86-video-suncg6">
1970 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-suncg6" checkoutdir="xorg/driver/xf86-video-suncg6" />
1971 <dependencies>
1972 <dep package="xserver"/>
1973 </dependencies>
1974 </autotools>
1975
1976 <autotools id="xf86-video-sunffb">
1977 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-sunffb" checkoutdir="xorg/driver/xf86-video-sunffb" />
1978 <dependencies>
1979 <dep package="xserver"/>
1980 </dependencies>
1981 </autotools>
1982
1983 <autotools id="xf86-video-sunleo">
1984 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-sunleo" checkoutdir="xorg/driver/xf86-video-sunleo" />
1985 <dependencies>
1986 <dep package="xserver"/>
1987 </dependencies>
1988 </autotools>
1989
1990 <autotools id="xf86-video-suntcx">
1991 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-suntcx" checkoutdir="xorg/driver/xf86-video-suntcx" />
1992 <dependencies>
1993 <dep package="xserver"/>
1994 </dependencies>
1995 </autotools>
1996
1997 <autotools id="xf86-video-tdfx">
1998 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-tdfx" checkoutdir="xorg/driver/xf86-video-tdfx" />
1999 <dependencies>
2000 <dep package="xserver"/>
2001 </dependencies>
2002 </autotools>
2003
2004 <autotools id="xf86-video-tga">
2005 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-tga" checkoutdir="xorg/driver/xf86-video-tga" />
2006 <dependencies>
2007 <dep package="xserver"/>
2008 </dependencies>
2009 </autotools>
2010
2011 <autotools id="xf86-video-trident">
2012 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-trident" checkoutdir="xorg/driver/xf86-video-trident" />
2013 <dependencies>
2014 <dep package="xserver"/>
2015 </dependencies>
2016 </autotools>
2017
2018 <autotools id="xf86-video-tseng">
2019 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-tseng" checkoutdir="xorg/driver/xf86-video-tseng" />
2020 <dependencies>
2021 <dep package="xserver"/>
2022 </dependencies>
2023 </autotools>
2024
2025 <autotools id="xf86-video-v4l">
2026 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-v4l" checkoutdir="xorg/driver/xf86-video-v4l" />
2027 <dependencies>
2028 <dep package="xserver"/>
2029 </dependencies>
2030 </autotools>
2031
2032 <autotools id="xf86-video-vesa">
2033 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-vesa" checkoutdir="xorg/driver/xf86-video-vesa" />
2034 <dependencies>
2035 <dep package="xserver"/>
2036 </dependencies>
2037 </autotools>
2038
2039 <autotools id="xf86-video-vga">
2040 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-vga" checkoutdir="xorg/driver/xf86-video-vga" />
2041 <dependencies>
2042 <dep package="xserver"/>
2043 </dependencies>
2044 </autotools>
2045
2046 <autotools id="xf86-video-via">
2047 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-via" checkoutdir="xorg/driver/xf86-video-via" />
2048 <dependencies>
2049 <dep package="xserver"/>
2050 </dependencies>
2051 </autotools>
2052
2053 <autotools id="xf86-video-vmware">
2054 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-vmware" checkoutdir="xorg/driver/xf86-video-vmware" />
2055 <dependencies>
2056 <dep package="xserver"/>
2057 </dependencies>
2058 </autotools>
2059
2060 <autotools id="xf86-video-voodoo">
2061 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-voodoo" checkoutdir="xorg/driver/xf86-video-voodoo" />
2062 <dependencies>
2063 <dep package="xserver"/>
2064 </dependencies>
2065 </autotools>
2066
2067 <autotools id="xf86-video-wsfb">
2068 <branch repo="git.freedesktop.org" module="xorg/driver/xf86-video-wsfb" checkoutdir="xorg/driver/xf86-video-wsfb" />
2069 <dependencies>
2070 <dep package="xserver"/>
2071 </dependencies>
2072 </autotools>
2073
2074 <metamodule id="xorg-drivers">
2075 <dependencies>
2076 <dep package="xf86-input-acecad"/>
2077 <dep package="xf86-input-aiptek"/>
2078 <dep package="xf86-input-calcomp"/>
2079 <dep package="xf86-input-citron"/>
2080 <dep package="xf86-input-digitaledge"/>
2081 <dep package="xf86-input-dmc"/>
2082 <dep package="xf86-input-dynapro"/>
2083 <dep package="xf86-input-elo2300"/>
2084 <dep package="xf86-input-elographics"/>
2085 <dep package="xf86-input-evdev"/>
2086 <dep package="xf86-input-fpit"/>
2087 <dep package="xf86-input-hyperpen"/>
2088 <dep package="xf86-input-jamstudio"/>
2089 <dep package="xf86-input-joystick"/>
2090 <dep package="xf86-input-keyboard"/>
2091 <dep package="xf86-input-magellan"/>
2092 <dep package="xf86-input-magictouch"/>
2093 <dep package="xf86-input-microtouch"/>
2094 <dep package="xf86-input-mouse"/>
2095 <dep package="xf86-input-mutouch"/>
2096 <dep package="xf86-input-palmax"/>
2097 <dep package="xf86-input-penmount"/>
2098 <dep package="xf86-input-spaceorb"/>
2099 <dep package="xf86-input-tek4957"/>
2100 <dep package="xf86-input-ur98"/>
2101 <dep package="xf86-input-void"/>
2102 <dep package="xf86-video-apm"/>
2103 <dep package="xf86-video-ark"/>
2104 <dep package="xf86-video-ati"/>
2105 <dep package="xf86-video-chips"/>
2106 <dep package="xf86-video-cirrus"/>
2107 <dep package="xf86-video-cyrix"/>
2108 <dep package="xf86-video-dummy"/>
2109 <dep package="xf86-video-fbdev"/>
2110 <dep package="xf86-video-glint"/>
2111 <dep package="xf86-video-i128"/>
2112 <dep package="xf86-video-i740"/>
2113 <dep package="xf86-video-intel"/>
2114 <dep package="xf86-video-imstt"/>
2115 <dep package="xf86-video-mga"/>
2116 <dep package="xf86-video-neomagic"/>
2117 <dep package="xf86-video-newport"/>
2118 <dep package="xf86-video-nsc"/>
2119 <dep package="xf86-video-nv"/>
2120 <dep package="xf86-video-rendition"/>
2121 <dep package="xf86-video-s3"/>
2122 <dep package="xf86-video-s3virge"/>
2123 <dep package="xf86-video-savage"/>
2124 <dep package="xf86-video-siliconmotion"/>
2125 <dep package="xf86-video-sis"/>
2126 <dep package="xf86-video-sisusb"/>
2127 <dep package="xf86-video-sunbw2"/>
2128 <dep package="xf86-video-suncg14"/>
2129 <dep package="xf86-video-suncg3"/>
2130 <dep package="xf86-video-suncg6"/>
2131 <dep package="xf86-video-sunffb"/>
2132 <dep package="xf86-video-sunleo"/>
2133 <dep package="xf86-video-suntcx"/>
2134 <dep package="xf86-video-tdfx"/>
2135 <dep package="xf86-video-tga"/>
2136 <dep package="xf86-video-trident"/>
2137 <dep package="xf86-video-tseng"/>
2138 <dep package="xf86-video-v4l"/>
2139 <dep package="xf86-video-vesa"/>
2140 <dep package="xf86-video-vga"/>
2141 <dep package="xf86-video-via"/>
2142 <dep package="xf86-video-vmware"/>
2143 <dep package="xf86-video-voodoo"/>
2144 <dep package="xf86-video-wsfb"/>
2145 </dependencies>
2146 </metamodule>
2147
2148 <!-- Modules that only build on x86 (32 and 64bit) -->
2149
2150 <metamodule id="xorg-x86-drivers">
2151 <dependencies>
2152 <dep package="xf86-input-vmmouse"/>
2153 </dependencies>
2154 </metamodule>
2155
2156 <!-- This probably isn't sufficient, but it is a start -->
2157
2158 <metamodule id="xorg-sun-drivers">
2159 <dependencies>
2160 <dep package="xf86-video-sunbw2"/>
2161 <dep package="xf86-video-suncg14"/>
2162 <dep package="xf86-video-suncg3"/>
2163 <dep package="xf86-video-suncg6"/>
2164 <dep package="xf86-video-sunffb"/>
2165 <dep package="xf86-video-sunleo"/>
2166 <dep package="xf86-video-suntcx"/>
2167 </dependencies>
2168 </metamodule>
2169
2170
2171 <!-- Bogosity of depending on libraries caused by Xnest. Sigh -->
2172 <autotools id="xserver">
2173 <branch repo="git.freedesktop.org" module="xorg/xserver"/>
2174 <dependencies>
2175 <dep package="xorg-protos"/>
2176 <dep package="libXaw"/>
2177 <dep package="libxkbui"/>
2178 <dep package="libXfont"/>
2179 <dep package="libxtrans"/>
2180 <dep package="libXau"/>
2181 <dep package="libxkbfile"/>
2182 <dep package="libXdmcp"/>
2183 <dep package="libXxf86misc"/>
2184 <dep package="libXxf86vm"/>
2185 <dep package="liblbxutil"/>
2186 <dep package="libdrm"/>
2187 </dependencies>
2188 </autotools>
2189
2190 <metamodule id="xorg">
2191 <dependencies>
2192 <dep package="xorg-protos"/>
2193 <dep package="xorg-libs"/>
2194 <dep package="xorg-fonts"/>
2195 <dep package="xorg-apps"/>
2196 <dep package="xorg-drivers"/>
2197 <dep package="xserver"/>
2198 </dependencies>
2199 </metamodule>
2200
2201</moduleset>
diff --git a/scripts/lib/bsp/__init__.py b/scripts/lib/bsp/__init__.py
new file mode 100644
index 0000000000..8bbb6e1530
--- /dev/null
+++ b/scripts/lib/bsp/__init__.py
@@ -0,0 +1,22 @@
1#
2# Yocto BSP tools library
3#
4# Copyright (c) 2012, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# AUTHORS
21# Tom Zanussi <tom.zanussi (at] intel.com>
22#
diff --git a/scripts/lib/bsp/engine.py b/scripts/lib/bsp/engine.py
new file mode 100644
index 0000000000..681720d20a
--- /dev/null
+++ b/scripts/lib/bsp/engine.py
@@ -0,0 +1,1780 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2012, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module implements the templating engine used by 'yocto-bsp' to
22# create BSPs. The BSP templates are simply the set of files expected
23# to appear in a generated BSP, marked up with a small set of tags
24# used to customize the output. The engine parses through the
25# templates and generates a Python program containing all the logic
26# and input elements needed to display and retrieve BSP-specific
27# information from the user. The resulting program uses those results
28# to generate the final BSP files.
29#
30# AUTHORS
31# Tom Zanussi <tom.zanussi (at] intel.com>
32#
33
34import os
35import sys
36from abc import ABCMeta, abstractmethod
37from tags import *
38import shlex
39import json
40import subprocess
41import shutil
42
43class Line():
44 """
45 Generic (abstract) container representing a line that will appear
46 in the BSP-generating program.
47 """
48 __metaclass__ = ABCMeta
49
50 def __init__(self, line):
51 self.line = line
52 self.generated_line = ""
53 self.prio = sys.maxint
54 self.discard = False
55
56 @abstractmethod
57 def gen(self, context = None):
58 """
59 Generate the final executable line that will appear in the
60 BSP-generation program.
61 """
62 pass
63
64 def escape(self, line):
65 """
66 Escape single and double quotes and backslashes until I find
67 something better (re.escape() escapes way too much).
68 """
69 return line.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'")
70
71 def parse_error(self, msg, lineno, line):
72 raise SyntaxError("%s: %s" % (msg, line))
73
74
75class NormalLine(Line):
76 """
77 Container for normal (non-tag) lines.
78 """
79 def __init__(self, line):
80 Line.__init__(self, line)
81 self.is_filename = False
82 self.is_dirname = False
83 self.out_filebase = None
84
85 def gen(self, context = None):
86 if self.is_filename:
87 line = "current_file = \"" + os.path.join(self.out_filebase, self.escape(self.line)) + "\"; of = open(current_file, \"w\")"
88 elif self.is_dirname:
89 dirname = os.path.join(self.out_filebase, self.escape(self.line))
90 line = "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
91 else:
92 line = "of.write(\"" + self.escape(self.line) + "\\n\")"
93 return line
94
95
96class CodeLine(Line):
97 """
98 Container for Python code tag lines.
99 """
100 def __init__(self, line):
101 Line.__init__(self, line)
102
103 def gen(self, context = None):
104 return self.line
105
106
107class Assignment:
108 """
109 Representation of everything we know about {{=name }} tags.
110 Instances of these are used by Assignment lines.
111 """
112 def __init__(self, start, end, name):
113 self.start = start
114 self.end = end
115 self.name = name
116
117
118class AssignmentLine(NormalLine):
119 """
120 Container for normal lines containing assignment tags. Assignment
121 tags must be in ascending order of 'start' value.
122 """
123 def __init__(self, line):
124 NormalLine.__init__(self, line)
125 self.assignments = []
126
127 def add_assignment(self, start, end, name):
128 self.assignments.append(Assignment(start, end, name))
129
130 def gen(self, context = None):
131 line = self.escape(self.line)
132
133 for assignment in self.assignments:
134 replacement = "\" + " + assignment.name + " + \""
135 idx = line.find(ASSIGN_TAG)
136 line = line[:idx] + replacement + line[idx + assignment.end - assignment.start:]
137 if self.is_filename:
138 return "current_file = \"" + os.path.join(self.out_filebase, line) + "\"; of = open(current_file, \"w\")"
139 elif self.is_dirname:
140 dirname = os.path.join(self.out_filebase, line)
141 return "if not os.path.exists(\"" + dirname + "\"): os.mkdir(\"" + dirname + "\")"
142 else:
143 return "of.write(\"" + line + "\\n\")"
144
145
146class InputLine(Line):
147 """
148 Base class for Input lines.
149 """
150 def __init__(self, props, tag, lineno):
151 Line.__init__(self, tag)
152 self.props = props
153 self.lineno = lineno
154
155 try:
156 self.prio = int(props["prio"])
157 except KeyError:
158 self.prio = sys.maxint
159
160 def gen(self, context = None):
161 try:
162 depends_on = self.props["depends-on"]
163 try:
164 depends_on_val = self.props["depends-on-val"]
165 except KeyError:
166 self.parse_error("No 'depends-on-val' for 'depends-on' property",
167 self.lineno, self.line)
168 except KeyError:
169 pass
170
171
172class EditBoxInputLine(InputLine):
173 """
174 Base class for 'editbox' Input lines.
175
176 props:
177 name: example - "Load address"
178 msg: example - "Please enter the load address"
179 result:
180 Sets the value of the variable specified by 'name' to
181 whatever the user typed.
182 """
183 def __init__(self, props, tag, lineno):
184 InputLine.__init__(self, props, tag, lineno)
185
186 def gen(self, context = None):
187 InputLine.gen(self, context)
188 name = self.props["name"]
189 if not name:
190 self.parse_error("No input 'name' property found",
191 self.lineno, self.line)
192 msg = self.props["msg"]
193 if not msg:
194 self.parse_error("No input 'msg' property found",
195 self.lineno, self.line)
196
197 try:
198 default_choice = self.props["default"]
199 except KeyError:
200 default_choice = ""
201
202 msg += " [default: " + default_choice + "]"
203
204 line = name + " = default(raw_input(\"" + msg + " \"), " + name + ")"
205
206 return line
207
208
209class GitRepoEditBoxInputLine(EditBoxInputLine):
210 """
211 Base class for 'editbox' Input lines for user input of remote git
212 repos. This class verifies the existence and connectivity of the
213 specified git repo.
214
215 props:
216 name: example - "Load address"
217 msg: example - "Please enter the load address"
218 result:
219 Sets the value of the variable specified by 'name' to
220 whatever the user typed.
221 """
222 def __init__(self, props, tag, lineno):
223 EditBoxInputLine.__init__(self, props, tag, lineno)
224
225 def gen(self, context = None):
226 EditBoxInputLine.gen(self, context)
227 name = self.props["name"]
228 if not name:
229 self.parse_error("No input 'name' property found",
230 self.lineno, self.line)
231 msg = self.props["msg"]
232 if not msg:
233 self.parse_error("No input 'msg' property found",
234 self.lineno, self.line)
235
236 try:
237 default_choice = self.props["default"]
238 except KeyError:
239 default_choice = ""
240
241 msg += " [default: " + default_choice + "]"
242
243 line = name + " = get_verified_git_repo(\"" + msg + "\"," + name + ")"
244
245 return line
246
247
248class FileEditBoxInputLine(EditBoxInputLine):
249 """
250 Base class for 'editbox' Input lines for user input of existing
251 files. This class verifies the existence of the specified file.
252
253 props:
254 name: example - "Load address"
255 msg: example - "Please enter the load address"
256 result:
257 Sets the value of the variable specified by 'name' to
258 whatever the user typed.
259 """
260 def __init__(self, props, tag, lineno):
261 EditBoxInputLine.__init__(self, props, tag, lineno)
262
263 def gen(self, context = None):
264 EditBoxInputLine.gen(self, context)
265 name = self.props["name"]
266 if not name:
267 self.parse_error("No input 'name' property found",
268 self.lineno, self.line)
269 msg = self.props["msg"]
270 if not msg:
271 self.parse_error("No input 'msg' property found",
272 self.lineno, self.line)
273
274 try:
275 default_choice = self.props["default"]
276 except KeyError:
277 default_choice = ""
278
279 msg += " [default: " + default_choice + "]"
280
281 line = name + " = get_verified_file(\"" + msg + "\"," + name + ", True)"
282
283 return line
284
285
286class BooleanInputLine(InputLine):
287 """
288 Base class for boolean Input lines.
289 props:
290 name: example - "keyboard"
291 msg: example - "Got keyboard?"
292 result:
293 Sets the value of the variable specified by 'name' to "yes" or "no"
294 example - keyboard = "yes"
295 """
296 def __init__(self, props, tag, lineno):
297 InputLine.__init__(self, props, tag, lineno)
298
299 def gen(self, context = None):
300 InputLine.gen(self, context)
301 name = self.props["name"]
302 if not name:
303 self.parse_error("No input 'name' property found",
304 self.lineno, self.line)
305 msg = self.props["msg"]
306 if not msg:
307 self.parse_error("No input 'msg' property found",
308 self.lineno, self.line)
309
310 try:
311 default_choice = self.props["default"]
312 except KeyError:
313 default_choice = ""
314
315 msg += " [default: " + default_choice + "]"
316
317 line = name + " = boolean(raw_input(\"" + msg + " \"), " + name + ")"
318
319 return line
320
321
322class ListInputLine(InputLine):
323 """
324 Base class for List-based Input lines. e.g. Choicelist, Checklist.
325 """
326 __metaclass__ = ABCMeta
327
328 def __init__(self, props, tag, lineno):
329 InputLine.__init__(self, props, tag, lineno)
330 self.choices = []
331
332 def gen_choicepair_list(self):
333 """Generate a list of 2-item val:desc lists from self.choices."""
334 if not self.choices:
335 return None
336
337 choicepair_list = list()
338
339 for choice in self.choices:
340 choicepair = []
341 choicepair.append(choice.val)
342 choicepair.append(choice.desc)
343 choicepair_list.append(choicepair)
344
345 return choicepair_list
346
347 def gen_degenerate_choicepair_list(self, choices):
348 """Generate a list of 2-item val:desc with val=desc from passed-in choices."""
349 choicepair_list = list()
350
351 for choice in choices:
352 choicepair = []
353 choicepair.append(choice)
354 choicepair.append(choice)
355 choicepair_list.append(choicepair)
356
357 return choicepair_list
358
359 def exec_listgen_fn(self, context = None):
360 """
361 Execute the list-generating function contained as a string in
362 the "gen" property.
363 """
364 retval = None
365 try:
366 fname = self.props["gen"]
367 modsplit = fname.split('.')
368 mod_fn = modsplit.pop()
369 mod = '.'.join(modsplit)
370
371 __import__(mod)
372 # python 2.7 has a better way to do this using importlib.import_module
373 m = sys.modules[mod]
374
375 fn = getattr(m, mod_fn)
376 if not fn:
377 self.parse_error("couldn't load function specified for 'gen' property ",
378 self.lineno, self.line)
379 retval = fn(context)
380 if not retval:
381 self.parse_error("function specified for 'gen' property returned nothing ",
382 self.lineno, self.line)
383 except KeyError:
384 pass
385
386 return retval
387
388 def gen_choices_str(self, choicepairs):
389 """
390 Generate a numbered list of choices from a list of choicepairs
391 for display to the user.
392 """
393 choices_str = ""
394
395 for i, choicepair in enumerate(choicepairs):
396 choices_str += "\t" + str(i + 1) + ") " + choicepair[1] + "\n"
397
398 return choices_str
399
400 def gen_choices_val_str(self, choicepairs):
401 """
402 Generate an array of choice values corresponding to the
403 numbered list generated by gen_choices_str().
404 """
405 choices_val_list = "["
406
407 for i, choicepair in enumerate(choicepairs):
408 choices_val_list += "\"" + choicepair[0] + "\","
409 choices_val_list += "]"
410
411 return choices_val_list
412
413 def gen_choices_val_list(self, choicepairs):
414 """
415 Generate an array of choice values corresponding to the
416 numbered list generated by gen_choices_str().
417 """
418 choices_val_list = []
419
420 for i, choicepair in enumerate(choicepairs):
421 choices_val_list.append(choicepair[0])
422
423 return choices_val_list
424
425 def gen_choices_list(self, context = None, checklist = False):
426 """
427 Generate an array of choice values corresponding to the
428 numbered list generated by gen_choices_str().
429 """
430 choices = self.exec_listgen_fn(context)
431 if choices:
432 if len(choices) == 0:
433 self.parse_error("No entries available for input list",
434 self.lineno, self.line)
435 choicepairs = self.gen_degenerate_choicepair_list(choices)
436 else:
437 if len(self.choices) == 0:
438 self.parse_error("No entries available for input list",
439 self.lineno, self.line)
440 choicepairs = self.gen_choicepair_list()
441
442 return choicepairs
443
444 def gen_choices(self, context = None, checklist = False):
445 """
446 Generate an array of choice values corresponding to the
447 numbered list generated by gen_choices_str(), display it to
448 the user, and process the result.
449 """
450 msg = self.props["msg"]
451 if not msg:
452 self.parse_error("No input 'msg' property found",
453 self.lineno, self.line)
454
455 try:
456 default_choice = self.props["default"]
457 except KeyError:
458 default_choice = ""
459
460 msg += " [default: " + default_choice + "]"
461
462 choicepairs = self.gen_choices_list(context, checklist)
463
464 choices_str = self.gen_choices_str(choicepairs)
465 choices_val_list = self.gen_choices_val_list(choicepairs)
466 if checklist:
467 choiceval = default(find_choicevals(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)
468 else:
469 choiceval = default(find_choiceval(raw_input(msg + "\n" + choices_str), choices_val_list), default_choice)
470
471 return choiceval
472
473
474def find_choiceval(choice_str, choice_list):
475 """
476 Take number as string and return val string from choice_list,
477 empty string if oob. choice_list is a simple python list.
478 """
479 choice_val = ""
480
481 try:
482 choice_idx = int(choice_str)
483 if choice_idx <= len(choice_list):
484 choice_idx -= 1
485 choice_val = choice_list[choice_idx]
486 except ValueError:
487 pass
488
489 return choice_val
490
491
492def find_choicevals(choice_str, choice_list):
493 """
494 Take numbers as space-separated string and return vals list from
495 choice_list, empty list if oob. choice_list is a simple python
496 list.
497 """
498 choice_vals = []
499
500 choices = choice_str.split()
501 for choice in choices:
502 choice_vals.append(find_choiceval(choice, choice_list))
503
504 return choice_vals
505
506
507def default(input_str, name):
508 """
509 Return default if no input_str, otherwise stripped input_str.
510 """
511 if not input_str:
512 return name
513
514 return input_str.strip()
515
516
517def verify_git_repo(giturl):
518 """
519 Verify that the giturl passed in can be connected to. This can be
520 used as a check for the existence of the given repo and/or basic
521 git remote connectivity.
522
523 Returns True if the connection was successful, fals otherwise
524 """
525 if not giturl:
526 return False
527
528 gitcmd = "git ls-remote %s > /dev/null 2>&1" % (giturl)
529 rc = subprocess.call(gitcmd, shell=True)
530 if rc == 0:
531 return True
532
533 return False
534
535
536def get_verified_git_repo(input_str, name):
537 """
538 Return git repo if verified, otherwise loop forever asking user
539 for filename.
540 """
541 msg = input_str.strip() + " "
542
543 giturl = default(raw_input(msg), name)
544
545 while True:
546 if verify_git_repo(giturl):
547 return giturl
548 giturl = default(raw_input(msg), name)
549
550
551def get_verified_file(input_str, name, filename_can_be_null):
552 """
553 Return filename if the file exists, otherwise loop forever asking
554 user for filename.
555 """
556 msg = input_str.strip() + " "
557
558 filename = default(raw_input(msg), name)
559
560 while True:
561 if not filename and filename_can_be_null:
562 return filename
563 if os.path.isfile(filename):
564 return filename
565 filename = default(raw_input(msg), name)
566
567
568def replace_file(replace_this, with_this):
569 """
570 Replace the given file with the contents of filename, retaining
571 the original filename.
572 """
573 try:
574 replace_this.close()
575 shutil.copy(with_this, replace_this.name)
576 except IOError:
577 pass
578
579
580def boolean(input_str, name):
581 """
582 Return lowercase version of first char in string, or value in name.
583 """
584 if not input_str:
585 return name
586
587 str = input_str.lower().strip()
588 if str and str[0] == "y" or str[0] == "n":
589 return str[0]
590 else:
591 return name
592
593
594def strip_base(input_str):
595 """
596 strip '/base' off the end of input_str, so we can use 'base' in
597 the branch names we present to the user.
598 """
599 if input_str and input_str.endswith("/base"):
600 return input_str[:-len("/base")]
601 return input_str.strip()
602
603
604deferred_choices = {}
605
606def gen_choices_defer(input_line, context, checklist = False):
607 """
608 Save the context hashed the name of the input item, which will be
609 passed to the gen function later.
610 """
611 name = input_line.props["name"]
612
613 try:
614 nameappend = input_line.props["nameappend"]
615 except KeyError:
616 nameappend = ""
617
618 try:
619 branches_base = input_line.props["branches_base"]
620 except KeyError:
621 branches_base = ""
622
623 filename = input_line.props["filename"]
624
625 closetag_start = filename.find(CLOSE_TAG)
626
627 if closetag_start != -1:
628 filename = filename[closetag_start + len(CLOSE_TAG):]
629
630 filename = filename.strip()
631 filename = os.path.splitext(filename)[0]
632
633 captured_context = capture_context(context)
634 context["filename"] = filename
635 captured_context["filename"] = filename
636 context["nameappend"] = nameappend
637 captured_context["nameappend"] = nameappend
638 context["branches_base"] = branches_base
639 captured_context["branches_base"] = branches_base
640
641 deferred_choice = (input_line, captured_context, checklist)
642 key = name + "_" + filename + "_" + nameappend
643 deferred_choices[key] = deferred_choice
644
645
646def invoke_deferred_choices(name):
647 """
648 Invoke the choice generation function using the context hashed by
649 'name'.
650 """
651 deferred_choice = deferred_choices[name]
652 input_line = deferred_choice[0]
653 context = deferred_choice[1]
654 checklist = deferred_choice[2]
655
656 context["name"] = name
657
658 choices = input_line.gen_choices(context, checklist)
659
660 return choices
661
662
663class ChoicelistInputLine(ListInputLine):
664 """
665 Base class for choicelist Input lines.
666 props:
667 name: example - "xserver_choice"
668 msg: example - "Please select an xserver for this machine"
669 result:
670 Sets the value of the variable specified by 'name' to whichever Choice was chosen
671 example - xserver_choice = "xserver_vesa"
672 """
673 def __init__(self, props, tag, lineno):
674 ListInputLine.__init__(self, props, tag, lineno)
675
676 def gen(self, context = None):
677 InputLine.gen(self, context)
678
679 gen_choices_defer(self, context)
680 name = self.props["name"]
681 nameappend = context["nameappend"]
682 filename = context["filename"]
683
684 try:
685 default_choice = self.props["default"]
686 except KeyError:
687 default_choice = ""
688
689 line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"
690
691 return line
692
693
694class ListValInputLine(InputLine):
695 """
696 Abstract base class for choice and checkbox Input lines.
697 """
698 def __init__(self, props, tag, lineno):
699 InputLine.__init__(self, props, tag, lineno)
700
701 try:
702 self.val = self.props["val"]
703 except KeyError:
704 self.parse_error("No input 'val' property found", self.lineno, self.line)
705
706 try:
707 self.desc = self.props["msg"]
708 except KeyError:
709 self.parse_error("No input 'msg' property found", self.lineno, self.line)
710
711
712class ChoiceInputLine(ListValInputLine):
713 """
714 Base class for choicelist item Input lines.
715 """
716 def __init__(self, props, tag, lineno):
717 ListValInputLine.__init__(self, props, tag, lineno)
718
719 def gen(self, context = None):
720 return None
721
722
723class ChecklistInputLine(ListInputLine):
724 """
725 Base class for checklist Input lines.
726 """
727 def __init__(self, props, tag, lineno):
728 ListInputLine.__init__(self, props, tag, lineno)
729
730 def gen(self, context = None):
731 InputLine.gen(self, context)
732
733 gen_choices_defer(self, context, True)
734 name = self.props["name"]
735 nameappend = context["nameappend"]
736 filename = context["filename"]
737
738 try:
739 default_choice = self.props["default"]
740 except KeyError:
741 default_choice = ""
742
743 line = name + " = default(invoke_deferred_choices(\"" + name + "_" + filename + "_" + nameappend + "\"), \"" + default_choice + "\")"
744
745 return line
746
747
748class CheckInputLine(ListValInputLine):
749 """
750 Base class for checklist item Input lines.
751 """
752 def __init__(self, props, tag, lineno):
753 ListValInputLine.__init__(self, props, tag, lineno)
754
755 def gen(self, context = None):
756 return None
757
758
759class SubstrateBase(object):
760 """
761 Base class for both expanded and unexpanded file and dir container
762 objects.
763 """
764 def __init__(self, filename, filebase, out_filebase):
765 self.filename = filename
766 self.filebase = filebase
767 self.out_filebase = out_filebase
768 self.raw_lines = []
769 self.expanded_lines = []
770 self.prev_choicelist = None
771
772 def parse_error(self, msg, lineno, line):
773 raise SyntaxError("%s: [%s: %d]: %s" % (msg, self.filename, lineno, line))
774
775 def expand_input_tag(self, tag, lineno):
776 """
777 Input tags consist of the word 'input' at the beginning,
778 followed by name:value property pairs which are converted into
779 a dictionary.
780 """
781 propstr = tag[len(INPUT_TAG):]
782
783 props = dict(prop.split(":", 1) for prop in shlex.split(propstr))
784 props["filename"] = self.filename
785
786 input_type = props[INPUT_TYPE_PROPERTY]
787 if not props[INPUT_TYPE_PROPERTY]:
788 self.parse_error("No input 'type' property found", lineno, tag)
789
790 if input_type == "boolean":
791 return BooleanInputLine(props, tag, lineno)
792 if input_type == "edit":
793 return EditBoxInputLine(props, tag, lineno)
794 if input_type == "edit-git-repo":
795 return GitRepoEditBoxInputLine(props, tag, lineno)
796 if input_type == "edit-file":
797 return FileEditBoxInputLine(props, tag, lineno)
798 elif input_type == "choicelist":
799 self.prev_choicelist = ChoicelistInputLine(props, tag, lineno)
800 return self.prev_choicelist
801 elif input_type == "choice":
802 if not self.prev_choicelist:
803 self.parse_error("Found 'choice' input tag but no previous choicelist",
804 lineno, tag)
805 choice = ChoiceInputLine(props, tag, lineno)
806 self.prev_choicelist.choices.append(choice)
807 return choice
808 elif input_type == "checklist":
809 return ChecklistInputLine(props, tag, lineno)
810 elif input_type == "check":
811 return CheckInputLine(props, tag, lineno)
812
813 def expand_assignment_tag(self, start, line, lineno):
814 """
815 Expand all tags in a line.
816 """
817 expanded_line = AssignmentLine(line.rstrip())
818
819 while start != -1:
820 end = line.find(CLOSE_TAG, start)
821 if end == -1:
822 self.parse_error("No close tag found for assignment tag", lineno, line)
823 else:
824 name = line[start + len(ASSIGN_TAG):end].strip()
825 expanded_line.add_assignment(start, end + len(CLOSE_TAG), name)
826 start = line.find(ASSIGN_TAG, end)
827
828 return expanded_line
829
830 def expand_tag(self, line, lineno):
831 """
832 Returns a processed tag line, or None if there was no tag
833
834 The rules for tags are very simple:
835 - No nested tags
836 - Tags start with {{ and end with }}
837 - An assign tag, {{=, can appear anywhere and will
838 be replaced with what the assignment evaluates to
839 - Any other tag occupies the whole line it is on
840 - if there's anything else on the tag line, it's an error
841 - if it starts with 'input', it's an input tag and
842 will only be used for prompting and setting variables
843 - anything else is straight Python
844 - tags are in effect only until the next blank line or tag or 'pass' tag
845 - we don't have indentation in tags, but we need some way to end a block
846 forcefully without blank lines or other tags - that's the 'pass' tag
847 - todo: implement pass tag
848 - directories and filenames can have tags as well, but only assignment
849 and 'if' code lines
850 - directories and filenames are the only case where normal tags can
851 coexist with normal text on the same 'line'
852 """
853 start = line.find(ASSIGN_TAG)
854 if start != -1:
855 return self.expand_assignment_tag(start, line, lineno)
856
857 start = line.find(OPEN_TAG)
858 if start == -1:
859 return None
860
861 end = line.find(CLOSE_TAG, 0)
862 if end == -1:
863 self.parse_error("No close tag found for open tag", lineno, line)
864
865 tag = line[start + len(OPEN_TAG):end].strip()
866
867 if not tag.lstrip().startswith(INPUT_TAG):
868 return CodeLine(tag)
869
870 return self.expand_input_tag(tag, lineno)
871
872 def expand_file_or_dir_name(self):
873 """
874 Expand file or dir names into codeline. Dirnames and
875 filenames can only have assignments or if statements. First
876 translate if statements into CodeLine + (dirname or filename
877 creation).
878 """
879 lineno = 0
880
881 line = self.filename[len(self.filebase):]
882 if line.startswith("/"):
883 line = line[1:]
884 opentag_start = -1
885
886 start = line.find(OPEN_TAG)
887 while start != -1:
888 if not line[start:].startswith(ASSIGN_TAG):
889 opentag_start = start
890 break
891 start += len(ASSIGN_TAG)
892 start = line.find(OPEN_TAG, start)
893
894 if opentag_start != -1:
895 end = line.find(CLOSE_TAG, opentag_start)
896 if end == -1:
897 self.parse_error("No close tag found for open tag", lineno, line)
898 # we have a {{ tag i.e. code
899 tag = line[opentag_start + len(OPEN_TAG):end].strip()
900
901 if not tag.lstrip().startswith(IF_TAG):
902 self.parse_error("Only 'if' tags are allowed in file or directory names",
903 lineno, line)
904 self.expanded_lines.append(CodeLine(tag))
905
906 # everything after }} is the actual filename (possibly with assignments)
907 # everything before is the pathname
908 line = line[:opentag_start] + line[end + len(CLOSE_TAG):].strip()
909
910 assign_start = line.find(ASSIGN_TAG)
911 if assign_start != -1:
912 assignment_tag = self.expand_assignment_tag(assign_start, line, lineno)
913 if isinstance(self, SubstrateFile):
914 assignment_tag.is_filename = True
915 assignment_tag.out_filebase = self.out_filebase
916 elif isinstance(self, SubstrateDir):
917 assignment_tag.is_dirname = True
918 assignment_tag.out_filebase = self.out_filebase
919 self.expanded_lines.append(assignment_tag)
920 return
921
922 normal_line = NormalLine(line)
923 if isinstance(self, SubstrateFile):
924 normal_line.is_filename = True
925 normal_line.out_filebase = self.out_filebase
926 elif isinstance(self, SubstrateDir):
927 normal_line.is_dirname = True
928 normal_line.out_filebase = self.out_filebase
929 self.expanded_lines.append(normal_line)
930
931 def expand(self):
932 """
933 Expand the file or dir name first, eventually this ends up
934 creating the file or dir.
935 """
936 self.expand_file_or_dir_name()
937
938
939class SubstrateFile(SubstrateBase):
940 """
941 Container for both expanded and unexpanded substrate files.
942 """
943 def __init__(self, filename, filebase, out_filebase):
944 SubstrateBase.__init__(self, filename, filebase, out_filebase)
945
946 def read(self):
947 if self.raw_lines:
948 return
949 f = open(self.filename)
950 self.raw_lines = f.readlines()
951
952 def expand(self):
953 """Expand the contents of all template tags in the file."""
954 SubstrateBase.expand(self)
955 self.read()
956
957 for lineno, line in enumerate(self.raw_lines):
958 expanded_line = self.expand_tag(line, lineno + 1) # humans not 0-based
959 if not expanded_line:
960 expanded_line = NormalLine(line.rstrip())
961 self.expanded_lines.append(expanded_line)
962
963 def gen(self, context = None):
964 """Generate the code that generates the BSP."""
965 base_indent = 0
966
967 indent = new_indent = base_indent
968
969 for line in self.expanded_lines:
970 genline = line.gen(context)
971 if not genline:
972 continue
973 if isinstance(line, InputLine):
974 line.generated_line = genline
975 continue
976 if genline.startswith(OPEN_START):
977 if indent == 1:
978 base_indent = 1
979 if indent:
980 if genline == BLANKLINE_STR or (not genline.startswith(NORMAL_START)
981 and not genline.startswith(OPEN_START)):
982 indent = new_indent = base_indent
983 if genline.endswith(":"):
984 new_indent = base_indent + 1
985 line.generated_line = (indent * INDENT_STR) + genline
986 indent = new_indent
987
988
989class SubstrateDir(SubstrateBase):
990 """
991 Container for both expanded and unexpanded substrate dirs.
992 """
993 def __init__(self, filename, filebase, out_filebase):
994 SubstrateBase.__init__(self, filename, filebase, out_filebase)
995
996 def expand(self):
997 SubstrateBase.expand(self)
998
999 def gen(self, context = None):
1000 """Generate the code that generates the BSP."""
1001 indent = new_indent = 0
1002 for line in self.expanded_lines:
1003 genline = line.gen(context)
1004 if not genline:
1005 continue
1006 if genline.endswith(":"):
1007 new_indent = 1
1008 else:
1009 new_indent = 0
1010 line.generated_line = (indent * INDENT_STR) + genline
1011 indent = new_indent
1012
1013
1014def expand_target(target, all_files, out_filebase):
1015 """
1016 Expand the contents of all template tags in the target. This
1017 means removing tags and categorizing or creating lines so that
1018 future passes can process and present input lines and generate the
1019 corresponding lines of the Python program that will be exec'ed to
1020 actually produce the final BSP. 'all_files' includes directories.
1021 """
1022 for root, dirs, files in os.walk(target):
1023 for file in files:
1024 if file.endswith("~") or file.endswith("#"):
1025 continue
1026 f = os.path.join(root, file)
1027 sfile = SubstrateFile(f, target, out_filebase)
1028 sfile.expand()
1029 all_files.append(sfile)
1030
1031 for dir in dirs:
1032 d = os.path.join(root, dir)
1033 sdir = SubstrateDir(d, target, out_filebase)
1034 sdir.expand()
1035 all_files.append(sdir)
1036
1037
1038def gen_program_machine_lines(machine, program_lines):
1039 """
1040 Use the input values we got from the command line.
1041 """
1042 line = "machine = \"" + machine + "\""
1043 program_lines.append(line)
1044
1045 line = "layer_name = \"" + machine + "\""
1046 program_lines.append(line)
1047
1048
1049def sort_inputlines(input_lines):
1050 """Sort input lines according to priority (position)."""
1051 input_lines.sort(key = lambda l: l.prio)
1052
1053
1054def find_parent_dependency(lines, depends_on):
1055 for i, line in lines:
1056 if isinstance(line, CodeLine):
1057 continue
1058 if line.props["name"] == depends_on:
1059 return i
1060
1061 return -1
1062
1063
1064def process_inputline_dependencies(input_lines, all_inputlines):
1065 """If any input lines depend on others, put the others first."""
1066 for line in input_lines:
1067 if isinstance(line, InputLineGroup):
1068 group_inputlines = []
1069 process_inputline_dependencies(line.group, group_inputlines)
1070 line.group = group_inputlines
1071 all_inputlines.append(line)
1072 continue
1073
1074 if isinstance(line, CodeLine) or isinstance(line, NormalLine):
1075 all_inputlines.append(line)
1076 continue
1077
1078 try:
1079 depends_on = line.props["depends-on"]
1080 depends_codeline = "if " + line.props["depends-on"] + " == \"" + line.props["depends-on-val"] + "\":"
1081 all_inputlines.append(CodeLine(depends_codeline))
1082 all_inputlines.append(line)
1083 except KeyError:
1084 all_inputlines.append(line)
1085
1086
1087def conditional_filename(filename):
1088 """
1089 Check if the filename itself contains a conditional statement. If
1090 so, return a codeline for it.
1091 """
1092 opentag_start = filename.find(OPEN_TAG)
1093
1094 if opentag_start != -1:
1095 if filename[opentag_start:].startswith(ASSIGN_TAG):
1096 return None
1097 end = filename.find(CLOSE_TAG, opentag_start)
1098 if end == -1:
1099 print "No close tag found for open tag in filename %s" % filename
1100 sys.exit(1)
1101
1102 # we have a {{ tag i.e. code
1103 tag = filename[opentag_start + len(OPEN_TAG):end].strip()
1104 if not tag.lstrip().startswith(IF_TAG):
1105 print "Only 'if' tags are allowed in file or directory names, filename: %s" % filename
1106 sys.exit(1)
1107
1108 return CodeLine(tag)
1109
1110 return None
1111
1112
1113class InputLineGroup(InputLine):
1114 """
1115 InputLine that does nothing but group other input lines
1116 corresponding to all the input lines in a SubstrateFile so they
1117 can be generated as a group. prio is the only property used.
1118 """
1119 def __init__(self, codeline):
1120 InputLine.__init__(self, {}, "", 0)
1121 self.group = []
1122 self.prio = sys.maxint
1123 self.group.append(codeline)
1124
1125 def append(self, line):
1126 self.group.append(line)
1127 if line.prio < self.prio:
1128 self.prio = line.prio
1129
1130 def len(self):
1131 return len(self.group)
1132
1133
1134def gather_inputlines(files):
1135 """
1136 Gather all the InputLines - we want to generate them first.
1137 """
1138 all_inputlines = []
1139 input_lines = []
1140
1141 for file in files:
1142 if isinstance(file, SubstrateFile):
1143 group = None
1144 basename = os.path.basename(file.filename)
1145
1146 codeline = conditional_filename(basename)
1147 if codeline:
1148 group = InputLineGroup(codeline)
1149
1150 have_condition = False
1151 condition_to_write = None
1152 for line in file.expanded_lines:
1153 if isinstance(line, CodeLine):
1154 have_condition = True
1155 condition_to_write = line
1156 continue
1157 if isinstance(line, InputLine):
1158 if group:
1159 if condition_to_write:
1160 condition_to_write.prio = line.prio
1161 condition_to_write.discard = True
1162 group.append(condition_to_write)
1163 condition_to_write = None
1164 group.append(line)
1165 else:
1166 if condition_to_write:
1167 condition_to_write.prio = line.prio
1168 condition_to_write.discard = True
1169 input_lines.append(condition_to_write)
1170 condition_to_write = None
1171 input_lines.append(line)
1172 else:
1173 if condition_to_write:
1174 condition_to_write = None
1175 if have_condition:
1176 if not line.line.strip():
1177 line.discard = True
1178 input_lines.append(line)
1179 have_condition = False
1180
1181 if group and group.len() > 1:
1182 input_lines.append(group)
1183
1184 sort_inputlines(input_lines)
1185 process_inputline_dependencies(input_lines, all_inputlines)
1186
1187 return all_inputlines
1188
1189
1190def run_program_lines(linelist, codedump):
1191 """
1192 For a single file, print all the python code into a buf and execute it.
1193 """
1194 buf = "\n".join(linelist)
1195
1196 if codedump:
1197 of = open("bspgen.out", "w")
1198 of.write(buf)
1199 of.close()
1200 exec buf
1201
1202
1203def gen_target(files, context = None):
1204 """
1205 Generate the python code for each file.
1206 """
1207 for file in files:
1208 file.gen(context)
1209
1210
1211def gen_program_header_lines(program_lines):
1212 """
1213 Generate any imports we need.
1214 """
1215 program_lines.append("current_file = \"\"")
1216
1217
1218def gen_supplied_property_vals(properties, program_lines):
1219 """
1220 Generate user-specified entries for input values instead of
1221 generating input prompts.
1222 """
1223 for name, val in properties.iteritems():
1224 program_line = name + " = \"" + val + "\""
1225 program_lines.append(program_line)
1226
1227
1228def gen_initial_property_vals(input_lines, program_lines):
1229 """
1230 Generate null or default entries for input values, so we don't
1231 have undefined variables.
1232 """
1233 for line in input_lines:
1234 if isinstance(line, InputLineGroup):
1235 gen_initial_property_vals(line.group, program_lines)
1236 continue
1237
1238 if isinstance(line, InputLine):
1239 try:
1240 name = line.props["name"]
1241 try:
1242 default_val = "\"" + line.props["default"] + "\""
1243 except:
1244 default_val = "\"\""
1245 program_line = name + " = " + default_val
1246 program_lines.append(program_line)
1247 except KeyError:
1248 pass
1249
1250
1251def gen_program_input_lines(input_lines, program_lines, context, in_group = False):
1252 """
1253 Generate only the input lines used for prompting the user. For
1254 that, we only have input lines and CodeLines that affect the next
1255 input line.
1256 """
1257 indent = new_indent = 0
1258
1259 for line in input_lines:
1260 if isinstance(line, InputLineGroup):
1261 gen_program_input_lines(line.group, program_lines, context, True)
1262 continue
1263 if not line.line.strip():
1264 continue
1265
1266 genline = line.gen(context)
1267 if not genline:
1268 continue
1269 if genline.endswith(":"):
1270 new_indent += 1
1271 else:
1272 if indent > 1 or (not in_group and indent):
1273 new_indent -= 1
1274
1275 line.generated_line = (indent * INDENT_STR) + genline
1276 program_lines.append(line.generated_line)
1277
1278 indent = new_indent
1279
1280
1281def gen_program_lines(target_files, program_lines):
1282 """
1283 Generate the program lines that make up the BSP generation
1284 program. This appends the generated lines of all target_files to
1285 program_lines, and skips input lines, which are dealt with
1286 separately, or omitted.
1287 """
1288 for file in target_files:
1289 if file.filename.endswith("noinstall"):
1290 continue
1291
1292 for line in file.expanded_lines:
1293 if isinstance(line, InputLine):
1294 continue
1295 if line.discard:
1296 continue
1297
1298 program_lines.append(line.generated_line)
1299
1300
1301def create_context(machine, arch, scripts_path):
1302 """
1303 Create a context object for use in deferred function invocation.
1304 """
1305 context = {}
1306
1307 context["machine"] = machine
1308 context["arch"] = arch
1309 context["scripts_path"] = scripts_path
1310
1311 return context
1312
1313
1314def capture_context(context):
1315 """
1316 Create a context object for use in deferred function invocation.
1317 """
1318 captured_context = {}
1319
1320 captured_context["machine"] = context["machine"]
1321 captured_context["arch"] = context["arch"]
1322 captured_context["scripts_path"] = context["scripts_path"]
1323
1324 return captured_context
1325
1326
1327def expand_targets(context, bsp_output_dir, expand_common=True):
1328 """
1329 Expand all the tags in both the common and machine-specific
1330 'targets'.
1331
1332 If expand_common is False, don't expand the common target (this
1333 option is used to create special-purpose layers).
1334 """
1335 target_files = []
1336
1337 machine = context["machine"]
1338 arch = context["arch"]
1339 scripts_path = context["scripts_path"]
1340
1341 lib_path = scripts_path + '/lib'
1342 bsp_path = lib_path + '/bsp'
1343 arch_path = bsp_path + '/substrate/target/arch'
1344
1345 if expand_common:
1346 common = os.path.join(arch_path, "common")
1347 expand_target(common, target_files, bsp_output_dir)
1348
1349 arches = os.listdir(arch_path)
1350 if arch not in arches or arch == "common":
1351 print "Invalid karch, exiting\n"
1352 sys.exit(1)
1353
1354 target = os.path.join(arch_path, arch)
1355 expand_target(target, target_files, bsp_output_dir)
1356
1357 gen_target(target_files, context)
1358
1359 return target_files
1360
1361
1362def yocto_common_create(machine, target, scripts_path, layer_output_dir, codedump, properties_file, properties_str="", expand_common=True):
1363 """
1364 Common layer-creation code
1365
1366 machine - user-defined machine name (if needed, will generate 'machine' var)
1367 target - the 'target' the layer will be based on, must be one in
1368 scripts/lib/bsp/substrate/target/arch
1369 scripts_path - absolute path to yocto /scripts dir
1370 layer_output_dir - dirname to create for layer
1371 codedump - dump generated code to bspgen.out
1372 properties_file - use values from this file if nonempty i.e no prompting
1373 properties_str - use values from this string if nonempty i.e no prompting
1374 expand_common - boolean, use the contents of (for bsp layers) arch/common
1375 """
1376 if os.path.exists(layer_output_dir):
1377 print "\nlayer output dir already exists, exiting. (%s)" % layer_output_dir
1378 sys.exit(1)
1379
1380 properties = None
1381
1382 if properties_file:
1383 try:
1384 infile = open(properties_file, "r")
1385 except IOError:
1386 print "Couldn't open properties file %s for reading, exiting" % properties_file
1387 sys.exit(1)
1388
1389 properties = json.load(infile)
1390
1391 if properties_str and not properties:
1392 properties = json.loads(properties_str)
1393
1394 os.mkdir(layer_output_dir)
1395
1396 context = create_context(machine, target, scripts_path)
1397 target_files = expand_targets(context, layer_output_dir, expand_common)
1398
1399 input_lines = gather_inputlines(target_files)
1400
1401 program_lines = []
1402
1403 gen_program_header_lines(program_lines)
1404
1405 gen_initial_property_vals(input_lines, program_lines)
1406
1407 if properties:
1408 gen_supplied_property_vals(properties, program_lines)
1409
1410 gen_program_machine_lines(machine, program_lines)
1411
1412 if not properties:
1413 gen_program_input_lines(input_lines, program_lines, context)
1414
1415 gen_program_lines(target_files, program_lines)
1416
1417 run_program_lines(program_lines, codedump)
1418
1419
1420def yocto_layer_create(layer_name, scripts_path, layer_output_dir, codedump, properties_file, properties=""):
1421 """
1422 Create yocto layer
1423
1424 layer_name - user-defined layer name
1425 scripts_path - absolute path to yocto /scripts dir
1426 layer_output_dir - dirname to create for layer
1427 codedump - dump generated code to bspgen.out
1428 properties_file - use values from this file if nonempty i.e no prompting
1429 properties - use values from this string if nonempty i.e no prompting
1430 """
1431 yocto_common_create(layer_name, "layer", scripts_path, layer_output_dir, codedump, properties_file, properties, False)
1432
1433 print "\nNew layer created in %s.\n" % (layer_output_dir)
1434 print "Don't forget to add it to your BBLAYERS (for details see %s\README)." % (layer_output_dir)
1435
1436
1437def yocto_bsp_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties=None):
1438 """
1439 Create bsp
1440
1441 machine - user-defined machine name
1442 arch - the arch the bsp will be based on, must be one in
1443 scripts/lib/bsp/substrate/target/arch
1444 scripts_path - absolute path to yocto /scripts dir
1445 bsp_output_dir - dirname to create for BSP
1446 codedump - dump generated code to bspgen.out
1447 properties_file - use values from this file if nonempty i.e no prompting
1448 properties - use values from this string if nonempty i.e no prompting
1449 """
1450 yocto_common_create(machine, arch, scripts_path, bsp_output_dir, codedump, properties_file, properties)
1451
1452 print "\nNew %s BSP created in %s" % (arch, bsp_output_dir)
1453
1454
1455def print_dict(items, indent = 0):
1456 """
1457 Print the values in a possibly nested dictionary.
1458 """
1459 for key, val in items.iteritems():
1460 print " "*indent + "\"%s\" :" % key,
1461 if type(val) == dict:
1462 print "{"
1463 print_dict(val, indent + 1)
1464 print " "*indent + "}"
1465 else:
1466 print "%s" % val
1467
1468
1469def get_properties(input_lines):
1470 """
1471 Get the complete set of properties for all the input items in the
1472 BSP, as a possibly nested dictionary.
1473 """
1474 properties = {}
1475
1476 for line in input_lines:
1477 if isinstance(line, InputLineGroup):
1478 statement = line.group[0].line
1479 group_properties = get_properties(line.group)
1480 properties[statement] = group_properties
1481 continue
1482
1483 if not isinstance(line, InputLine):
1484 continue
1485
1486 if isinstance(line, ChoiceInputLine):
1487 continue
1488
1489 props = line.props
1490 item = {}
1491 name = props["name"]
1492 for key, val in props.items():
1493 if not key == "name":
1494 item[key] = val
1495 properties[name] = item
1496
1497 return properties
1498
1499
1500def yocto_layer_list_properties(arch, scripts_path, properties_file, expand_common=True):
1501 """
1502 List the complete set of properties for all the input items in the
1503 layer. If properties_file is non-null, write the complete set of
1504 properties as a nested JSON object corresponding to a possibly
1505 nested dictionary.
1506 """
1507 context = create_context("unused", arch, scripts_path)
1508 target_files = expand_targets(context, "unused", expand_common)
1509
1510 input_lines = gather_inputlines(target_files)
1511
1512 properties = get_properties(input_lines)
1513 if properties_file:
1514 try:
1515 of = open(properties_file, "w")
1516 except IOError:
1517 print "Couldn't open properties file %s for writing, exiting" % properties_file
1518 sys.exit(1)
1519
1520 json.dump(properties, of)
1521
1522 print_dict(properties)
1523
1524
1525def split_nested_property(property):
1526 """
1527 A property name of the form x.y describes a nested property
1528 i.e. the property y is contained within x and can be addressed
1529 using standard JSON syntax for nested properties. Note that if a
1530 property name itself contains '.', it should be contained in
1531 double quotes.
1532 """
1533 splittable_property = ""
1534 in_quotes = False
1535 for c in property:
1536 if c == '.' and not in_quotes:
1537 splittable_property += '\n'
1538 continue
1539 if c == '"':
1540 in_quotes = not in_quotes
1541 splittable_property += c
1542
1543 split_properties = splittable_property.split('\n')
1544
1545 if len(split_properties) > 1:
1546 return split_properties
1547
1548 return None
1549
1550
1551def find_input_line_group(substring, input_lines):
1552 """
1553 Find and return the InputLineGroup containing the specified substring.
1554 """
1555 for line in input_lines:
1556 if isinstance(line, InputLineGroup):
1557 if substring in line.group[0].line:
1558 return line
1559
1560 return None
1561
1562
1563def find_input_line(name, input_lines):
1564 """
1565 Find the input line with the specified name.
1566 """
1567 for line in input_lines:
1568 if isinstance(line, InputLineGroup):
1569 l = find_input_line(name, line.group)
1570 if l:
1571 return l
1572
1573 if isinstance(line, InputLine):
1574 try:
1575 if line.props["name"] == name:
1576 return line
1577 if line.props["name"] + "_" + line.props["nameappend"] == name:
1578 return line
1579 except KeyError:
1580 pass
1581
1582 return None
1583
1584
1585def print_values(type, values_list):
1586 """
1587 Print the values in the given list of values.
1588 """
1589 if type == "choicelist":
1590 for value in values_list:
1591 print "[\"%s\", \"%s\"]" % (value[0], value[1])
1592 elif type == "boolean":
1593 for value in values_list:
1594 print "[\"%s\", \"%s\"]" % (value[0], value[1])
1595
1596
1597def yocto_layer_list_property_values(arch, property, scripts_path, properties_file, expand_common=True):
1598 """
1599 List the possible values for a given input property. If
1600 properties_file is non-null, write the complete set of properties
1601 as a JSON object corresponding to an array of possible values.
1602 """
1603 context = create_context("unused", arch, scripts_path)
1604 context["name"] = property
1605
1606 target_files = expand_targets(context, "unused", expand_common)
1607
1608 input_lines = gather_inputlines(target_files)
1609
1610 properties = get_properties(input_lines)
1611
1612 nested_properties = split_nested_property(property)
1613 if nested_properties:
1614 # currently the outer property of a nested property always
1615 # corresponds to an input line group
1616 input_line_group = find_input_line_group(nested_properties[0], input_lines)
1617 if input_line_group:
1618 input_lines[:] = input_line_group.group[1:]
1619 # The inner property of a nested property name is the
1620 # actual property name we want, so reset to that
1621 property = nested_properties[1]
1622
1623 input_line = find_input_line(property, input_lines)
1624 if not input_line:
1625 print "Couldn't find values for property %s" % property
1626 return
1627
1628 values_list = []
1629
1630 type = input_line.props["type"]
1631 if type == "boolean":
1632 values_list.append(["y", "n"])
1633 elif type == "choicelist" or type == "checklist":
1634 try:
1635 gen_fn = input_line.props["gen"]
1636 if nested_properties:
1637 context["filename"] = nested_properties[0]
1638 try:
1639 context["branches_base"] = input_line.props["branches_base"]
1640 except KeyError:
1641 context["branches_base"] = None
1642 values_list = input_line.gen_choices_list(context, False)
1643 except KeyError:
1644 for choice in input_line.choices:
1645 choicepair = []
1646 choicepair.append(choice.val)
1647 choicepair.append(choice.desc)
1648 values_list.append(choicepair)
1649
1650 if properties_file:
1651 try:
1652 of = open(properties_file, "w")
1653 except IOError:
1654 print "Couldn't open properties file %s for writing, exiting" % properties_file
1655 sys.exit(1)
1656
1657 json.dump(values_list, of)
1658
1659 print_values(type, values_list)
1660
1661
1662def yocto_bsp_list(args, scripts_path, properties_file):
1663 """
1664 Print available architectures, or the complete list of properties
1665 defined by the BSP, or the possible values for a particular BSP
1666 property.
1667 """
1668 if len(args) < 1:
1669 return False
1670
1671 if args[0] == "karch":
1672 lib_path = scripts_path + '/lib'
1673 bsp_path = lib_path + '/bsp'
1674 arch_path = bsp_path + '/substrate/target/arch'
1675 print "Architectures available:"
1676 for arch in os.listdir(arch_path):
1677 if arch == "common" or arch == "layer":
1678 continue
1679 print " %s" % arch
1680 return True
1681 else:
1682 arch = args[0]
1683
1684 if len(args) < 2 or len(args) > 3:
1685 return False
1686
1687 if len(args) == 2:
1688 if args[1] == "properties":
1689 yocto_layer_list_properties(arch, scripts_path, properties_file)
1690 else:
1691 return False
1692
1693 if len(args) == 3:
1694 if args[1] == "property":
1695 yocto_layer_list_property_values(arch, args[2], scripts_path, properties_file)
1696 else:
1697 return False
1698
1699 return True
1700
1701
1702def yocto_layer_list(args, scripts_path, properties_file):
1703 """
1704 Print the complete list of input properties defined by the layer,
1705 or the possible values for a particular layer property.
1706 """
1707 if len(args) < 1:
1708 return False
1709
1710 if len(args) < 1 or len(args) > 2:
1711 return False
1712
1713 if len(args) == 1:
1714 if args[0] == "properties":
1715 yocto_layer_list_properties("layer", scripts_path, properties_file, False)
1716 else:
1717 return False
1718
1719 if len(args) == 2:
1720 if args[0] == "property":
1721 yocto_layer_list_property_values("layer", args[1], scripts_path, properties_file, False)
1722 else:
1723 return False
1724
1725 return True
1726
1727
1728def map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
1729 """
1730 Return the linux-yocto bsp branch to use with the specified
1731 kbranch. This handles the -standard variants for 3.4 and 3.8; the
1732 other variants don't need mappings.
1733 """
1734 if need_new_kbranch == "y":
1735 kbranch = new_kbranch
1736 else:
1737 kbranch = existing_kbranch
1738
1739 if kbranch.startswith("standard/common-pc-64"):
1740 return "bsp/common-pc-64/common-pc-64-standard.scc"
1741 if kbranch.startswith("standard/common-pc"):
1742 return "bsp/common-pc/common-pc-standard.scc"
1743 else:
1744 return "ktypes/standard/standard.scc"
1745
1746
1747def map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
1748 """
1749 Return the linux-yocto bsp branch to use with the specified
1750 kbranch. This handles the -preempt-rt variants for 3.4 and 3.8;
1751 the other variants don't need mappings.
1752 """
1753 if need_new_kbranch == "y":
1754 kbranch = new_kbranch
1755 else:
1756 kbranch = existing_kbranch
1757
1758 if kbranch.startswith("standard/preempt-rt/common-pc-64"):
1759 return "bsp/common-pc-64/common-pc-64-preempt-rt.scc"
1760 if kbranch.startswith("standard/preempt-rt/common-pc"):
1761 return "bsp/common-pc/common-pc-preempt-rt.scc"
1762 else:
1763 return "ktypes/preempt-rt/preempt-rt.scc"
1764
1765
1766def map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch):
1767 """
1768 Return the linux-yocto bsp branch to use with the specified
1769 kbranch. This handles the -tiny variants for 3.4 and 3.8; the
1770 other variants don't need mappings.
1771 """
1772 if need_new_kbranch == "y":
1773 kbranch = new_kbranch
1774 else:
1775 kbranch = existing_kbranch
1776
1777 if kbranch.startswith("standard/tiny/common-pc"):
1778 return "bsp/common-pc/common-pc-tiny.scc"
1779 else:
1780 return "ktypes/tiny/tiny.scc"
diff --git a/scripts/lib/bsp/help.py b/scripts/lib/bsp/help.py
new file mode 100644
index 0000000000..7c436d6be0
--- /dev/null
+++ b/scripts/lib/bsp/help.py
@@ -0,0 +1,1043 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2012, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module implements some basic help invocation functions along
22# with the bulk of the help topic text for the Yocto BSP Tools.
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] intel.com>
26#
27
28import subprocess
29import logging
30
31
32def subcommand_error(args):
33 logging.info("invalid subcommand %s" % args[0])
34
35
36def display_help(subcommand, subcommands):
37 """
38 Display help for subcommand.
39 """
40 if subcommand not in subcommands:
41 return False
42
43 help = subcommands.get(subcommand, subcommand_error)[2]
44 pager = subprocess.Popen('less', stdin=subprocess.PIPE)
45 pager.communicate(help)
46
47 return True
48
49
50def yocto_help(args, usage_str, subcommands):
51 """
52 Subcommand help dispatcher.
53 """
54 if len(args) == 1 or not display_help(args[1], subcommands):
55 print(usage_str)
56
57
58def invoke_subcommand(args, parser, main_command_usage, subcommands):
59 """
60 Dispatch to subcommand handler borrowed from combo-layer.
61 Should use argparse, but has to work in 2.6.
62 """
63 if not args:
64 logging.error("No subcommand specified, exiting")
65 parser.print_help()
66 elif args[0] == "help":
67 yocto_help(args, main_command_usage, subcommands)
68 elif args[0] not in subcommands:
69 logging.error("Unsupported subcommand %s, exiting\n" % (args[0]))
70 parser.print_help()
71 else:
72 usage = subcommands.get(args[0], subcommand_error)[1]
73 subcommands.get(args[0], subcommand_error)[0](args[1:], usage)
74
75
76##
77# yocto-bsp help and usage strings
78##
79
80yocto_bsp_usage = """
81
82 Create a customized Yocto BSP layer.
83
84 usage: yocto-bsp [--version] [--help] COMMAND [ARGS]
85
86 Current 'yocto-bsp' commands are:
87 create Create a new Yocto BSP
88 list List available values for options and BSP properties
89
90 See 'yocto-bsp help COMMAND' for more information on a specific command.
91"""
92
93yocto_bsp_help_usage = """
94
95 usage: yocto-bsp help <subcommand>
96
97 This command displays detailed help for the specified subcommand.
98"""
99
100yocto_bsp_create_usage = """
101
102 Create a new Yocto BSP
103
104 usage: yocto-bsp create <bsp-name> <karch> [-o <DIRNAME> | --outdir <DIRNAME>]
105 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
106
107 This command creates a Yocto BSP based on the specified parameters.
108 The new BSP will be a new Yocto BSP layer contained by default within
109 the top-level directory specified as 'meta-bsp-name'. The -o option
110 can be used to place the BSP layer in a directory with a different
111 name and location.
112
113 The value of the 'karch' parameter determines the set of files that
114 will be generated for the BSP, along with the specific set of
115 'properties' that will be used to fill out the BSP-specific portions
116 of the BSP. The possible values for the 'karch' paramter can be
117 listed via 'yocto-bsp list karch'.
118
119 NOTE: Once created, you should add your new layer to your
120 bblayers.conf file in order for it to be subsequently seen and
121 modified by the yocto-kernel tool.
122
123 See 'yocto bsp help create' for more detailed instructions.
124"""
125
126yocto_bsp_create_help = """
127
128NAME
129 yocto-bsp create - Create a new Yocto BSP
130
131SYNOPSIS
132 yocto-bsp create <bsp-name> <karch> [-o <DIRNAME> | --outdir <DIRNAME>]
133 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
134
135DESCRIPTION
136 This command creates a Yocto BSP based on the specified
137 parameters. The new BSP will be a new Yocto BSP layer contained
138 by default within the top-level directory specified as
139 'meta-bsp-name'. The -o option can be used to place the BSP layer
140 in a directory with a different name and location.
141
142 The value of the 'karch' parameter determines the set of files
143 that will be generated for the BSP, along with the specific set of
144 'properties' that will be used to fill out the BSP-specific
145 portions of the BSP. The possible values for the 'karch' paramter
146 can be listed via 'yocto-bsp list karch'.
147
148 The BSP-specific properties that define the values that will be
149 used to generate a particular BSP can be specified on the
150 command-line using the -i option and supplying a JSON object
151 consisting of the set of name:value pairs needed by the BSP.
152
153 If the -i option is not used, the user will be interactively
154 prompted for each of the required property values, which will then
155 be used as values for BSP generation.
156
157 The set of properties available for a given architecture can be
158 listed using the 'yocto-bsp list' command.
159
160 Specifying -c causes the Python code generated and executed to
161 create the BSP to be dumped to the 'bspgen.out' file in the
162 current directory, and is useful for debugging.
163
164 NOTE: Once created, you should add your new layer to your
165 bblayers.conf file in order for it to be subsequently seen and
166 modified by the yocto-kernel tool.
167
168 For example, assuming your poky repo is at /path/to/poky, your new
169 BSP layer is at /path/to/poky/meta-mybsp, and your build directory
170 is /path/to/build:
171
172 $ gedit /path/to/build/conf/bblayers.conf
173
174 BBLAYERS ?= " \\
175 /path/to/poky/meta \\
176 /path/to/poky/meta-yocto \\
177 /path/to/poky/meta-mybsp \\
178 "
179"""
180
181yocto_bsp_list_usage = """
182
183 usage: yocto-bsp list karch
184 yocto-bsp list <karch> properties
185 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
186 yocto-bsp list <karch> property <xxx>
187 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
188
189 This command enumerates the complete set of possible values for a
190 specified option or property needed by the BSP creation process.
191
192 The first form enumerates all the possible values that exist and can
193 be specified for the 'karch' parameter to the 'yocto bsp create'
194 command.
195
196 The second form enumerates all the possible properties that exist and
197 must have values specified for them in the 'yocto bsp create' command
198 for the given 'karch'.
199
200 The third form enumerates all the possible values that exist and can
201 be specified for any of the enumerable properties of the given
202 'karch' in the 'yocto bsp create' command.
203
204 See 'yocto-bsp help list' for more details.
205"""
206
207yocto_bsp_list_help = """
208
209NAME
210 yocto-bsp list - List available values for options and BSP properties
211
212SYNOPSIS
213 yocto-bsp list karch
214 yocto-bsp list <karch> properties
215 [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
216 yocto-bsp list <karch> property <xxx>
217 [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
218
219DESCRIPTION
220 This command enumerates the complete set of possible values for a
221 specified option or property needed by the BSP creation process.
222
223 The first form enumerates all the possible values that exist and
224 can be specified for the 'karch' parameter to the 'yocto bsp
225 create' command. Example output for the 'list karch' command:
226
227 $ yocto-bsp list karch
228 Architectures available:
229 arm
230 powerpc
231 i386
232 mips
233 x86_64
234 qemu
235
236 The second form enumerates all the possible properties that exist
237 and must have values specified for them in the 'yocto bsp create'
238 command for the given 'karch'. This command is mainly meant to
239 allow the development user interface alternatives to the default
240 text-based prompting interface. If the -o option is specified,
241 the list of properties, in addition to being displayed, will be
242 written to the specified file as a JSON object. In this case, the
243 object will consist of the set of name:value pairs corresponding
244 to the (possibly nested) dictionary of properties defined by the
245 input statements used by the BSP. Some example output for the
246 'list properties' command:
247
248 $ yocto-bsp list arm properties
249 "touchscreen" : {
250 "msg" : Does your BSP have a touchscreen? (y/N)
251 "default" : n
252 "type" : boolean
253 }
254 "uboot_loadaddress" : {
255 "msg" : Please specify a value for UBOOT_LOADADDRESS.
256 "default" : 0x80008000
257 "type" : edit
258 "prio" : 40
259 }
260 "kernel_choice" : {
261 "prio" : 10
262 "default" : linux-yocto_3.2
263 "depends-on" : use_default_kernel
264 "depends-on-val" : n
265 "msg" : Please choose the kernel to use in this BSP =>
266 "type" : choicelist
267 "gen" : bsp.kernel.kernels
268 }
269 "if kernel_choice == "linux-yocto_3.0":" : {
270 "base_kbranch_linux_yocto_3_0" : {
271 "prio" : 20
272 "default" : yocto/standard
273 "depends-on" : new_kbranch_linux_yocto_3_0
274 "depends-on-val" : y
275 "msg" : Please choose a machine branch to base this BSP on =>
276 "type" : choicelist
277 "gen" : bsp.kernel.all_branches
278 }
279 .
280 .
281 .
282
283 Each entry in the output consists of the name of the input element
284 e.g. "touchscreen", followed by the properties defined for that
285 element enclosed in braces. This information should provide
286 sufficient information to create a complete user interface with.
287 Two features of the scheme provide for conditional input. First,
288 if a Python "if" statement appears in place of an input element
289 name, the set of enclosed input elements apply and should be
290 presented to the user only if the 'if' statement evaluates to
291 true. The test in the if statement will always reference another
292 input element in the list, which means that the element being
293 tested should be presented to the user before the elements
294 enclosed by the if block. Secondly, in a similar way, some
295 elements contain "depends-on" and depends-on-val" tags, which mean
296 that the affected input element should only be presented to the
297 user if the element it depends on has already been presented to
298 the user and the user has selected the specified value for that
299 element.
300
301 The third form enumerates all the possible values that exist and
302 can be specified for any of the enumerable properties of the given
303 'karch' in the 'yocto bsp create' command. If the -o option is
304 specified, the list of values for the given property, in addition
305 to being displayed, will be written to the specified file as a
306 JSON object. In this case, the object will consist of the set of
307 name:value pairs corresponding to the array of property values
308 associated with the property.
309
310 $ yocto-bsp list i386 property xserver_choice
311 ["xserver_vesa", "VESA xserver support"]
312 ["xserver_i915", "i915 xserver support"]
313
314 $ yocto-bsp list arm property base_kbranch_linux_yocto_3_0
315 Getting branches from remote repo git://git.yoctoproject.org/linux-yocto-3.0...
316 ["yocto/base", "yocto/base"]
317 ["yocto/eg20t", "yocto/eg20t"]
318 ["yocto/gma500", "yocto/gma500"]
319 ["yocto/pvr", "yocto/pvr"]
320 ["yocto/standard/arm-versatile-926ejs", "yocto/standard/arm-versatile-926ejs"]
321 ["yocto/standard/base", "yocto/standard/base"]
322 ["yocto/standard/cedartrail", "yocto/standard/cedartrail"]
323 .
324 .
325 .
326 ["yocto/standard/qemu-ppc32", "yocto/standard/qemu-ppc32"]
327 ["yocto/standard/routerstationpro", "yocto/standard/routerstationpro"]
328
329 The third form as well is meant mainly for developers of
330 alternative interfaces - it allows the developer to fetch the
331 possible values for a given input element on-demand. This
332 on-demand capability is especially valuable for elements that
333 require relatively expensive remote operations to fulfill, such as
334 the example that returns the set of branches available in a remote
335 git tree above.
336
337"""
338
339##
340# yocto-kernel help and usage strings
341##
342
343yocto_kernel_usage = """
344
345 Modify and list Yocto BSP kernel config items and patches.
346
347 usage: yocto-kernel [--version] [--help] COMMAND [ARGS]
348
349 Current 'yocto-kernel' commands are:
350 config list List the modifiable set of bare kernel config options for a BSP
351 config add Add or modify bare kernel config options for a BSP
352 config rm Remove bare kernel config options from a BSP
353 patch list List the patches associated with a BSP
354 patch add Patch the Yocto kernel for a BSP
355 patch rm Remove patches from a BSP
356 feature list List the features used by a BSP
357 feature add Have a BSP use a feature
358 feature rm Have a BSP stop using a feature
359 features list List the features available to BSPs
360 feature describe Describe a particular feature
361 feature create Create a new BSP-local feature
362 feature destroy Remove a BSP-local feature
363
364 See 'yocto-kernel help COMMAND' for more information on a specific command.
365
366"""
367
368
369yocto_kernel_help_usage = """
370
371 usage: yocto-kernel help <subcommand>
372
373 This command displays detailed help for the specified subcommand.
374"""
375
376yocto_kernel_config_list_usage = """
377
378 List the modifiable set of bare kernel config options for a BSP
379
380 usage: yocto-kernel config list <bsp-name>
381
382 This command lists the 'modifiable' config items for a BSP i.e. the
383 items which are eligible for modification or removal by other
384 yocto-kernel commands.
385
386 'modifiable' config items are the config items contained a BSP's
387 user-config.cfg base config.
388"""
389
390
391yocto_kernel_config_list_help = """
392
393NAME
394 yocto-kernel config list - List the modifiable set of bare kernel
395 config options for a BSP
396
397SYNOPSIS
398 yocto-kernel config list <bsp-name>
399
400DESCRIPTION
401 This command lists the 'modifiable' config items for a BSP
402 i.e. the items which are eligible for modification or removal by
403 other yocto-kernel commands.
404"""
405
406
407yocto_kernel_config_add_usage = """
408
409 Add or modify bare kernel config options for a BSP
410
411 usage: yocto-kernel config add <bsp-name> [<CONFIG_XXX=x> ...]
412
413 This command adds one or more CONFIG_XXX=x items to a BSP's user-config.cfg
414 base config.
415"""
416
417
418yocto_kernel_config_add_help = """
419
420NAME
421 yocto-kernel config add - Add or modify bare kernel config options
422 for a BSP
423
424SYNOPSIS
425 yocto-kernel config add <bsp-name> [<CONFIG_XXX=x> ...]
426
427DESCRIPTION
428 This command adds one or more CONFIG_XXX=x items to a BSP's
429 foo.cfg base config.
430
431 NOTE: It's up to the user to determine whether or not the config
432 options being added make sense or not - this command does no
433 sanity checking or verification of any kind to ensure that a
434 config option really makes sense and will actually be set in in
435 the final config. For example, if a config option depends on
436 other config options, it will be turned off by kconfig if the
437 other options aren't set correctly.
438"""
439
440
441yocto_kernel_config_rm_usage = """
442
443 Remove bare kernel config options from a BSP
444
445 usage: yocto-kernel config rm <bsp-name>
446
447 This command removes (turns off) one or more CONFIG_XXX items from a
448 BSP's user-config.cfg base config.
449
450 The set of config items available to be removed by this command for a
451 BSP is listed and the user prompted for the specific items to remove.
452"""
453
454
455yocto_kernel_config_rm_help = """
456
457NAME
458 yocto-kernel config rm - Remove bare kernel config options from a
459 BSP
460
461SYNOPSIS
462 yocto-kernel config rm <bsp-name>
463
464DESCRIPTION
465 This command removes (turns off) one or more CONFIG_XXX items from a
466 BSP's user-config.cfg base config.
467
468 The set of config items available to be removed by this command
469 for a BSP is listed and the user prompted for the specific items
470 to remove.
471"""
472
473
474yocto_kernel_patch_list_usage = """
475
476 List the patches associated with the kernel for a BSP
477
478 usage: yocto-kernel patch list <bsp-name>
479
480 This command lists the patches associated with a BSP.
481
482 NOTE: this only applies to patches listed in the kernel recipe's
483 user-patches.scc file (and currently repeated in its SRC_URI).
484"""
485
486
487yocto_kernel_patch_list_help = """
488
489NAME
490 yocto-kernel patch list - List the patches associated with the kernel
491 for a BSP
492
493SYNOPSIS
494 yocto-kernel patch list <bsp-name>
495
496DESCRIPTION
497 This command lists the patches associated with a BSP.
498
499 NOTE: this only applies to patches listed in the kernel recipe's
500 user-patches.scc file (and currently repeated in its SRC_URI).
501"""
502
503
504yocto_kernel_patch_add_usage = """
505
506 Patch the Yocto kernel for a specific BSP
507
508 usage: yocto-kernel patch add <bsp-name> [<PATCH> ...]
509
510 This command adds one or more patches to a BSP's machine branch. The
511 patch will be added to the BSP's linux-yocto kernel user-patches.scc
512 file (and currently repeated in its SRC_URI) and will be guaranteed
513 to be applied in the order specified.
514"""
515
516
517yocto_kernel_patch_add_help = """
518
519NAME
520 yocto-kernel patch add - Patch the Yocto kernel for a specific BSP
521
522SYNOPSIS
523 yocto-kernel patch add <bsp-name> [<PATCH> ...]
524
525DESCRIPTION
526 This command adds one or more patches to a BSP's machine branch.
527 The patch will be added to the BSP's linux-yocto kernel
528 user-patches.scc file (and currently repeated in its SRC_URI) and
529 will be guaranteed to be applied in the order specified.
530
531 NOTE: It's up to the user to determine whether or not the patches
532 being added makes sense or not - this command does no sanity
533 checking or verification of any kind to ensure that a patch can
534 actually be applied to the BSP's kernel branch; it's assumed that
535 the user has already done that.
536"""
537
538
539yocto_kernel_patch_rm_usage = """
540
541 Remove a patch from the Yocto kernel for a specific BSP
542
543 usage: yocto-kernel patch rm <bsp-name>
544
545 This command removes one or more patches from a BSP's machine branch.
546 The patch will be removed from the BSP's linux-yocto kernel
547 user-patches.scc file (and currently repeated in its SRC_URI) and
548 kernel SRC_URI dir.
549
550 The set of patches available to be removed by this command for a BSP
551 is listed and the user prompted for the specific patches to remove.
552"""
553
554
555yocto_kernel_patch_rm_help = """
556
557NAME
558 yocto-kernel patch rm - Remove a patch from the Yocto kernel for a specific BSP
559
560SYNOPSIS
561 yocto-kernel patch rm <bsp-name>
562
563DESCRIPTION
564 This command removes one or more patches from a BSP's machine
565 branch. The patch will be removed from the BSP's linux-yocto
566 kernel user-patches.scc file (and currently repeated in its
567 SRC_URI).
568
569 The set of patches available to be removed by this command for a
570 BSP is listed and the user prompted for the specific patches to
571 remove.
572"""
573
574yocto_kernel_feature_list_usage = """
575
576 List the BSP features that are being used by a BSP
577
578 usage: yocto-kernel feature list <bsp-name>
579
580 This command lists the features being used by a BSP i.e. the features
581 which are eligible for modification or removal by other yocto-kernel
582 commands.
583
584 'modifiable' features are the features listed in a BSP's
585 user-features.scc file.
586"""
587
588
589yocto_kernel_feature_list_help = """
590
591NAME
592 yocto-kernel feature list - List the modifiable set of features
593 being used by a BSP
594
595SYNOPSIS
596 yocto-kernel feature list <bsp-name>
597
598DESCRIPTION
599 This command lists the 'modifiable' features being used by a BSP
600 i.e. the features which are eligible for modification or removal
601 by other yocto-kernel commands.
602"""
603
604
605yocto_kernel_feature_add_usage = """
606
607 Add to or modify the list of features being used for a BSP
608
609 usage: yocto-kernel feature add <bsp-name> [/xxxx/yyyy/feature.scc ...]
610
611 This command adds one or more feature items to a BSP's kernel
612 user-features.scc file, which is the file used to manage features in
613 a yocto-bsp-generated BSP. Features to be added must be specified as
614 fully-qualified feature names.
615"""
616
617
618yocto_kernel_feature_add_help = """
619
620NAME
621 yocto-kernel feature add - Add to or modify the list of features
622 being used for a BSP
623
624SYNOPSIS
625 yocto-kernel feature add <bsp-name> [/xxxx/yyyy/feature.scc ...]
626
627DESCRIPTION
628 This command adds one or more feature items to a BSP's
629 user-features.scc file, which is the file used to manage features
630 in a yocto-bsp-generated BSP. Features to be added must be
631 specified as fully-qualified feature names.
632"""
633
634
635yocto_kernel_feature_rm_usage = """
636
637 Remove a feature from the list of features being used for a BSP
638
639 usage: yocto-kernel feature rm <bsp-name>
640
641 This command removes (turns off) one or more features from a BSP's
642 user-features.scc file, which is the file used to manage features in
643 a yocto-bsp-generated BSP.
644
645 The set of features available to be removed by this command for a BSP
646 is listed and the user prompted for the specific items to remove.
647"""
648
649
650yocto_kernel_feature_rm_help = """
651
652NAME
653 yocto-kernel feature rm - Remove a feature from the list of
654 features being used for a BSP
655
656SYNOPSIS
657 yocto-kernel feature rm <bsp-name>
658
659DESCRIPTION
660 This command removes (turns off) one or more features from a BSP's
661 user-features.scc file, which is the file used to manage features
662 in a yocto-bsp-generated BSP.
663
664 The set of features available to be removed by this command for a
665 BSP is listed and the user prompted for the specific items to
666 remove.
667"""
668
669
670yocto_kernel_available_features_list_usage = """
671
672 List the set of kernel features available to a BSP
673
674 usage: yocto-kernel features list <bsp-name>
675
676 This command lists the complete set of kernel features available to a
677 BSP. This includes the features contained in linux-yocto meta
678 branches as well as recipe-space features defined locally to the BSP.
679"""
680
681
682yocto_kernel_available_features_list_help = """
683
684NAME
685 yocto-kernel features list - List the set of kernel features
686 available to a BSP
687
688SYNOPSIS
689 yocto-kernel features list <bsp-name>
690
691DESCRIPTION
692 This command lists the complete set of kernel features available
693 to a BSP. This includes the features contained in linux-yocto
694 meta branches as well as recipe-space features defined locally to
695 the BSP.
696"""
697
698
699yocto_kernel_feature_describe_usage = """
700
701 Print the description and compatibility information for a given kernel feature
702
703 usage: yocto-kernel feature describe <bsp-name> [/xxxx/yyyy/feature.scc ...]
704
705 This command prints the description and compatibility of a specific
706 feature in the format 'description [compatibility].
707"""
708
709
710yocto_kernel_feature_describe_help = """
711
712NAME
713 yocto-kernel feature describe - print the description and
714 compatibility information for a given kernel feature
715
716SYNOPSIS
717 yocto-kernel feature describe <bsp-name> [/xxxx/yyyy/feature.scc ...]
718
719DESCRIPTION
720 This command prints the description and compatibility of a
721 specific feature in the format 'description [compatibility]. If
722 the feature doesn't define a description or compatibility, a
723 string with generic unknown values will be printed.
724"""
725
726
727yocto_kernel_feature_create_usage = """
728
729 Create a recipe-space kernel feature in a BSP
730
731 usage: yocto-kernel feature create <bsp-name> newfeature.scc \
732 "Feature Description" capabilities [<CONFIG_XXX=x> ...] [<PATCH> ...]
733
734 This command creates a new kernel feature from the bare config
735 options and patches specified on the command-line.
736"""
737
738
739yocto_kernel_feature_create_help = """
740
741NAME
742 yocto-kernel feature create - create a recipe-space kernel feature
743 in a BSP
744
745SYNOPSIS
746 yocto-kernel feature create <bsp-name> newfeature.scc \
747 "Feature Description" capabilities [<CONFIG_XXX=x> ...] [<PATCH> ...]
748
749DESCRIPTION
750 This command creates a new kernel feature from the bare config
751 options and patches specified on the command-line. The new
752 feature will be created in recipe-space, specifically in either
753 the kernel .bbappend's /files/cfg or /files/features subdirectory,
754 depending on whether or not the feature contains config items only
755 or config items along with patches. The named feature must end
756 with .scc and must not contain a feature directory to contain the
757 feature (this will be determined automatically), and a feature
758 decription in double-quotes along with a capabilities string
759 (which for the time being can be one of: 'all' or 'board').
760"""
761
762
763yocto_kernel_feature_destroy_usage = """
764
765 Destroy a recipe-space kernel feature in a BSP
766
767 usage: yocto-kernel feature destroy <bsp-name> feature.scc
768
769 This command destroys a kernel feature defined in the specified BSP's
770 recipe-space kernel definition.
771"""
772
773
774yocto_kernel_feature_destroy_help = """
775
776NAME
777 yocto-kernel feature destroy <bsp-name> feature.scc - destroy a
778 recipe-space kernel feature in a BSP
779
780SYNOPSIS
781 yocto-kernel feature destroy <bsp-name> feature.scc
782
783DESCRIPTION
784 This command destroys a kernel feature defined in the specified
785 BSP's recipe-space kernel definition. The named feature must end
786 with .scc and must not contain a feature directory to contain the
787 feature (this will be determined automatically). If the kernel
788 feature is in use by a BSP, it can't be removed until the BSP
789 stops using it (see yocto-kernel feature rm to stop using it).
790"""
791
792##
793# yocto-layer help and usage strings
794##
795
796yocto_layer_usage = """
797
798 Create a generic Yocto layer.
799
800 usage: yocto-layer [--version] [--help] COMMAND [ARGS]
801
802 Current 'yocto-layer' commands are:
803 create Create a new generic Yocto layer
804 list List available values for input options and properties
805
806 See 'yocto-layer help COMMAND' for more information on a specific command.
807"""
808
809yocto_layer_help_usage = """
810
811 usage: yocto-layer help <subcommand>
812
813 This command displays detailed help for the specified subcommand.
814"""
815
816yocto_layer_create_usage = """
817
818 Create a new generic Yocto layer
819
820 usage: yocto-layer create <layer-name> [layer_priority]
821 [-o <DIRNAME> | --outdir <DIRNAME>]
822 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
823
824 This command creates a generic Yocto layer based on the specified
825 parameters. The new layer will be a new Yocto layer contained by
826 default within the top-level directory specified as
827 'meta-layer-name'. The -o option can be used to place the layer in a
828 directory with a different name and location.
829
830 If layer_priority is specified, a simple layer will be created using
831 the given layer priority, and the user will not be prompted for
832 further input.
833
834 NOTE: Once created, you should add your new layer to your
835 bblayers.conf file in order for it to be subsequently seen and
836 modified by the yocto-kernel tool. Instructions for doing this can
837 be found in the README file generated in the layer's top-level
838 directory.
839
840 See 'yocto layer help create' for more detailed instructions.
841"""
842
843yocto_layer_create_help = """
844
845NAME
846 yocto-layer create - Create a new generic Yocto layer
847
848SYNOPSIS
849 yocto-layer create <layer-name> [layer_priority]
850 [-o <DIRNAME> | --outdir <DIRNAME>]
851 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
852
853DESCRIPTION
854 This command creates a generic Yocto layer based on the specified
855 parameters. The new layer will be a new Yocto layer contained by
856 default within the top-level directory specified as
857 'meta-layer-name'. The -o option can be used to place the layer
858 in a directory with a different name and location.
859
860 If layer_priority is specified, a simple layer will be created
861 using the given layer priority, and the user will not be prompted
862 for further input.
863
864 The layer-specific properties that define the values that will be
865 used to generate the layer can be specified on the command-line
866 using the -i option and supplying a JSON object consisting of the
867 set of name:value pairs needed by the layer.
868
869 If the -i option is not used, the user will be interactively
870 prompted for each of the required property values, which will then
871 be used as values for layer generation.
872
873 The set of properties available can be listed using the
874 'yocto-layer list' command.
875
876 Specifying -c causes the Python code generated and executed to
877 create the layer to be dumped to the 'bspgen.out' file in the
878 current directory, and is useful for debugging.
879
880 NOTE: Once created, you should add your new layer to your
881 bblayers.conf file in order for it to be subsequently seen and
882 modified by the yocto-kernel tool. Instructions for doing this
883 can be found in the README file generated in the layer's top-level
884 directory.
885
886 For example, assuming your poky repo is at /path/to/poky, your new
887 layer is at /path/to/poky/meta-mylayer, and your build directory
888 is /path/to/build:
889
890 $ gedit /path/to/build/conf/bblayers.conf
891
892 BBLAYERS ?= " \\
893 /path/to/poky/meta \\
894 /path/to/poky/meta-yocto \\
895 /path/to/poky/meta-mylayer \\
896 "
897"""
898
899yocto_layer_list_usage = """
900
901 usage: yocto-layer list properties
902 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
903 yocto-layer list property <xxx>
904 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
905
906 This command enumerates the complete set of possible values for a
907 specified option or property needed by the layer creation process.
908
909 The first form enumerates all the possible properties that exist and
910 must have values specified for them in the 'yocto-layer create'
911 command.
912
913 The second form enumerates all the possible values that exist and can
914 be specified for any of the enumerable properties in the 'yocto-layer
915 create' command.
916
917 See 'yocto-layer help list' for more details.
918"""
919
920yocto_layer_list_help = """
921
922NAME
923 yocto-layer list - List available values for layer input options and properties
924
925SYNOPSIS
926 yocto-layer list properties
927 [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
928 yocto-layer list property <xxx>
929 [--o <JSON PROPERTY FILE> | -outfile <JSON PROPERTY_FILE>]
930
931DESCRIPTION
932 This command enumerates the complete set of possible values for a
933 specified option or property needed by the layer creation process.
934
935 The first form enumerates all the possible properties that exist
936 and must have values specified for them in the 'yocto-layer
937 create' command. This command is mainly meant to aid the
938 development of user interface alternatives to the default
939 text-based prompting interface. If the -o option is specified,
940 the list of properties, in addition to being displayed, will be
941 written to the specified file as a JSON object. In this case, the
942 object will consist of the set of name:value pairs corresponding
943 to the (possibly nested) dictionary of properties defined by the
944 input statements used by the BSP. Some example output for the
945 'list properties' command:
946
947 $ yocto-layer list properties
948 "example_bbappend_name" : {
949 "default" : example
950 "msg" : Please enter the name you'd like to use for your bbappend file:
951 "type" : edit
952 "prio" : 20
953 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
954 }
955 "create_example_recipe" : {
956 "default" : n
957 "msg" : Would you like to have an example recipe created? (y/n)
958 "type" : boolean
959 "prio" : 20
960 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
961 }
962 "example_recipe_name" : {
963 "default" : example
964 "msg" : Please enter the name you'd like to use for your example recipe:
965 "type" : edit
966 "prio" : 20
967 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
968 }
969 "layer_priority" : {
970 "default" : 6
971 "msg" : Please enter the layer priority you'd like to use for the layer:
972 "type" : edit
973 "prio" : 20
974 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
975 }
976 "create_example_bbappend" : {
977 "default" : n
978 "msg" : Would you like to have an example bbappend file created? (y/n)
979 "type" : boolean
980 "prio" : 20
981 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
982 }
983 "example_bbappend_version" : {
984 "default" : 0.1
985 "msg" : Please enter the version number you'd like to use for your bbappend file (this should match the recipe you're appending to):
986 "type" : edit
987 "prio" : 20
988 "filename" : /home/trz/yocto/yocto-layer-dev/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
989 }
990
991 Each entry in the output consists of the name of the input element
992 e.g. "layer_priority", followed by the properties defined for that
993 element enclosed in braces. This information should provide
994 sufficient information to create a complete user interface. Two
995 features of the scheme provide for conditional input. First, if a
996 Python "if" statement appears in place of an input element name,
997 the set of enclosed input elements apply and should be presented
998 to the user only if the 'if' statement evaluates to true. The
999 test in the if statement will always reference another input
1000 element in the list, which means that the element being tested
1001 should be presented to the user before the elements enclosed by
1002 the if block. Secondly, in a similar way, some elements contain
1003 "depends-on" and depends-on-val" tags, which mean that the
1004 affected input element should only be presented to the user if the
1005 element it depends on has already been presented to the user and
1006 the user has selected the specified value for that element.
1007
1008 The second form enumerates all the possible values that exist and
1009 can be specified for any of the enumerable properties in the
1010 'yocto-layer create' command. If the -o option is specified, the
1011 list of values for the given property, in addition to being
1012 displayed, will be written to the specified file as a JSON object.
1013 In this case, the object will consist of the set of name:value
1014 pairs corresponding to the array of property values associated
1015 with the property.
1016
1017 $ yocto-layer list property layer_priority
1018 [no output - layer_priority is a text field that has no enumerable values]
1019
1020 The second form as well is meant mainly for developers of
1021 alternative interfaces - it allows the developer to fetch the
1022 possible values for a given input element on-demand. This
1023 on-demand capability is especially valuable for elements that
1024 require relatively expensive remote operations to fulfill, such as
1025 the example that returns the set of branches available in a remote
1026 git tree above.
1027
1028"""
1029
1030##
1031# test code
1032##
1033
1034test_bsp_properties = {
1035 'smp': 'yes',
1036 'touchscreen': 'yes',
1037 'keyboard': 'no',
1038 'xserver': 'yes',
1039 'xserver_choice': 'xserver-i915',
1040 'features': ['goodfeature', 'greatfeature'],
1041 'tunefile': 'tune-quark',
1042}
1043
diff --git a/scripts/lib/bsp/kernel.py b/scripts/lib/bsp/kernel.py
new file mode 100644
index 0000000000..ba68b60fcb
--- /dev/null
+++ b/scripts/lib/bsp/kernel.py
@@ -0,0 +1,1071 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2012, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module implements the kernel-related functions used by
22# 'yocto-kernel' to manage kernel config items and patches for Yocto
23# BSPs.
24#
25# AUTHORS
26# Tom Zanussi <tom.zanussi (at] intel.com>
27#
28
29import sys
30import os
31import shutil
32from tags import *
33import glob
34import subprocess
35from engine import create_context
36
37
38def find_bblayers():
39 """
40 Find and return a sanitized list of the layers found in BBLAYERS.
41 """
42 try:
43 builddir = os.environ["BUILDDIR"]
44 except KeyError:
45 print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
46 sys.exit(1)
47 bblayers_conf = os.path.join(builddir, "conf/bblayers.conf")
48
49 layers = []
50
51 bitbake_env_cmd = "bitbake -e"
52 bitbake_env_lines = subprocess.Popen(bitbake_env_cmd, shell=True,
53 stdout=subprocess.PIPE).stdout.read()
54
55 if not bitbake_env_lines:
56 print "Couldn't get '%s' output, exiting." % bitbake_env_cmd
57 sys.exit(1)
58
59 for line in bitbake_env_lines.split('\n'):
60 bblayers = get_line_val(line, "BBLAYERS")
61 if (bblayers):
62 break
63
64 if not bblayers:
65 print "Couldn't find BBLAYERS in %s output, exiting." % \
66 bitbake_env_cmd
67 sys.exit(1)
68
69 raw_layers = bblayers.split()
70
71 for layer in raw_layers:
72 if layer == 'BBLAYERS' or '=' in layer:
73 continue
74 layers.append(layer)
75
76 return layers
77
78
79def get_line_val(line, key):
80 """
81 Extract the value from the VAR="val" string
82 """
83 if line.startswith(key + "="):
84 stripped_line = line.split('=')[1]
85 stripped_line = stripped_line.replace('\"', '')
86 return stripped_line
87 return None
88
89
90def find_meta_layer():
91 """
92 Find and return the meta layer in BBLAYERS.
93 """
94 layers = find_bblayers()
95
96 for layer in layers:
97 if layer.endswith("meta"):
98 return layer
99
100 return None
101
102
103def find_bsp_layer(machine):
104 """
105 Find and return a machine's BSP layer in BBLAYERS.
106 """
107 layers = find_bblayers()
108
109 for layer in layers:
110 if layer.endswith(machine):
111 return layer
112
113 print "Unable to find the BSP layer for machine %s." % machine
114 print "Please make sure it is listed in bblayers.conf"
115 sys.exit(1)
116
117
118def gen_choices_str(choices):
119 """
120 Generate a numbered list of choices from a list of choices for
121 display to the user.
122 """
123 choices_str = ""
124
125 for i, choice in enumerate(choices):
126 choices_str += "\t" + str(i + 1) + ") " + choice + "\n"
127
128 return choices_str
129
130
131def open_user_file(scripts_path, machine, userfile, mode):
132 """
133 Find one of the user files (user-config.cfg, user-patches.scc)
134 associated with the machine (could be in files/,
135 linux-yocto-custom/, etc). Returns the open file if found, None
136 otherwise.
137
138 The caller is responsible for closing the file returned.
139 """
140 layer = find_bsp_layer(machine)
141 linuxdir = os.path.join(layer, "recipes-kernel/linux")
142 linuxdir_list = os.listdir(linuxdir)
143 for fileobj in linuxdir_list:
144 fileobj_path = os.path.join(linuxdir, fileobj)
145 if os.path.isdir(fileobj_path):
146 userfile_name = os.path.join(fileobj_path, userfile)
147 try:
148 f = open(userfile_name, mode)
149 return f
150 except IOError:
151 continue
152 return None
153
154
155def read_config_items(scripts_path, machine):
156 """
157 Find and return a list of config items (CONFIG_XXX) in a machine's
158 user-defined config fragment [${machine}-user-config.cfg].
159 """
160 config_items = []
161
162 f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "r")
163 lines = f.readlines()
164 for line in lines:
165 s = line.strip()
166 if s and not s.startswith("#"):
167 config_items.append(s)
168 f.close()
169
170 return config_items
171
172
173def write_config_items(scripts_path, machine, config_items):
174 """
175 Write (replace) the list of config items (CONFIG_XXX) in a
176 machine's user-defined config fragment [${machine}=user-config.cfg].
177 """
178 f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "w")
179 for item in config_items:
180 f.write(item + "\n")
181 f.close()
182
183 kernel_contents_changed(scripts_path, machine)
184
185
186def yocto_kernel_config_list(scripts_path, machine):
187 """
188 Display the list of config items (CONFIG_XXX) in a machine's
189 user-defined config fragment [${machine}-user-config.cfg].
190 """
191 config_items = read_config_items(scripts_path, machine)
192
193 print "The current set of machine-specific kernel config items for %s is:" % machine
194 print gen_choices_str(config_items)
195
196
197def yocto_kernel_config_rm(scripts_path, machine):
198 """
199 Display the list of config items (CONFIG_XXX) in a machine's
200 user-defined config fragment [${machine}-user-config.cfg], prompt the user
201 for one or more to remove, and remove them.
202 """
203 config_items = read_config_items(scripts_path, machine)
204
205 print "Specify the kernel config items to remove:"
206 input = raw_input(gen_choices_str(config_items))
207 rm_choices = input.split()
208 rm_choices.sort()
209
210 removed = []
211
212 for choice in reversed(rm_choices):
213 try:
214 idx = int(choice) - 1
215 except ValueError:
216 print "Invalid choice (%s), exiting" % choice
217 sys.exit(1)
218 if idx < 0 or idx >= len(config_items):
219 print "Invalid choice (%d), exiting" % (idx + 1)
220 sys.exit(1)
221 removed.append(config_items.pop(idx))
222
223 write_config_items(scripts_path, machine, config_items)
224
225 print "Removed items:"
226 for r in removed:
227 print "\t%s" % r
228
229
230def yocto_kernel_config_add(scripts_path, machine, config_items):
231 """
232 Add one or more config items (CONFIG_XXX) to a machine's
233 user-defined config fragment [${machine}-user-config.cfg].
234 """
235 new_items = []
236 dup_items = []
237
238 cur_items = read_config_items(scripts_path, machine)
239
240 for item in config_items:
241 if not item.startswith("CONFIG") or (not "=y" in item and not "=m" in item):
242 print "Invalid config item (%s), exiting" % item
243 sys.exit(1)
244 if item not in cur_items and item not in new_items:
245 new_items.append(item)
246 else:
247 dup_items.append(item)
248
249 if len(new_items) > 0:
250 cur_items.extend(new_items)
251 write_config_items(scripts_path, machine, cur_items)
252 print "Added item%s:" % ("" if len(new_items)==1 else "s")
253 for n in new_items:
254 print "\t%s" % n
255
256 if len(dup_items) > 0:
257 output="The following item%s already exist%s in the current configuration, ignoring %s:" % \
258 (("","s", "it") if len(dup_items)==1 else ("s", "", "them" ))
259 print output
260 for n in dup_items:
261 print "\t%s" % n
262
263def find_current_kernel(bsp_layer, machine):
264 """
265 Determine the kernel and version currently being used in the BSP.
266 """
267 machine_conf = os.path.join(bsp_layer, "conf/machine/" + machine + ".conf")
268
269 preferred_kernel = preferred_kernel_version = preferred_version_varname = None
270
271 f = open(machine_conf, "r")
272 lines = f.readlines()
273 for line in lines:
274 if line.strip().startswith("PREFERRED_PROVIDER_virtual/kernel"):
275 preferred_kernel = line.split()[-1]
276 preferred_kernel = preferred_kernel.replace('\"','')
277 preferred_version_varname = "PREFERRED_VERSION_" + preferred_kernel
278 if preferred_version_varname and line.strip().startswith(preferred_version_varname):
279 preferred_kernel_version = line.split()[-1]
280 preferred_kernel_version = preferred_kernel_version.replace('\"','')
281 preferred_kernel_version = preferred_kernel_version.replace('%','')
282
283 if preferred_kernel and preferred_kernel_version:
284 return preferred_kernel + "_" + preferred_kernel_version
285 elif preferred_kernel:
286 return preferred_kernel
287
288
289def find_filesdir(scripts_path, machine):
290 """
291 Find the name of the 'files' dir associated with the machine
292 (could be in files/, linux-yocto-custom/, etc). Returns the name
293 of the files dir if found, None otherwise.
294 """
295 layer = find_bsp_layer(machine)
296 filesdir = None
297 linuxdir = os.path.join(layer, "recipes-kernel/linux")
298 linuxdir_list = os.listdir(linuxdir)
299 for fileobj in linuxdir_list:
300 fileobj_path = os.path.join(linuxdir, fileobj)
301 if os.path.isdir(fileobj_path):
302 # this could be files/ or linux-yocto-custom/, we have no way of distinguishing
303 # so we take the first (and normally only) dir we find as the 'filesdir'
304 filesdir = fileobj_path
305
306 return filesdir
307
308
309def read_patch_items(scripts_path, machine):
310 """
311 Find and return a list of patch items in a machine's user-defined
312 patch list [${machine}-user-patches.scc].
313 """
314 patch_items = []
315
316 f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "r")
317 lines = f.readlines()
318 for line in lines:
319 s = line.strip()
320 if s and not s.startswith("#"):
321 fields = s.split()
322 if not fields[0] == "patch":
323 continue
324 patch_items.append(fields[1])
325 f.close()
326
327 return patch_items
328
329
330def write_patch_items(scripts_path, machine, patch_items):
331 """
332 Write (replace) the list of patches in a machine's user-defined
333 patch list [${machine}-user-patches.scc].
334 """
335 f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "w")
336 for item in patch_items:
337 f.write("patch " + item + "\n")
338 f.close()
339
340 kernel_contents_changed(scripts_path, machine)
341
342
343def yocto_kernel_patch_list(scripts_path, machine):
344 """
345 Display the list of patches in a machine's user-defined patch list
346 [${machine}-user-patches.scc].
347 """
348 patches = read_patch_items(scripts_path, machine)
349
350 print "The current set of machine-specific patches for %s is:" % machine
351 print gen_choices_str(patches)
352
353
354def yocto_kernel_patch_rm(scripts_path, machine):
355 """
356 Remove one or more patches from a machine's user-defined patch
357 list [${machine}-user-patches.scc].
358 """
359 patches = read_patch_items(scripts_path, machine)
360
361 print "Specify the patches to remove:"
362 input = raw_input(gen_choices_str(patches))
363 rm_choices = input.split()
364 rm_choices.sort()
365
366 removed = []
367
368 filesdir = find_filesdir(scripts_path, machine)
369 if not filesdir:
370 print "Couldn't rm patch(es) since we couldn't find a 'files' dir"
371 sys.exit(1)
372
373 for choice in reversed(rm_choices):
374 try:
375 idx = int(choice) - 1
376 except ValueError:
377 print "Invalid choice (%s), exiting" % choice
378 sys.exit(1)
379 if idx < 0 or idx >= len(patches):
380 print "Invalid choice (%d), exiting" % (idx + 1)
381 sys.exit(1)
382 filesdir_patch = os.path.join(filesdir, patches[idx])
383 if os.path.isfile(filesdir_patch):
384 os.remove(filesdir_patch)
385 removed.append(patches[idx])
386 patches.pop(idx)
387
388 write_patch_items(scripts_path, machine, patches)
389
390 print "Removed patches:"
391 for r in removed:
392 print "\t%s" % r
393
394
395def yocto_kernel_patch_add(scripts_path, machine, patches):
396 """
397 Add one or more patches to a machine's user-defined patch list
398 [${machine}-user-patches.scc].
399 """
400 existing_patches = read_patch_items(scripts_path, machine)
401
402 for patch in patches:
403 if os.path.basename(patch) in existing_patches:
404 print "Couldn't add patch (%s) since it's already been added" % os.path.basename(patch)
405 sys.exit(1)
406
407 filesdir = find_filesdir(scripts_path, machine)
408 if not filesdir:
409 print "Couldn't add patch (%s) since we couldn't find a 'files' dir to add it to" % os.path.basename(patch)
410 sys.exit(1)
411
412 new_patches = []
413
414 for patch in patches:
415 if not os.path.isfile(patch):
416 print "Couldn't find patch (%s), exiting" % patch
417 sys.exit(1)
418 basename = os.path.basename(patch)
419 filesdir_patch = os.path.join(filesdir, basename)
420 shutil.copyfile(patch, filesdir_patch)
421 new_patches.append(basename)
422
423 cur_items = read_patch_items(scripts_path, machine)
424 cur_items.extend(new_patches)
425 write_patch_items(scripts_path, machine, cur_items)
426
427 print "Added patches:"
428 for n in new_patches:
429 print "\t%s" % n
430
431
432def inc_pr(line):
433 """
434 Add 1 to the PR value in the given bbappend PR line. For the PR
435 lines in kernel .bbappends after modifications. Handles PRs of
436 the form PR := "${PR}.1" as well as PR = "r0".
437 """
438 idx = line.find("\"")
439
440 pr_str = line[idx:]
441 pr_str = pr_str.replace('\"','')
442 fields = pr_str.split('.')
443 if len(fields) > 1:
444 fields[1] = str(int(fields[1]) + 1)
445 pr_str = "\"" + '.'.join(fields) + "\"\n"
446 else:
447 pr_val = pr_str[1:]
448 pr_str = "\"" + "r" + str(int(pr_val) + 1) + "\"\n"
449 idx2 = line.find("\"", idx + 1)
450 line = line[:idx] + pr_str
451
452 return line
453
454
455def kernel_contents_changed(scripts_path, machine):
456 """
457 Do what we need to do to notify the system that the kernel
458 recipe's contents have changed.
459 """
460 layer = find_bsp_layer(machine)
461
462 kernel = find_current_kernel(layer, machine)
463 if not kernel:
464 print "Couldn't determine the kernel for this BSP, exiting."
465 sys.exit(1)
466
467 kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend")
468 if not os.path.isfile(kernel_bbfile):
469 kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bb")
470 if not os.path.isfile(kernel_bbfile):
471 return
472 kernel_bbfile_prev = kernel_bbfile + ".prev"
473 shutil.copyfile(kernel_bbfile, kernel_bbfile_prev)
474
475 ifile = open(kernel_bbfile_prev, "r")
476 ofile = open(kernel_bbfile, "w")
477 ifile_lines = ifile.readlines()
478 for ifile_line in ifile_lines:
479 if ifile_line.strip().startswith("PR"):
480 ifile_line = inc_pr(ifile_line)
481 ofile.write(ifile_line)
482 ofile.close()
483 ifile.close()
484
485
486def kernels(context):
487 """
488 Return the list of available kernels in the BSP i.e. corresponding
489 to the kernel .bbappends found in the layer.
490 """
491 archdir = os.path.join(context["scripts_path"], "lib/bsp/substrate/target/arch/" + context["arch"])
492 kerndir = os.path.join(archdir, "recipes-kernel/linux")
493 bbglob = os.path.join(kerndir, "*.bbappend")
494
495 bbappends = glob.glob(bbglob)
496
497 kernels = []
498
499 for kernel in bbappends:
500 filename = os.path.splitext(os.path.basename(kernel))[0]
501 idx = filename.find(CLOSE_TAG)
502 if idx != -1:
503 filename = filename[idx + len(CLOSE_TAG):].strip()
504 kernels.append(filename)
505
506 kernels.append("custom")
507
508 return kernels
509
510
511def extract_giturl(file):
512 """
513 Extract the git url of the kernel repo from the kernel recipe's
514 SRC_URI.
515 """
516 url = None
517 f = open(file, "r")
518 lines = f.readlines()
519 for line in lines:
520 line = line.strip()
521 if line.startswith("SRC_URI"):
522 line = line[len("SRC_URI"):].strip()
523 if line.startswith("="):
524 line = line[1:].strip()
525 if line.startswith("\""):
526 line = line[1:].strip()
527 prot = "git"
528 for s in line.split(";"):
529 if s.startswith("git://"):
530 url = s
531 if s.startswith("protocol="):
532 prot = s.split("=")[1]
533 if url:
534 url = prot + url[3:]
535 return url
536
537
538def find_giturl(context):
539 """
540 Find the git url of the kernel repo from the kernel recipe's
541 SRC_URI.
542 """
543 name = context["name"]
544 filebase = context["filename"]
545 scripts_path = context["scripts_path"]
546
547 meta_layer = find_meta_layer()
548
549 kerndir = os.path.join(meta_layer, "recipes-kernel/linux")
550 bbglob = os.path.join(kerndir, "*.bb")
551 bbs = glob.glob(bbglob)
552 for kernel in bbs:
553 filename = os.path.splitext(os.path.basename(kernel))[0]
554 if filename in filebase:
555 giturl = extract_giturl(kernel)
556 return giturl
557
558 return None
559
560
561def read_features(scripts_path, machine):
562 """
563 Find and return a list of features in a machine's user-defined
564 features fragment [${machine}-user-features.scc].
565 """
566 features = []
567
568 f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "r")
569 lines = f.readlines()
570 for line in lines:
571 s = line.strip()
572 if s and not s.startswith("#"):
573 feature_include = s.split()
574 features.append(feature_include[1].strip())
575 f.close()
576
577 return features
578
579
580def write_features(scripts_path, machine, features):
581 """
582 Write (replace) the list of feature items in a
583 machine's user-defined features fragment [${machine}=user-features.cfg].
584 """
585 f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "w")
586 for item in features:
587 f.write("include " + item + "\n")
588 f.close()
589
590 kernel_contents_changed(scripts_path, machine)
591
592
593def yocto_kernel_feature_list(scripts_path, machine):
594 """
595 Display the list of features used in a machine's user-defined
596 features fragment [${machine}-user-features.scc].
597 """
598 features = read_features(scripts_path, machine)
599
600 print "The current set of machine-specific features for %s is:" % machine
601 print gen_choices_str(features)
602
603
604def yocto_kernel_feature_rm(scripts_path, machine):
605 """
606 Display the list of features used in a machine's user-defined
607 features fragment [${machine}-user-features.scc], prompt the user
608 for one or more to remove, and remove them.
609 """
610 features = read_features(scripts_path, machine)
611
612 print "Specify the features to remove:"
613 input = raw_input(gen_choices_str(features))
614 rm_choices = input.split()
615 rm_choices.sort()
616
617 removed = []
618
619 for choice in reversed(rm_choices):
620 try:
621 idx = int(choice) - 1
622 except ValueError:
623 print "Invalid choice (%s), exiting" % choice
624 sys.exit(1)
625 if idx < 0 or idx >= len(features):
626 print "Invalid choice (%d), exiting" % (idx + 1)
627 sys.exit(1)
628 removed.append(features.pop(idx))
629
630 write_features(scripts_path, machine, features)
631
632 print "Removed features:"
633 for r in removed:
634 print "\t%s" % r
635
636
637def yocto_kernel_feature_add(scripts_path, machine, features):
638 """
639 Add one or more features a machine's user-defined features
640 fragment [${machine}-user-features.scc].
641 """
642 new_items = []
643
644 for item in features:
645 if not item.endswith(".scc"):
646 print "Invalid feature (%s), exiting" % item
647 sys.exit(1)
648 new_items.append(item)
649
650 cur_items = read_features(scripts_path, machine)
651 cur_items.extend(new_items)
652
653 write_features(scripts_path, machine, cur_items)
654
655 print "Added features:"
656 for n in new_items:
657 print "\t%s" % n
658
659
660def find_feature_url(git_url):
661 """
662 Find the url of the kern-features.rc kernel for the kernel repo
663 specified from the BSP's kernel recipe SRC_URI.
664 """
665 feature_url = ""
666 if git_url.startswith("git://"):
667 git_url = git_url[len("git://"):].strip()
668 s = git_url.split("/")
669 if s[1].endswith(".git"):
670 s[1] = s[1][:len(s[1]) - len(".git")]
671 feature_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
672 "/plain/meta/cfg/kern-features.rc?h=meta"
673
674 return feature_url
675
676
677def find_feature_desc(lines):
678 """
679 Find the feature description and compatibility in the passed-in
680 set of lines. Returns a string string of the form 'desc
681 [compat]'.
682 """
683 desc = "no description available"
684 compat = "unknown"
685
686 for line in lines:
687 idx = line.find("KFEATURE_DESCRIPTION")
688 if idx != -1:
689 desc = line[idx + len("KFEATURE_DESCRIPTION"):].strip()
690 if desc.startswith("\""):
691 desc = desc[1:]
692 if desc.endswith("\""):
693 desc = desc[:-1]
694 else:
695 idx = line.find("KFEATURE_COMPATIBILITY")
696 if idx != -1:
697 compat = line[idx + len("KFEATURE_COMPATIBILITY"):].strip()
698
699 return desc + " [" + compat + "]"
700
701
702def print_feature_descs(layer, feature_dir):
703 """
704 Print the feature descriptions for the features in feature_dir.
705 """
706 kernel_files_features = os.path.join(layer, "recipes-kernel/linux/files/" +
707 feature_dir)
708 for root, dirs, files in os.walk(kernel_files_features):
709 for file in files:
710 if file.endswith("~") or file.endswith("#"):
711 continue
712 if file.endswith(".scc"):
713 fullpath = os.path.join(layer, "recipes-kernel/linux/files/" +
714 feature_dir + "/" + file)
715 f = open(fullpath)
716 feature_desc = find_feature_desc(f.readlines())
717 print feature_dir + "/" + file + ": " + feature_desc
718
719
720def yocto_kernel_available_features_list(scripts_path, machine):
721 """
722 Display the list of all the kernel features available for use in
723 BSPs, as gathered from the set of feature sources.
724 """
725 layer = find_bsp_layer(machine)
726 kernel = find_current_kernel(layer, machine)
727 if not kernel:
728 print "Couldn't determine the kernel for this BSP, exiting."
729 sys.exit(1)
730
731 context = create_context(machine, "arch", scripts_path)
732 context["name"] = "name"
733 context["filename"] = kernel
734 giturl = find_giturl(context)
735 feature_url = find_feature_url(giturl)
736
737 feature_cmd = "wget -q -O - " + feature_url
738 tmp = subprocess.Popen(feature_cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
739
740 print "The current set of kernel features available to %s is:\n" % machine
741
742 if tmp:
743 tmpline = tmp.split("\n")
744 in_kernel_options = False
745 for line in tmpline:
746 if not "=" in line:
747 if in_kernel_options:
748 break
749 if "kernel-options" in line:
750 in_kernel_options = True
751 continue
752 if in_kernel_options:
753 feature_def = line.split("=")
754 feature_type = feature_def[0].strip()
755 feature = feature_def[1].strip()
756 desc = get_feature_desc(giturl, feature)
757 print "%s: %s" % (feature, desc)
758
759 print "[local]"
760
761 print_feature_descs(layer, "cfg")
762 print_feature_descs(layer, "features")
763
764
765def find_feature_desc_url(git_url, feature):
766 """
767 Find the url of the kernel feature in the kernel repo specified
768 from the BSP's kernel recipe SRC_URI.
769 """
770 feature_desc_url = ""
771 if git_url.startswith("git://"):
772 git_url = git_url[len("git://"):].strip()
773 s = git_url.split("/")
774 if s[1].endswith(".git"):
775 s[1] = s[1][:len(s[1]) - len(".git")]
776 feature_desc_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
777 "/plain/meta/cfg/kernel-cache/" + feature + "?h=meta"
778
779 return feature_desc_url
780
781
782def get_feature_desc(git_url, feature):
783 """
784 Return a feature description of the form 'description [compatibility]
785 BSPs, as gathered from the set of feature sources.
786 """
787 feature_desc_url = find_feature_desc_url(git_url, feature)
788 feature_desc_cmd = "wget -q -O - " + feature_desc_url
789 tmp = subprocess.Popen(feature_desc_cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
790
791 return find_feature_desc(tmp.split("\n"))
792
793
794def yocto_kernel_feature_describe(scripts_path, machine, feature):
795 """
796 Display the description of a specific kernel feature available for
797 use in a BSP.
798 """
799 layer = find_bsp_layer(machine)
800
801 kernel = find_current_kernel(layer, machine)
802 if not kernel:
803 print "Couldn't determine the kernel for this BSP, exiting."
804 sys.exit(1)
805
806 context = create_context(machine, "arch", scripts_path)
807 context["name"] = "name"
808 context["filename"] = kernel
809 giturl = find_giturl(context)
810
811 desc = get_feature_desc(giturl, feature)
812
813 print desc
814
815
816def check_feature_name(feature_name):
817 """
818 Sanity-check the feature name for create/destroy. Return False if not OK.
819 """
820 if not feature_name.endswith(".scc"):
821 print "Invalid feature name (must end with .scc) [%s], exiting" % feature_name
822 return False
823
824 if "/" in feature_name:
825 print "Invalid feature name (don't specify directory) [%s], exiting" % feature_name
826 return False
827
828 return True
829
830
831def check_create_input(feature_items):
832 """
833 Sanity-check the create input. Return False if not OK.
834 """
835 if not check_feature_name(feature_items[0]):
836 return False
837
838 if feature_items[1].endswith(".patch") or feature_items[1].startswith("CONFIG_"):
839 print "Missing description and/or compatibilty [%s], exiting" % feature_items[1]
840 return False
841
842 if feature_items[2].endswith(".patch") or feature_items[2].startswith("CONFIG_"):
843 print "Missing description and/or compatibility [%s], exiting" % feature_items[1]
844 return False
845
846 return True
847
848
849def yocto_kernel_feature_create(scripts_path, machine, feature_items):
850 """
851 Create a recipe-space kernel feature in a BSP.
852 """
853 if not check_create_input(feature_items):
854 sys.exit(1)
855
856 feature = feature_items[0]
857 feature_basename = feature.split(".")[0]
858 feature_description = feature_items[1]
859 feature_compat = feature_items[2]
860
861 patches = []
862 cfg_items = []
863
864 for item in feature_items[3:]:
865 if item.endswith(".patch"):
866 patches.append(item)
867 elif item.startswith("CONFIG"):
868 if ("=y" in item or "=m" in item):
869 cfg_items.append(item)
870 else:
871 print "Invalid feature item (must be .patch or CONFIG_*) [%s], exiting" % item
872 sys.exit(1)
873
874 feature_dirname = "cfg"
875 if patches:
876 feature_dirname = "features"
877
878 filesdir = find_filesdir(scripts_path, machine)
879 if not filesdir:
880 print "Couldn't add feature (%s), no 'files' dir found" % feature
881 sys.exit(1)
882
883 featdir = os.path.join(filesdir, feature_dirname)
884 if not os.path.exists(featdir):
885 os.mkdir(featdir)
886
887 for patch in patches:
888 if not os.path.isfile(patch):
889 print "Couldn't find patch (%s), exiting" % patch
890 sys.exit(1)
891 basename = os.path.basename(patch)
892 featdir_patch = os.path.join(featdir, basename)
893 shutil.copyfile(patch, featdir_patch)
894
895 new_cfg_filename = os.path.join(featdir, feature_basename + ".cfg")
896 new_cfg_file = open(new_cfg_filename, "w")
897 for cfg_item in cfg_items:
898 new_cfg_file.write(cfg_item + "\n")
899 new_cfg_file.close()
900
901 new_feature_filename = os.path.join(featdir, feature_basename + ".scc")
902 new_feature_file = open(new_feature_filename, "w")
903 new_feature_file.write("define KFEATURE_DESCRIPTION \"" + feature_description + "\"\n")
904 new_feature_file.write("define KFEATURE_COMPATIBILITY " + feature_compat + "\n\n")
905
906 for patch in patches:
907 patch_dir, patch_file = os.path.split(patch)
908 new_feature_file.write("patch " + patch_file + "\n")
909
910 new_feature_file.write("kconf non-hardware " + feature_basename + ".cfg\n")
911 new_feature_file.close()
912
913 print "Added feature:"
914 print "\t%s" % feature_dirname + "/" + feature
915
916
917def feature_in_use(scripts_path, machine, feature):
918 """
919 Determine whether the specified feature is in use by the BSP.
920 Return True if so, False otherwise.
921 """
922 features = read_features(scripts_path, machine)
923 for f in features:
924 if f == feature:
925 return True
926 return False
927
928
929def feature_remove(scripts_path, machine, feature):
930 """
931 Remove the specified feature from the available recipe-space
932 features defined for the BSP.
933 """
934 features = read_features(scripts_path, machine)
935 new_features = []
936 for f in features:
937 if f == feature:
938 continue
939 new_features.append(f)
940 write_features(scripts_path, machine, new_features)
941
942
943def yocto_kernel_feature_destroy(scripts_path, machine, feature):
944 """
945 Remove a recipe-space kernel feature from a BSP.
946 """
947 if not check_feature_name(feature):
948 sys.exit(1)
949
950 if feature_in_use(scripts_path, machine, "features/" + feature) or \
951 feature_in_use(scripts_path, machine, "cfg/" + feature):
952 print "Feature %s is in use (use 'feature rm' to un-use it first), exiting" % feature
953 sys.exit(1)
954
955 filesdir = find_filesdir(scripts_path, machine)
956 if not filesdir:
957 print "Couldn't destroy feature (%s), no 'files' dir found" % feature
958 sys.exit(1)
959
960 feature_dirname = "features"
961 featdir = os.path.join(filesdir, feature_dirname)
962 if not os.path.exists(featdir):
963 print "Couldn't find feature directory (%s)" % feature_dirname
964 sys.exit(1)
965
966 feature_fqn = os.path.join(featdir, feature)
967 if not os.path.exists(feature_fqn):
968 feature_dirname = "cfg"
969 featdir = os.path.join(filesdir, feature_dirname)
970 if not os.path.exists(featdir):
971 print "Couldn't find feature directory (%s)" % feature_dirname
972 sys.exit(1)
973 feature_fqn = os.path.join(featdir, feature_filename)
974 if not os.path.exists(feature_fqn):
975 print "Couldn't find feature (%s)" % feature
976 sys.exit(1)
977
978 f = open(feature_fqn, "r")
979 lines = f.readlines()
980 for line in lines:
981 s = line.strip()
982 if s.startswith("patch ") or s.startswith("kconf "):
983 split_line = s.split()
984 filename = os.path.join(featdir, split_line[-1])
985 if os.path.exists(filename):
986 os.remove(filename)
987 f.close()
988 os.remove(feature_fqn)
989
990 feature_remove(scripts_path, machine, feature)
991
992 print "Removed feature:"
993 print "\t%s" % feature_dirname + "/" + feature
994
995
996def base_branches(context):
997 """
998 Return a list of the base branches found in the kernel git repo.
999 """
1000 giturl = find_giturl(context)
1001
1002 print "Getting branches from remote repo %s..." % giturl
1003
1004 gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
1005 tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read()
1006
1007 branches = []
1008
1009 if tmp:
1010 tmpline = tmp.split("\n")
1011 for line in tmpline:
1012 if len(line)==0:
1013 break;
1014 if not line.endswith("base"):
1015 continue;
1016 idx = line.find("refs/heads/")
1017 kbranch = line[idx + len("refs/heads/"):]
1018 if kbranch.find("/") == -1 and kbranch.find("base") == -1:
1019 continue
1020 idx = kbranch.find("base")
1021 branches.append(kbranch[:idx - 1])
1022
1023 return branches
1024
1025
1026def all_branches(context):
1027 """
1028 Return a list of all the branches found in the kernel git repo.
1029 """
1030 giturl = find_giturl(context)
1031
1032 print "Getting branches from remote repo %s..." % giturl
1033
1034 gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
1035 tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read()
1036
1037 branches = []
1038
1039 base_prefixes = None
1040
1041 try:
1042 branches_base = context["branches_base"]
1043 if branches_base:
1044 base_prefixes = branches_base.split(":")
1045 except KeyError:
1046 pass
1047
1048 arch = context["arch"]
1049
1050 if tmp:
1051 tmpline = tmp.split("\n")
1052 for line in tmpline:
1053 if len(line)==0:
1054 break;
1055 idx = line.find("refs/heads/")
1056 kbranch = line[idx + len("refs/heads/"):]
1057 kbranch_prefix = kbranch.rsplit("/", 1)[0]
1058
1059 if base_prefixes:
1060 for base_prefix in base_prefixes:
1061 if kbranch_prefix == base_prefix:
1062 branches.append(kbranch)
1063 continue
1064
1065 if (kbranch.find("/") != -1 and
1066 (kbranch.find("standard") != -1 or kbranch.find("base") != -1) or
1067 kbranch == "base"):
1068 branches.append(kbranch)
1069 continue
1070
1071 return branches
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..44a80d226c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/conf/machine/{{=machine}}.conf
@@ -0,0 +1,105 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
7{{ if xserver == "y": }}
8PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
9XSERVER ?= "xserver-xorg \
10 xf86-input-evdev \
11 xf86-input-mouse \
12 xf86-video-omapfb \
13 xf86-input-keyboard"
14
15# Ship all kernel modules by default
16MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
17
18# Allow for MMC booting (required by the NAND-less Beagleboard XM)
19EXTRA_IMAGEDEPENDS += "u-boot"
20
21# Uncomment the following line to enable the hard floating point abi. Note that
22# this breaks some binary libraries and 3D (neither of which ship with
23# meta-yocto). For maximum compatibility, leave this disabled.
24#DEFAULTTUNE ?= "cortexa8hf-neon"
25{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_cortexa8" }}
26{{ input type:"choice" val:"tune_arm1136jf_s" msg:"arm1136jf-s tuning optimizations" }}
27{{ input type:"choice" val:"tune_arm920t" msg:"arm920t tuning optimizations" }}
28{{ input type:"choice" val:"tune_arm926ejs" msg:"arm926ejs tuning optimizations" }}
29{{ input type:"choice" val:"tune_arm9tdmi" msg:"arm9tdmi tuning optimizations" }}
30{{ input type:"choice" val:"tune_cortexa5" msg:"cortexa5 tuning optimizations" }}
31{{ input type:"choice" val:"tune_cortexa7" msg:"cortexa7 tuning optimizations" }}
32{{ input type:"choice" val:"tune_cortexa8" msg:"cortexa8 tuning optimizations" }}
33{{ input type:"choice" val:"tune_cortexa9" msg:"cortexa9 tuning optimizations" }}
34{{ input type:"choice" val:"tune_cortexa15" msg:"cortexa15 tuning optimizations" }}
35{{ input type:"choice" val:"tune_cortexm1" msg:"cortexm1 tuning optimizations" }}
36{{ input type:"choice" val:"tune_cortexm3" msg:"cortexm3 tuning optimizations" }}
37{{ input type:"choice" val:"tune_cortexr4" msg:"cortexr4 tuning optimizations" }}
38{{ input type:"choice" val:"tune_ep9312" msg:"ep9312 tuning optimizations" }}
39{{ input type:"choice" val:"tune_iwmmxt" msg:"iwmmxt tuning optimizations" }}
40{{ input type:"choice" val:"tune_strongarm1100" msg:"strongarm1100 tuning optimizations" }}
41{{ input type:"choice" val:"tune_xscale" msg:"xscale tuning optimizations" }}
42{{ if tunefile == "tune_arm1136jf_s": }}
43include conf/machine/include/tune-arm1136jf-s.inc
44{{ if tunefile == "tune_arm920t": }}
45include conf/machine/include/tune-arm920t.inc
46{{ if tunefile == "tune_arm926ejs": }}
47include conf/machine/include/tune-arm926ejs.inc
48{{ if tunefile == "tune_arm9tdmi": }}
49include conf/machine/include/tune-arm9tdmi.inc
50{{ if tunefile == "tune_cortexa5": }}
51include conf/machine/include/tune-cortexa5.inc
52{{ if tunefile == "tune_cortexa7": }}
53include conf/machine/include/tune-cortexa7.inc
54{{ if tunefile == "tune_cortexa8": }}
55include conf/machine/include/tune-cortexa8.inc
56{{ if tunefile == "tune_cortexa9": }}
57include conf/machine/include/tune-cortexa9.inc
58{{ if tunefile == "tune_cortexa15": }}
59include conf/machine/include/tune-cortexa15.inc
60{{ if tunefile == "tune_cortexm1": }}
61include conf/machine/include/tune-cortexm1.inc
62{{ if tunefile == "tune_cortexm3": }}
63include conf/machine/include/tune-cortexm3.inc
64{{ if tunefile == "tune_cortexr4": }}
65include conf/machine/include/tune-cortexr4.inc
66{{ if tunefile == "tune_ep9312": }}
67include conf/machine/include/tune-ep9312.inc
68{{ if tunefile == "tune_iwmmxt": }}
69include conf/machine/include/tune-iwmmxt.inc
70{{ if tunefile == "tune_strongarm1100": }}
71include conf/machine/include/tune-strongarm1100.inc
72{{ if tunefile == "tune_xscale": }}
73include conf/machine/include/tune-xscale.inc
74
75IMAGE_FSTYPES += "tar.bz2 jffs2"
76EXTRA_IMAGECMD_jffs2 = "-lnp "
77
78# 2.6.37 and later kernels use OMAP_SERIAL, ttyO2
79# earlier kernels use ttyS2
80SERIAL_CONSOLE = "115200 ttyO2"
81
82{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
83{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
84{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
85PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
86
87{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
88{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
89{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
90PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
91PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
92
93KERNEL_IMAGETYPE = "zImage"
94KERNEL_DEVICETREE = "${S}/arch/arm/boot/dts/omap3-beagle.dts ${S}/arch/arm/boot/dts/omap3-beagle-xm.dts"
95
96SPL_BINARY = "MLO"
97UBOOT_SUFFIX = "img"
98{{ input type:"edit" name:"uboot_machine" prio:"40" msg:"Please specify a value for UBOOT_MACHINE:" default:"omap3_beagle_config" }}
99UBOOT_MACHINE = "{{=uboot_machine}}"
100{{ input type:"edit" name:"uboot_entrypoint" prio:"40" msg:"Please specify a value for UBOOT_ENTRYPOINT:" default:"0x80008000" }}
101UBOOT_ENTRYPOINT = "{{=uboot_entrypoint}}"
102{{ input type:"edit" name:"uboot_loadaddress" prio:"40" msg:"Please specify a value for UBOOT_LOADADDRESS:" default:"0x80008000" }}
103UBOOT_LOADADDRESS = "{{=uboot_loadaddress}}"
104
105MACHINE_FEATURES = "usbgadget usbhost vfat alsa"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
new file mode 100644
index 0000000000..264f3c91ad
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
@@ -0,0 +1,33 @@
1Section "Module"
2 Load "extmod"
3 Load "dbe"
4 Load "glx"
5 Load "freetype"
6 Load "type1"
7 Load "record"
8 Load "dri"
9EndSection
10
11Section "Monitor"
12 Identifier "Builtin Default Monitor"
13EndSection
14
15Section "Device"
16 Identifier "Builtin Default fbdev Device 0"
17 Driver "omapfb"
18EndSection
19
20Section "Screen"
21 Identifier "Builtin Default fbdev Screen 0"
22 Device "Builtin Default fbdev Device 0"
23 Monitor "Builtin Default Monitor"
24EndSection
25
26Section "ServerLayout"
27 Identifier "Builtin Default Layout"
28 Screen "Builtin Default fbdev Screen 0"
29EndSection
30
31Section "ServerFlags"
32 Option "DontZap" "0"
33EndSection
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000000..72d991c7e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-non_hardware.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-non_hardware.cfg
new file mode 100644
index 0000000000..361343bb58
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-non_hardware.cfg
@@ -0,0 +1,30 @@
1#
2# Miscellaneous filesystems
3#
4CONFIG_NFS_DEF_FILE_IO_SIZE=1024
5
6#
7# Multiple Device Support
8#
9# CONFIG_MD is not set
10
11# Kernel Features
12#
13CONFIG_NO_HZ=y
14
15#
16# CPUIdle
17#
18CONFIG_CPU_IDLE=y
19CONFIG_CPU_IDLE_GOV_LADDER=y
20CONFIG_CPU_IDLE_GOV_MENU=y
21
22#
23# Kernel hacking
24#
25CONFIG_DEBUG_FS=y
26
27#
28# Power management options
29#
30CONFIG_PM_DEBUG=y
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..56f7f0f1e3
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,13 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH arm
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for preempt-rt kernels
12include features/latencytop/latencytop.scc
13include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..80640db4a2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,13 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH arm
4
5include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for standard kernels
12include features/latencytop/latencytop.scc
13include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..51eaf2d32c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH arm
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..10134c81f5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
@@ -0,0 +1,320 @@
1#
2# System Type
3#
4CONFIG_ARCH_OMAP=y
5
6#
7# TI OMAP Implementations
8#
9# CONFIG_ARCH_OMAP2 is not set
10CONFIG_ARCH_OMAP3=y
11
12#
13# TI OMAP Common Features
14#
15CONFIG_ARCH_OMAP2PLUS=y
16
17#
18# OMAP Feature Selections
19#
20CONFIG_OMAP_32K_TIMER=y
21CONFIG_OMAP_32K_TIMER_HZ=128
22CONFIG_OMAP_DM_TIMER=y
23CONFIG_OMAP_RESET_CLOCKS=y
24CONFIG_OMAP_SMARTREFLEX=y
25CONFIG_OMAP_SMARTREFLEX_CLASS3=y
26CONFIG_OMAP_MBOX_FWK=m
27CONFIG_OMAP_MBOX_KFIFO_SIZE=256
28
29#
30# OMAP Board Type
31#
32CONFIG_MACH_OMAP3_BEAGLE=y
33
34#
35# Processor Features
36#
37CONFIG_ARM_THUMBEE=y
38CONFIG_ARM_ERRATA_430973=y
39
40#
41# Kernel Features
42#
43CONFIG_LEDS=y
44
45
46#
47# Serial drivers
48#
49CONFIG_SERIAL_OMAP=y
50CONFIG_SERIAL_OMAP_CONSOLE=y
51
52#
53# At least one emulation must be selected
54#
55CONFIG_VFP=y
56CONFIG_NEON=y
57
58#
59# Power management options
60#
61CONFIG_PM=y
62CONFIG_PM_RUNTIME=y
63
64#
65# Generic Driver Options
66#
67CONFIG_MTD=y
68CONFIG_MTD_CMDLINE_PARTS=y
69#
70# User Modules And Translation Layers
71#
72CONFIG_MTD_BLKDEVS=y
73CONFIG_MTD_BLOCK=y
74
75#
76# RAM/ROM/Flash chip drivers
77#
78CONFIG_MTD_CFI=y
79CONFIG_MTD_CFI_INTELEXT=y
80
81#
82# Disk-On-Chip Device Drivers
83#
84CONFIG_MTD_NAND=y
85
86CONFIG_MTD_NAND_OMAP2=y
87
88CONFIG_MTD_UBI=y
89
90#
91# SCSI device support
92#
93CONFIG_SCSI=y
94
95#
96# SCSI support type (disk, tape, CD-ROM)
97#
98CONFIG_BLK_DEV_SD=y
99
100#
101# Ethernet (10 or 100Mbit)
102#
103CONFIG_SMSC911X=y
104CONFIG_USB_NET_SMSC95XX=y
105
106#
107# Userland interfaces
108#
109CONFIG_INPUT_EVDEV=y
110
111#
112# Input Device Drivers
113#
114CONFIG_KEYBOARD_TWL4030=y
115CONFIG_INPUT_TOUCHSCREEN=y
116CONFIG_TOUCHSCREEN_ADS7846=y
117
118#
119# Miscellaneous I2C Chip support
120#
121CONFIG_I2C=y
122CONFIG_I2C_OMAP=y
123CONFIG_SPI=y
124CONFIG_SPI_MASTER=y
125CONFIG_SPI_OMAP24XX=y
126
127#
128# I2C GPIO expanders:
129#
130CONFIG_GPIO_TWL4030=y
131
132#
133# SPI GPIO expanders:
134#
135CONFIG_OMAP_WATCHDOG=y
136CONFIG_WATCHDOG_NOWAYOUT=y
137
138#
139# Multifunction device drivers
140#
141CONFIG_TWL4030_CORE=y
142CONFIG_REGULATOR=y
143CONFIG_REGULATOR_DUMMY=y
144CONFIG_REGULATOR_TWL4030=y
145
146#
147# Graphics support
148#
149CONFIG_FB=y
150CONFIG_DRM=m
151# CONFIG_VGASTATE is not set
152# CONFIG_VIDEO_OUTPUT_CONTROL is not set
153# CONFIG_FIRMWARE_EDID is not set
154# CONFIG_FB_DDC is not set
155# CONFIG_FB_BOOT_VESA_SUPPORT is not set
156CONFIG_FB_CFB_FILLRECT=y
157CONFIG_FB_CFB_COPYAREA=y
158CONFIG_FB_CFB_IMAGEBLIT=y
159# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
160# CONFIG_FB_SYS_FILLRECT is not set
161# CONFIG_FB_SYS_COPYAREA is not set
162# CONFIG_FB_SYS_IMAGEBLIT is not set
163# CONFIG_FB_FOREIGN_ENDIAN is not set
164# CONFIG_FB_SYS_FOPS is not set
165# CONFIG_FB_SVGALIB is not set
166# CONFIG_FB_MACMODES is not set
167# CONFIG_FB_BACKLIGHT is not set
168CONFIG_FB_MODE_HELPERS=y
169# CONFIG_FB_TILEBLITTING is not set
170
171#
172# Frame buffer hardware drivers
173#
174# CONFIG_FB_S1D13XXX is not set
175# CONFIG_FB_TMIO is not set
176# CONFIG_FB_VIRTUAL is not set
177# CONFIG_FB_METRONOME is not set
178# CONFIG_FB_MB862XX is not set
179# CONFIG_FB_BROADSHEET is not set
180# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
181CONFIG_OMAP2_VRAM=y
182CONFIG_OMAP2_VRFB=y
183CONFIG_OMAP2_DSS=y
184CONFIG_OMAP2_VRAM_SIZE=14
185CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
186# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
187CONFIG_OMAP2_DSS_DPI=y
188# CONFIG_OMAP2_DSS_RFBI is not set
189CONFIG_OMAP2_DSS_VENC=y
190# CONFIG_OMAP2_DSS_SDI is not set
191CONFIG_OMAP2_DSS_DSI=y
192# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
193CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
194CONFIG_FB_OMAP2=y
195CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
196CONFIG_FB_OMAP2_NUM_FBS=2
197
198#
199# OMAP2/3 Display Device Drivers
200#
201CONFIG_PANEL_GENERIC_DPI=y
202CONFIG_PANEL_DVI=y
203CONFIG_PANEL_SHARP_LS037V7DW01=y
204# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set
205# CONFIG_PANEL_TAAL is not set
206CONFIG_PANEL_TPO_TD043MTEA1=m
207# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
208CONFIG_BACKLIGHT_CLASS_DEVICE=y
209
210#
211# Display device support
212#
213CONFIG_DISPLAY_SUPPORT=y
214CONFIG_DUMMY_CONSOLE=y
215# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
216CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
217# CONFIG_FONTS is not set
218CONFIG_FONT_8x8=y
219CONFIG_FONT_8x16=y
220# CONFIG_LOGO_LINUX_MONO is not set
221# CONFIG_LOGO_LINUX_VGA16 is not set
222
223#
224# Console display driver support
225#
226CONFIG_FRAMEBUFFER_CONSOLE=y
227CONFIG_LOGO=y
228# CONFIG_VGA_CONSOLE is not set
229
230# DMA Devices
231CONFIG_DMADEVICES=y
232CONFIG_DMA_OMAP=y
233CONFIG_DMA_OF=y
234
235CONFIG_SOUND=y
236CONFIG_SND=y
237CONFIG_SND_SOC=y
238CONFIG_SND_OMAP_SOC=y
239CONFIG_SND_OMAP_SOC_OMAP_TWL4030=y
240
241#
242# USB Input Devices
243#
244CONFIG_USB=y
245CONFIG_USB_SUPPORT=y
246
247#
248# Miscellaneous USB options
249#
250CONFIG_USB_OTG=y
251# CONFIG_USB_OTG_WHITELIST is not set
252
253#
254# USB Host Controller Drivers
255#
256CONFIG_USB_EHCI_HCD=y
257CONFIG_USB_EHCI_TT_NEWSCHED=y
258CONFIG_USB_EHCI_ROOT_HUB_TT=y
259CONFIG_USB_MUSB_HDRC=y
260CONFIG_USB_MUSB_OMAP2PLUS=y
261CONFIG_USB_OMAP=y
262
263#
264# OMAP 343x high speed USB support
265#
266CONFIG_USB_MUSB_OTG=y
267CONFIG_USB_GADGET_MUSB_HDRC=y
268CONFIG_USB_MUSB_HDRC_HCD=y
269CONFIG_USB_INVENTRA_DMA=y
270
271#
272# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
273#
274
275#
276# may also be needed; see USB_STORAGE Help for more information
277#
278CONFIG_USB_STORAGE=y
279
280#
281# USB Miscellaneous drivers
282#
283CONFIG_USB_GADGET=y
284CONFIG_USB_GADGET_DUALSPEED=y
285CONFIG_USB_OTG_UTILS=y
286CONFIG_TWL4030_USB=y
287
288# USB gadget modules
289CONFIG_USB_G_NCM=y
290CONFIG_USB_MASS_STORAGE=y
291
292CONFIG_MMC=y
293
294#
295# MMC/SD Host Controller Drivers
296#
297CONFIG_MMC_OMAP_HS=y
298
299#
300# Real Time Clock
301#
302CONFIG_RTC_LIB=y
303CONFIG_RTC_CLASS=y
304CONFIG_RTC_DRV_TWL4030=y
305
306#
307# DOS/FAT/NT Filesystems
308#
309CONFIG_VFAT_FS=y
310
311#
312# Multimedia core support
313#
314
315# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
316
317#
318# Advanced Power Management Emulation support
319#
320CONFIG_APM_EMULATION=y
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..24196e6f67
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,7 @@
1kconf hardware {{=machine}}.cfg
2kconf non-hardware {{machine}}-non_hardware.cfg
3
4include features/usb-net/usb-net.scc
5
6kconf hardware {{=machine}}-user-config.cfg
7include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..25c87a85ac
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,25 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
13
14{{ if need_new_kbranch == "n": }}
15KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
16
17{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
18{{ if smp == "y": }}
19KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
20
21SRC_URI += "file://{{=machine}}-standard.scc \
22 file://{{=machine}}-user-config.cfg \
23 file://{{=machine}}-user-patches.scc \
24 file://{{=machine}}-user-features.scc \
25 "
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..08b1f88d1b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-preempt-rt.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
31#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..bc6968d832
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000000..d221d5f2a4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..1e814c54d7
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "19f7e43b54aef08d58135ed2a897d77b624b320a"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "459165c1dd61c4e843c36e6a1abeb30949a20ba7"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..ca7f8c5978
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT b/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT
new file mode 100644
index 0000000000..fb950dc69f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/COPYING.MIT
@@ -0,0 +1,17 @@
1Permission is hereby granted, free of charge, to any person obtaining a copy
2of this software and associated documentation files (the "Software"), to deal
3in the Software without restriction, including without limitation the rights
4to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5copies of the Software, and to permit persons to whom the Software is
6furnished to do so, subject to the following conditions:
7
8The above copyright notice and this permission notice shall be included in
9all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17THE SOFTWARE.
diff --git a/scripts/lib/bsp/substrate/target/arch/common/README b/scripts/lib/bsp/substrate/target/arch/common/README
new file mode 100644
index 0000000000..928659f302
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/README
@@ -0,0 +1,118 @@
1This README file contains information on building the meta-{{=machine}}
2BSP layer, and booting the images contained in the /binary directory.
3Please see the corresponding sections below for details.
4
5
6Dependencies
7============
8
9This layer depends on:
10
11 URI: git://git.openembedded.org/bitbake
12 branch: master
13
14 URI: git://git.openembedded.org/openembedded-core
15 layers: meta
16 branch: master
17
18 URI: git://git.yoctoproject.org/xxxx
19 layers: xxxx
20 branch: master
21
22
23Patches
24=======
25
26Please submit any patches against this BSP to the Yocto mailing list
27(yocto@yoctoproject.org) and cc: the maintainer:
28
29Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
30
31Please see the meta-xxxx/MAINTAINERS file for more details.
32
33
34Table of Contents
35=================
36
37 I. Building the meta-{{=machine}} BSP layer
38 II. Booting the images in /binary
39
40
41I. Building the meta-{{=machine}} BSP layer
42========================================
43
44--- replace with specific instructions for your layer ---
45
46In order to build an image with BSP support for a given release, you
47need to download the corresponding BSP tarball from the 'Board Support
48Package (BSP) Downloads' page of the Yocto Project website.
49
50Having done that, and assuming you extracted the BSP tarball contents
51at the top-level of your yocto build tree, you can build a
52{{=machine}} image by adding the location of the meta-{{=machine}}
53layer to bblayers.conf, along with any other layers needed (to access
54common metadata shared between BSPs) e.g.:
55
56 yocto/meta-xxxx \
57 yocto/meta-xxxx/meta-{{=machine}} \
58
59To enable the {{=machine}} layer, add the {{=machine}} MACHINE to local.conf:
60
61 MACHINE ?= "{{=machine}}"
62
63You should then be able to build a {{=machine}} image as such:
64
65 $ source oe-init-build-env
66 $ bitbake core-image-sato
67
68At the end of a successful build, you should have a live image that
69you can boot from a USB flash drive (see instructions on how to do
70that below, in the section 'Booting the images from /binary').
71
72As an alternative to downloading the BSP tarball, you can also work
73directly from the meta-xxxx git repository. For each BSP in the
74'meta-xxxx' repository, there are multiple branches, one corresponding
75to each major release starting with 'laverne' (0.90), in addition to
76the latest code which tracks the current master (note that not all
77BSPs are present in every release). Instead of extracting a BSP
78tarball at the top level of your yocto build tree, you can
79equivalently check out the appropriate branch from the meta-xxxx
80repository at the same location.
81
82
83II. Booting the images in /binary
84=================================
85
86--- replace with specific instructions for your platform ---
87
88This BSP contains bootable live images, which can be used to directly
89boot Yocto off of a USB flash drive.
90
91Under Linux, insert a USB flash drive. Assuming the USB flash drive
92takes device /dev/sdf, use dd to copy the live image to it. For
93example:
94
95# dd if=core-image-sato-{{=machine}}-20101207053738.hddimg of=/dev/sdf
96# sync
97# eject /dev/sdf
98
99This should give you a bootable USB flash device. Insert the device
100into a bootable USB socket on the target, and power on. This should
101result in a system booted to the Sato graphical desktop.
102
103If you want a terminal, use the arrows at the top of the UI to move to
104different pages of available applications, one of which is named
105'Terminal'. Clicking that should give you a root terminal.
106
107If you want to ssh into the system, you can use the root terminal to
108ifconfig the IP address and use that to ssh in. The root password is
109empty, so to log in type 'root' for the user name and hit 'Enter' at
110the Password prompt: and you should be in.
111
112----
113
114If you find you're getting corrupt images on the USB (it doesn't show
115the syslinux boot: prompt, or the boot: prompt contains strange
116characters), try doing this first:
117
118# dd if=/dev/zero of=/dev/sdf bs=1M count=512
diff --git a/scripts/lib/bsp/substrate/target/arch/common/README.sources b/scripts/lib/bsp/substrate/target/arch/common/README.sources
new file mode 100644
index 0000000000..3c4cb7b435
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/README.sources
@@ -0,0 +1,17 @@
1The sources for the packages comprising the images shipped with this
2BSP can be found at the following location:
3
4http://downloads.yoctoproject.org/mirror/sources/
5
6The metadata used to generate the images shipped with this BSP, in
7addition to the code contained in this BSP, can be found at the
8following location:
9
10http://www.yoctoproject.org/downloads/yocto-1.1/poky-edison-6.0.tar.bz2
11
12The metadata used to generate the images shipped with this BSP, in
13addition to the code contained in this BSP, can also be found at the
14following locations:
15
16git://git.yoctoproject.org/poky.git
17git://git.yoctoproject.org/meta-xxxx
diff --git a/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf b/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf
new file mode 100644
index 0000000000..5529f45954
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/conf/layer.conf
@@ -0,0 +1,10 @@
1# We have a conf and classes directory, add to BBPATH
2BBPATH .= ":${LAYERDIR}"
3
4# We have a recipes-* directories, add to BBFILES
5BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
6 ${LAYERDIR}/recipes-*/*/*.bbappend"
7
8BBFILE_COLLECTIONS += "{{=machine}}"
9BBFILE_PATTERN_{{=machine}} = "^${LAYERDIR}/"
10BBFILE_PRIORITY_{{=machine}} = "6"
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/{{=machine}}/machconfig b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/{{=machine}}/machconfig
new file mode 100644
index 0000000000..3b85d3821f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor/{{=machine}}/machconfig
@@ -0,0 +1,5 @@
1# Assume a USB mouse and keyboard are connected
2{{ input type:"boolean" name:"touchscreen" msg:"Does your BSP have a touchscreen? (y/n)" default:"n" }}
3HAVE_TOUCHSCREEN={{=touchscreen}}
4{{ input type:"boolean" name:"keyboard" msg:"Does your BSP have a keyboard? (y/n)" default:"y" }}
5HAVE_KEYBOARD={{=keyboard}}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend
new file mode 100644
index 0000000000..6d4804d127
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-bsp/formfactor/formfactor_0.0.bbappend
@@ -0,0 +1,2 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
2
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..03b7d84ec2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,26 @@
1{{ if kernel_choice == "custom": }}
2{{ input type:"boolean" name:"custom_kernel_remote" prio:"20" msg:"Is the custom kernel you'd like to use in a remote git repo? (y/n)" default:"y"}}
3
4{{ if kernel_choice == "custom" and custom_kernel_remote == "y": }}
5{{ input type:"edit-git-repo" name:"custom_kernel_remote_path" prio:"20" msg:"Please enter the full URI to the remote git repo (the default corresponds to linux-stable v3.13.9)" default:"git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git"}}
6
7{{ if kernel_choice == "custom" and custom_kernel_remote == "n": }}
8{{ input type:"edit-git-repo" name:"custom_kernel_local_path" prio:"20" msg:"You've indicated that you're not using a remote git repo. Please enter the full path to the local git repo you want to use (the default assumes a local linux-stable v3.13.9)" default:"/home/trz/yocto/kernels/linux-stable.git"}}
9
10{{ if kernel_choice == "custom": }}
11{{ input type:"boolean" name:"custom_kernel_need_kbranch" prio:"20" msg:"Do you need to use a specific (non-master) branch? (y/n)" default:"n"}}
12
13{{ if kernel_choice == "custom" and custom_kernel_need_kbranch == "y": }}
14{{ input type:"edit" name:"custom_kernel_kbranch" prio:"20" msg:"Please enter the branch you want to use (the default branch corresponds to the linux-stable 'linux-3.13.y' branch):" default:"linux-3.13.y"}}
15
16{{ if kernel_choice == "custom": }}
17{{ input type:"edit" name:"custom_kernel_srcrev" prio:"20" msg:"Please enter the SRCREV (commit id) you'd like to use (use '${AUTOREV}' to track the current HEAD):" default:"${AUTOREV}"}}
18
19{{ if kernel_choice == "custom": }}
20{{ input type:"edit" name:"custom_kernel_linux_version" prio:"20" msg:"Please enter the Linux version of the kernel you've specified:" default:"3.13.9"}}
21
22{{ if kernel_choice == "custom": }}
23{{ input type:"edit" name:"custom_kernel_linux_version_extension" prio:"20" msg:"Please enter a Linux version extension if you want (it will show up at the end of the kernel name shown by uname):" default:"-custom"}}
24
25{{ if kernel_choice == "custom": }}
26{{ input type:"edit-file" name:"custom_kernel_defconfig" prio:"20" msg:"It's recommended (but not required) that custom kernels be built using a defconfig. Please enter the full path to the defconfig for your kernel (NOTE: if you don't specify a defconfig the kernel probably won't build or boot):" default:""}}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom.bb b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom.bb
new file mode 100644
index 0000000000..6d3cc6f743
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom.bb
@@ -0,0 +1,57 @@
1# This file was derived from the linux-yocto-custom.bb recipe in
2# oe-core.
3#
4# linux-yocto-custom.bb:
5#
6# A yocto-bsp-generated kernel recipe that uses the linux-yocto and
7# oe-core kernel classes to apply a subset of yocto kernel
8# management to git managed kernel repositories.
9#
10# Warning:
11#
12# Building this kernel without providing a defconfig or BSP
13# configuration will result in build or boot errors. This is not a
14# bug.
15#
16# Notes:
17#
18# patches: patches can be merged into to the source git tree itself,
19# added via the SRC_URI, or controlled via a BSP
20# configuration.
21#
22# example configuration addition:
23# SRC_URI += "file://smp.cfg"
24# example patch addition:
25# SRC_URI += "file://0001-linux-version-tweak.patch
26# example feature addition:
27# SRC_URI += "file://feature.scc"
28#
29
30inherit kernel
31require recipes-kernel/linux/linux-yocto.inc
32
33{{ if kernel_choice == "custom" and custom_kernel_remote == "y": }}
34SRC_URI = "{{=custom_kernel_remote_path}};protocol=git;bareclone=1"
35{{ if kernel_choice == "custom" and custom_kernel_remote == "n": }}
36SRC_URI = "git://{{=custom_kernel_local_path}};protocol=file;bareclone=1"
37
38SRC_URI += "file://defconfig"
39
40SRC_URI += "file://{{=machine}}.scc \
41 file://{{=machine}}.cfg \
42 file://{{=machine}}-user-config.cfg \
43 file://{{=machine}}-user-patches.scc \
44 "
45
46{{ if kernel_choice == "custom" and custom_kernel_need_kbranch == "y" and custom_kernel_kbranch and custom_kernel_kbranch != "master": }}
47KBRANCH = "{{=custom_kernel_kbranch}}"
48
49LINUX_VERSION ?= "{{=custom_kernel_linux_version}}"
50LINUX_VERSION_EXTENSION ?= "{{=custom_kernel_linux_version_extension}}"
51
52SRCREV="{{=custom_kernel_srcrev}}"
53
54PR = "r0"
55PV = "${LINUX_VERSION}+git${SRCPV}"
56
57COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/defconfig b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/defconfig
new file mode 100644
index 0000000000..ceb0ffa30c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/defconfig
@@ -0,0 +1,5 @@
1#
2# Placeholder for custom default kernel configuration. yocto-bsp will
3# replace this file with a user-specified defconfig.
4#
5{{ if custom_kernel_defconfig: replace_file(of, custom_kernel_defconfig) }}
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..17c8b503da
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-config.cfg
@@ -0,0 +1,8 @@
1#
2# Used by yocto-kernel to manage config options.
3#
4# yocto-kernel may change the contents of this file in any
5# way it sees fit, including removing comments like this,
6# so don't manually make any modifications you don't want
7# to lose.
8#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..7a598d9118
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}-user-patches.scc
@@ -0,0 +1,8 @@
1#
2# Used by yocto-kernel to manage patches.
3#
4# yocto-kernel may change the contents of this file in any
5# way it sees fit, including removing comments like this,
6# so don't manually make any modifications you don't want
7# to lose.
8#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.cfg
new file mode 100644
index 0000000000..95170b12eb
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.cfg
@@ -0,0 +1,3 @@
1#
2# A convenient place to add config options, nothing more.
3#
diff --git a/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.scc
new file mode 100644
index 0000000000..2e3ca90793
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel/linux/{{ if kernel_choice == "custom": }} linux-yocto-custom/{{=machine}}.scc
@@ -0,0 +1,17 @@
1#
2# The top-level 'feature' for the {{=machine}} custom kernel.
3#
4# Essentially this is a convenient top-level container or starting
5# point for adding lower-level config fragements and features.
6#
7
8# {{=machine}}.cfg in the linux-yocto-custom subdir is just a
9# convenient place for adding random config fragments.
10
11kconf hardware {{=machine}}.cfg
12
13# These are used by yocto-kernel to add config fragments and features.
14# Don't remove if you plan on using yocto-kernel with this BSP.
15
16kconf hardware {{=machine}}-user-config.cfg
17include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..932fd79bb9
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/conf/machine/{{=machine}}.conf
@@ -0,0 +1,68 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
7{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
8{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
9PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
10
11{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
12{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
13{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
14PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
15PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
16
17{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_core2" }}
18{{ input type:"choice" val:"tune_i586" msg:"i586 tuning optimizations" }}
19{{ input type:"choice" val:"tune_atom" msg:"Atom tuning optimizations" }}
20{{ input type:"choice" val:"tune_core2" msg:"Core2 tuning optimizations" }}
21{{ if tunefile == "tune_i586": }}
22require conf/machine/include/tune-i586.inc
23{{ if tunefile == "tune_atom": }}
24require conf/machine/include/tune-atom.inc
25{{ if tunefile == "tune_core2": }}
26DEFAULTTUNE="core2-32"
27require conf/machine/include/tune-core2.inc
28
29require conf/machine/include/x86-base.inc
30
31MACHINE_FEATURES += "wifi efi pcbios"
32
33{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
34
35{{ if xserver == "y" and (kernel_choice == "linux-yocto_3.14" or kernel_choice == "linux-yocto_3.10"): }}
36{{ input type:"choicelist" name:"xserver_choice" prio:"50" msg:"Please select an xserver for this machine:" default:"xserver_i915" }}
37{{ input type:"choice" val:"xserver_vesa" msg:"VESA xserver support" }}
38{{ input type:"choice" val:"xserver_i915" msg:"i915 xserver support" }}
39{{ input type:"choice" val:"xserver_i965" msg:"i965 xserver support" }}
40
41{{ if xserver == "y" and kernel_choice == "custom": }}
42{{ input type:"choicelist" name:"xserver_choice" prio:"50" msg:"Please select an xserver for this machine:" default:"xserver_i915" }}
43{{ input type:"choice" val:"xserver_vesa" msg:"VESA xserver support" }}
44{{ input type:"choice" val:"xserver_i915" msg:"i915 xserver support" }}
45{{ input type:"choice" val:"xserver_i965" msg:"i965 xserver support" }}
46
47{{ if xserver == "y" and kernel_choice != "linux-yocto_3.14" and kernel_choice != "linux-yocto_3.10" and kernel_choice != "custom": xserver_choice = "xserver_i915" }}
48
49{{ if xserver == "y": }}
50XSERVER ?= "${XSERVER_X86_BASE} \
51 ${XSERVER_X86_EXT} \
52{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
53 ${XSERVER_X86_VESA} \
54{{ if xserver == "y" and xserver_choice == "xserver_i915": }}
55 ${XSERVER_X86_I915} \
56{{ if xserver == "y" and xserver_choice == "xserver_i965": }}
57 ${XSERVER_X86_I965} \
58{{ if xserver == "y": }}
59 "
60
61MACHINE_EXTRA_RRECOMMENDS += "linux-firmware v86d"
62
63GLIBC_ADDONS = "nptl"
64
65EXTRA_OECONF_append_pn-matchbox-panel-2 = " --with-battery=acpi"
66
67{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
68APPEND += "video=vesafb vga=0x318"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000000..72d991c7e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..bfefb0d0a0
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,15 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH i386
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for preempt-rt kernels
12include cfg/usb-mass-storage.scc
13include cfg/boot-live.scc
14include features/latencytop/latencytop.scc
15include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..60b670dffc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,15 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH i386
4
5include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for standard kernels
12include cfg/usb-mass-storage.scc
13include cfg/boot-live.scc
14include features/latencytop/latencytop.scc
15include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..ec44ef9485
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH i386
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..e93c0b8a08
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
@@ -0,0 +1,54 @@
1CONFIG_X86_32=y
2CONFIG_MATOM=y
3CONFIG_PRINTK=y
4
5# Basic hardware support for the box - network, USB, PCI, sound
6CONFIG_NETDEVICES=y
7CONFIG_ATA=y
8CONFIG_ATA_GENERIC=y
9CONFIG_ATA_SFF=y
10CONFIG_PCI=y
11CONFIG_MMC=y
12CONFIG_MMC_SDHCI=y
13CONFIG_USB_SUPPORT=y
14CONFIG_USB=y
15CONFIG_USB_ARCH_HAS_EHCI=y
16CONFIG_R8169=y
17CONFIG_PATA_SCH=y
18CONFIG_MMC_SDHCI_PCI=y
19CONFIG_USB_EHCI_HCD=y
20CONFIG_PCIEPORTBUS=y
21CONFIG_NET=y
22CONFIG_USB_UHCI_HCD=y
23CONFIG_USB_OHCI_HCD=y
24CONFIG_BLK_DEV_SD=y
25CONFIG_CHR_DEV_SG=y
26CONFIG_SOUND=y
27CONFIG_SND=y
28CONFIG_SND_HDA_INTEL=y
29CONFIG_SATA_AHCI=y
30CONFIG_AGP=y
31CONFIG_PM=y
32CONFIG_ACPI=y
33CONFIG_BACKLIGHT_LCD_SUPPORT=y
34CONFIG_BACKLIGHT_CLASS_DEVICE=y
35CONFIG_INPUT=y
36
37# Make sure these are on, otherwise the bootup won't be fun
38CONFIG_EXT3_FS=y
39CONFIG_UNIX=y
40CONFIG_INET=y
41CONFIG_MODULES=y
42CONFIG_SHMEM=y
43CONFIG_TMPFS=y
44CONFIG_PACKET=y
45
46# Needed for booting (and using) USB memory sticks
47CONFIG_BLK_DEV_LOOP=y
48CONFIG_NLS_CODEPAGE_437=y
49CONFIG_NLS_ISO8859_1=y
50
51CONFIG_RD_GZIP=y
52
53# Needed for booting (and using) CD images
54CONFIG_BLK_DEV_SR=y
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..eda1d62f11
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,20 @@
1kconf hardware {{=machine}}.cfg
2
3include features/intel-e1xxxx/intel-e100.scc
4include features/intel-e1xxxx/intel-e1xxxx.scc
5
6{{ if xserver == "y" and xserver_choice == "xserver_i915" or xserver_choice == "xserver_i965": }}
7include features/i915/i915.scc
8
9include features/serial/8250.scc
10include features/ericsson-3g/f5521gw.scc
11
12{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
13include cfg/vesafb.scc
14
15include cfg/usb-mass-storage.scc
16include cfg/boot-live.scc
17include features/power/intel.scc
18
19kconf hardware {{=machine}}-user-config.cfg
20include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..25c87a85ac
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,25 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
13
14{{ if need_new_kbranch == "n": }}
15KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
16
17{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
18{{ if smp == "y": }}
19KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
20
21SRC_URI += "file://{{=machine}}-standard.scc \
22 file://{{=machine}}-user-config.cfg \
23 file://{{=machine}}-user-patches.scc \
24 file://{{=machine}}-user-features.scc \
25 "
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..08b1f88d1b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-preempt-rt.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
31#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..bc6968d832
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000000..d221d5f2a4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..c1f26540a7
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "19f7e43b54aef08d58135ed2a897d77b624b320a"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "459165c1dd61c4e843c36e6a1abeb30949a20ba7"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..948d568cd1
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT b/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT
new file mode 100644
index 0000000000..89de354795
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/COPYING.MIT
@@ -0,0 +1,17 @@
1Permission is hereby granted, free of charge, to any person obtaining a copy
2of this software and associated documentation files (the "Software"), to deal
3in the Software without restriction, including without limitation the rights
4to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5copies of the Software, and to permit persons to whom the Software is
6furnished to do so, subject to the following conditions:
7
8The above copyright notice and this permission notice shall be included in
9all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17THE SOFTWARE.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/README b/scripts/lib/bsp/substrate/target/arch/layer/README
new file mode 100644
index 0000000000..943dfc4412
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/README
@@ -0,0 +1,64 @@
1This README file contains information on the contents of the
2{{=layer_name}} layer.
3
4Please see the corresponding sections below for details.
5
6
7Dependencies
8============
9
10This layer depends on:
11
12 URI: git://git.openembedded.org/bitbake
13 branch: master
14
15 URI: git://git.openembedded.org/openembedded-core
16 layers: meta
17 branch: master
18
19 URI: git://git.yoctoproject.org/xxxx
20 layers: xxxx
21 branch: master
22
23
24Patches
25=======
26
27Please submit any patches against the {{=layer_name}} layer to the
28xxxx mailing list (xxxx@zzzz.org) and cc: the maintainer:
29
30Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
31
32
33Table of Contents
34=================
35
36 I. Adding the {{=layer_name}} layer to your build
37 II. Misc
38
39
40I. Adding the {{=layer_name}} layer to your build
41=================================================
42
43--- replace with specific instructions for the {{=layer_name}} layer ---
44
45In order to use this layer, you need to make the build system aware of
46it.
47
48Assuming the {{=layer_name}} layer exists at the top-level of your
49yocto build tree, you can add it to the build system by adding the
50location of the {{=layer_name}} layer to bblayers.conf, along with any
51other layers needed. e.g.:
52
53 BBLAYERS ?= " \
54 /path/to/yocto/meta \
55 /path/to/yocto/meta-yocto \
56 /path/to/yocto/meta-yocto-bsp \
57 /path/to/yocto/meta-{{=layer_name}} \
58 "
59
60
61II. Misc
62========
63
64--- replace with specific information about the {{=layer_name}} layer ---
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf b/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf
new file mode 100644
index 0000000000..bdffe17195
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/conf/layer.conf
@@ -0,0 +1,10 @@
1# We have a conf and classes directory, add to BBPATH
2BBPATH .= ":${LAYERDIR}"
3
4# We have recipes-* directories, add to BBFILES
5BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
6 ${LAYERDIR}/recipes-*/*/*.bbappend"
7
8BBFILE_COLLECTIONS += "{{=layer_name}}"
9BBFILE_PATTERN_{{=layer_name}} = "^${LAYERDIR}/"
10BBFILE_PRIORITY_{{=layer_name}} = "{{=layer_priority}}"
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall b/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
new file mode 100644
index 0000000000..e2a89c3b5d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/layer-questions.noinstall
@@ -0,0 +1,14 @@
1{{ input type:"edit" name:"layer_priority" prio:"20" msg:"Please enter the layer priority you'd like to use for the layer:" default:"6"}}
2
3{{ input type:"boolean" name:"create_example_recipe" prio:"20" msg:"Would you like to have an example recipe created? (y/n)" default:"n"}}
4
5{{ if create_example_recipe == "y": }}
6{{ input type:"edit" name:"example_recipe_name" prio:"20" msg:"Please enter the name you'd like to use for your example recipe:" default:"example"}}
7
8{{ input type:"boolean" name:"create_example_bbappend" prio:"20" msg:"Would you like to have an example bbappend file created? (y/n)" default:"n"}}
9
10{{ if create_example_bbappend == "y": }}
11{{ input type:"edit" name:"example_bbappend_name" prio:"20" msg:"Please enter the name you'd like to use for your bbappend file:" default:"example"}}
12
13{{ if create_example_bbappend == "y": }}
14{{ input type:"edit" name:"example_bbappend_version" prio:"20" msg:"Please enter the version number you'd like to use for your bbappend file (this should match the recipe you're appending to):" default:"0.1"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}-{{=example_bbappend_version}}/example.patch b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}-{{=example_bbappend_version}}/example.patch
new file mode 100644
index 0000000000..2000a34da5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}-{{=example_bbappend_version}}/example.patch
@@ -0,0 +1,12 @@
1#
2# This is a non-functional placeholder file, here for example purposes
3# only.
4#
5# If you had a patch for your recipe, you'd put it in this directory
6# and reference it from your recipe's SRC_URI:
7#
8# SRC_URI += "file://example.patch"
9#
10# Note that you could also rename the directory containing this patch
11# to remove the version number or simply rename it 'files'. Doing so
12# allows you to use the same directory for multiple recipes.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}_{{=example_bbappend_version}}.bbappend b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}_{{=example_bbappend_version}}.bbappend
new file mode 100644
index 0000000000..2e50ff668d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_bbappend == "y": }} recipes-example-bbappend/example-bbappend/{{=example_bbappend_name}}_{{=example_bbappend_version}}.bbappend
@@ -0,0 +1,8 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
2
3#
4# This .bbappend doesn't yet do anything - replace this text with
5# modifications to the example_0.1.bb recipe, or whatever recipe it is
6# that you want to modify with this .bbappend (make sure you change
7# the recipe name (PN) and version (PV) to match).
8#
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/example.patch b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/example.patch
new file mode 100644
index 0000000000..2000a34da5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/example.patch
@@ -0,0 +1,12 @@
1#
2# This is a non-functional placeholder file, here for example purposes
3# only.
4#
5# If you had a patch for your recipe, you'd put it in this directory
6# and reference it from your recipe's SRC_URI:
7#
8# SRC_URI += "file://example.patch"
9#
10# Note that you could also rename the directory containing this patch
11# to remove the version number or simply rename it 'files'. Doing so
12# allows you to use the same directory for multiple recipes.
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/helloworld.c b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/helloworld.c
new file mode 100644
index 0000000000..71f2e46b4e
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}-0.1/helloworld.c
@@ -0,0 +1,8 @@
1#include <stdio.h>
2
3int main(int argc, char **argv)
4{
5 printf("Hello World!\n");
6
7 return 0;
8}
diff --git a/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}_0.1.bb b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}_0.1.bb
new file mode 100644
index 0000000000..14bf344da5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/layer/{{ if create_example_recipe == "y": }} recipes-example/example/{{=example_recipe_name}}_0.1.bb
@@ -0,0 +1,23 @@
1#
2# This file was derived from the 'Hello World!' example recipe in the
3# Yocto Project Development Manual.
4#
5
6DESCRIPTION = "Simple helloworld application"
7SECTION = "examples"
8LICENSE = "MIT"
9LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
10PR = "r0"
11
12SRC_URI = "file://helloworld.c"
13
14S = "${WORKDIR}"
15
16do_compile() {
17 ${CC} helloworld.c -o helloworld
18}
19
20do_install() {
21 install -d ${D}${bindir}
22 install -m 0755 helloworld ${D}${bindir}
23}
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..2e704263e1
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/conf/machine/{{=machine}}.conf
@@ -0,0 +1,38 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6require conf/machine/include/tune-mips32.inc
7
8MACHINE_FEATURES = "screen keyboard pci usbhost ext2 ext3 serial"
9
10KERNEL_IMAGETYPE = "vmlinux"
11KERNEL_ALT_IMAGETYPE = "vmlinux.bin"
12KERNEL_IMAGE_STRIP_EXTRA_SECTIONS = ".comment"
13
14{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
15{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
16{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
17PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
18
19{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
20{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
21{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
22PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
23PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
24
25{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
26{{ if xserver == "y": }}
27PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
28XSERVER ?= "xserver-xorg \
29 xf86-input-evdev \
30 xf86-video-fbdev"
31
32SERIAL_CONSOLE = "115200 ttyS0"
33USE_VT ?= "0"
34
35MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
36
37IMAGE_FSTYPES ?= "jffs2 tar.bz2"
38JFFS2_ERASEBLOCK = "0x10000" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..b0fb63ac6a
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH mips
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..326663a509
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH mips
4
5include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..4514765eb3
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH mips
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..a1b333ca56
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
@@ -0,0 +1 @@
CONFIG_MIPS=y
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..1ef01b6e3c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,7 @@
1kconf hardware {{=machine}}.cfg
2
3include cfg/usb-mass-storage.scc
4include cfg/fs/vfat.scc
5
6kconf hardware {{=machine}}-user-config.cfg
7include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..25c87a85ac
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,25 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
13
14{{ if need_new_kbranch == "n": }}
15KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
16
17{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
18{{ if smp == "y": }}
19KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
20
21SRC_URI += "file://{{=machine}}-standard.scc \
22 file://{{=machine}}-user-config.cfg \
23 file://{{=machine}}-user-patches.scc \
24 file://{{=machine}}-user-features.scc \
25 "
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..08b1f88d1b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-preempt-rt.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
31#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..bc6968d832
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000000..85544e812c
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..1e814c54d7
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "19f7e43b54aef08d58135ed2a897d77b624b320a"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "459165c1dd61c4e843c36e6a1abeb30949a20ba7"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..ca7f8c5978
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..78fb5db22b
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/conf/machine/{{=machine}}.conf
@@ -0,0 +1,74 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6TARGET_FPU = ""
7
8{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_ppce300c3" }}
9{{ input type:"choice" val:"tune_ppc476" msg:"ppc476 tuning optimizations" }}
10{{ input type:"choice" val:"tune_ppc603e" msg:"ppc603e tuning optimizations" }}
11{{ input type:"choice" val:"tune_ppc7400" msg:"ppc7400 tuning optimizations" }}
12{{ input type:"choice" val:"tune_ppce300c2" msg:"ppce300c2 tuning optimizations" }}
13{{ input type:"choice" val:"tune_ppce300c3" msg:"ppce300c3 tuning optimizations" }}
14{{ input type:"choice" val:"tune_ppce500" msg:"ppce500 tuning optimizations" }}
15{{ input type:"choice" val:"tune_ppce500mc" msg:"ppce500mc tuning optimizations" }}
16{{ input type:"choice" val:"tune_ppce500v2" msg:"ppce500v2 tuning optimizations" }}
17{{ input type:"choice" val:"tune_ppce5500" msg:"ppce5500 tuning optimizations" }}
18{{ input type:"choice" val:"tune_ppce6500" msg:"ppce6500 tuning optimizations" }}
19{{ if tunefile == "tune_ppc476": }}
20include conf/machine/include/tune-ppc476.inc
21{{ if tunefile == "tune_ppc603e": }}
22include conf/machine/include/tune-ppc603e.inc
23{{ if tunefile == "tune_ppc7400": }}
24include conf/machine/include/tune-ppc7400.inc
25{{ if tunefile == "tune_ppce300c2": }}
26include conf/machine/include/tune-ppce300c2.inc
27{{ if tunefile == "tune_ppce300c3": }}
28include conf/machine/include/tune-ppce300c3.inc
29{{ if tunefile == "tune_ppce500": }}
30include conf/machine/include/tune-ppce500.inc
31{{ if tunefile == "tune_ppce500mc": }}
32include conf/machine/include/tune-ppce500mc.inc
33{{ if tunefile == "tune_ppce500v2": }}
34include conf/machine/include/tune-ppce500v2.inc
35{{ if tunefile == "tune_ppce5500": }}
36include conf/machine/include/tune-ppce5500.inc
37{{ if tunefile == "tune_ppce6500": }}
38include conf/machine/include/tune-ppce6500.inc
39
40KERNEL_IMAGETYPE = "uImage"
41
42EXTRA_IMAGEDEPENDS += "u-boot"
43UBOOT_MACHINE_{{=machine}} = "MPC8315ERDB_config"
44
45SERIAL_CONSOLE = "115200 ttyS0"
46
47MACHINE_FEATURES = "keyboard pci ext2 ext3 serial"
48
49{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
50{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
51{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
52PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
53
54{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
55{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
56{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
57PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
58PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
59
60{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
61{{ if xserver == "y": }}
62PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
63XSERVER ?= "xserver-xorg \
64 xf86-input-evdev \
65 xf86-video-fbdev"
66
67PREFERRED_VERSION_u-boot ?= "v2013.07%"
68{{ input type:"edit" name:"uboot_entrypoint" prio:"40" msg:"Please specify a value for UBOOT_ENTRYPOINT:" default:"0x00000000" }}
69UBOOT_ENTRYPOINT = "{{=uboot_entrypoint}}"
70
71{{ input type:"edit" name:"kernel_devicetree" prio:"40" msg:"Please specify a [arch/powerpc/boot/dts/xxx] value for KERNEL_DEVICETREE:" default:"mpc8315erdb.dts" }}
72KERNEL_DEVICETREE = "${S}/arch/powerpc/boot/dts/{{=kernel_devicetree}}"
73
74MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..1da7b0c892
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH powerpc
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..53a74a6ca2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH powerpc
4
5include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..4ca6224774
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH powerpc
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..9f37d07553
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
@@ -0,0 +1,163 @@
1..........................................................................
2. WARNING
3.
4. This file is a kernel configuration fragment, and not a full kernel
5. configuration file. The final kernel configuration is made up of
6. an assembly of processed fragments, each of which is designed to
7. capture a specific part of the final configuration (e.g. platform
8. configuration, feature configuration, and board specific hardware
9. configuration). For more information on kernel configuration, please
10. consult the product documentation.
11.
12..........................................................................
13CONFIG_PPC32=y
14CONFIG_PPC_OF=y
15CONFIG_PPC_UDBG_16550=y
16
17#
18# Processor support
19#
20CONFIG_PPC_83xx=y
21
22#
23# Platform support
24#
25CONFIG_MPC831x_RDB=y
26# CONFIG_PPC_CHRP is not set
27# CONFIG_PPC_PMAC is not set
28
29#
30# Bus options
31#
32CONFIG_PCI=y
33
34#
35# Memory Technology Devices (MTD)
36#
37CONFIG_MTD=y
38CONFIG_MTD_PARTITIONS=y
39CONFIG_MTD_CMDLINE_PARTS=y
40CONFIG_MTD_OF_PARTS=y
41
42#
43# User Modules And Translation Layers
44#
45CONFIG_MTD_CHAR=y
46CONFIG_MTD_BLOCK=y
47
48#
49# RAM/ROM/Flash chip drivers
50#
51CONFIG_MTD_CFI=y
52CONFIG_MTD_CFI_AMDSTD=y
53
54#
55# Mapping drivers for chip access
56#
57CONFIG_MTD_PHYSMAP_OF=y
58
59#
60# NAND Flash Device Drivers
61#
62CONFIG_MTD_NAND=y
63
64#
65# Ethernet (1000 Mbit)
66#
67CONFIG_GIANFAR=y
68
69#
70# Serial drivers
71#
72CONFIG_SERIAL_8250=y
73CONFIG_SERIAL_8250_CONSOLE=y
74CONFIG_SERIAL_8250_NR_UARTS=2
75
76#
77# Watchdog Device Drivers
78#
79CONFIG_8xxx_WDT=y
80
81#
82# I2C support
83#
84CONFIG_I2C=y
85CONFIG_I2C_CHARDEV=y
86
87#
88# I2C Hardware Bus support
89#
90CONFIG_I2C_MPC=y
91
92CONFIG_SENSORS_LM75=y
93
94CONFIG_MISC_DEVICES=y
95
96#
97# Miscellaneous I2C Chip support
98#
99CONFIG_EEPROM_AT24=y
100
101#
102# SPI support
103#
104CONFIG_SPI=y
105# CONFIG_SPI_DEBUG is not set
106CONFIG_SPI_MASTER=y
107
108#
109# SPI Master Controller Drivers
110#
111CONFIG_SPI_MPC8xxx=y
112
113#
114# SPI Protocol Masters
115#
116CONFIG_HWMON=y
117
118#
119# SCSI device support
120#
121CONFIG_SCSI=y
122CONFIG_BLK_DEV_SD=y
123CONFIG_CHR_DEV_SG=y
124CONFIG_SCSI_LOGGING=y
125
126CONFIG_ATA=y
127CONFIG_ATA_VERBOSE_ERROR=y
128CONFIG_SATA_FSL=y
129CONFIG_ATA_SFF=y
130
131#
132# USB support
133#
134CONFIG_USB=m
135CONFIG_USB_DEVICEFS=y
136
137#
138# USB Host Controller Drivers
139#
140CONFIG_USB_EHCI_HCD=m
141CONFIG_USB_EHCI_FSL=y
142CONFIG_USB_STORAGE=m
143
144#
145# Real Time Clock
146#
147CONFIG_RTC_CLASS=y
148
149#
150# I2C RTC drivers
151#
152CONFIG_RTC_DRV_DS1307=y
153
154CONFIG_KGDB_8250=m
155
156CONFIG_CRYPTO_DEV_TALITOS=m
157
158CONFIG_FSL_DMA=y
159
160CONFIG_MMC=y
161CONFIG_MMC_SPI=m
162
163CONFIG_USB_FSL_MPH_DR_OF=y
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..c9fd468180
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,9 @@
1kconf hardware {{=machine}}.cfg
2
3include cfg/usb-mass-storage.scc
4include cfg/fs/vfat.scc
5
6include cfg/dmaengine.scc
7
8kconf hardware {{=machine}}-user-config.cfg
9include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..25c87a85ac
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,25 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
13
14{{ if need_new_kbranch == "n": }}
15KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
16
17{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
18{{ if smp == "y": }}
19KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
20
21SRC_URI += "file://{{=machine}}-standard.scc \
22 file://{{=machine}}-user-config.cfg \
23 file://{{=machine}}-user-patches.scc \
24 file://{{=machine}}-user-features.scc \
25 "
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..00c8c68933
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-preempt-rt.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
31#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..bc6968d832
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000000..d221d5f2a4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..a61f5ccb80
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "19f7e43b54aef08d58135ed2a897d77b624b320a"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "459165c1dd61c4e843c36e6a1abeb30949a20ba7"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..aebda9b3a5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..782ac217d9
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/conf/machine/{{=machine}}.conf
@@ -0,0 +1,68 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
7{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
8{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
9PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
10
11{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
12{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
13{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
14PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
15PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
16
17{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
18PREFERRED_PROVIDER_virtual/xserver ?= "xserver-xorg"
19PREFERRED_PROVIDER_virtual/libgl ?= "mesa"
20PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
21PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"
22
23{{ input type:"choicelist" name:"qemuarch" prio:"5" msg:"Which qemu architecture would you like to use?" default:"i386" }}
24{{ input type:"choice" val:"i386" msg:"i386 (32-bit)" }}
25{{ input type:"choice" val:"x86_64" msg:"x86_64 (64-bit)" }}
26{{ input type:"choice" val:"arm" msg:"ARM (32-bit)" }}
27{{ input type:"choice" val:"powerpc" msg:"PowerPC (32-bit)" }}
28{{ input type:"choice" val:"mips" msg:"MIPS (32-bit)" }}
29{{ if qemuarch == "i386": }}
30require conf/machine/include/qemu.inc
31require conf/machine/include/tune-i586.inc
32{{ if qemuarch == "x86_64": }}
33require conf/machine/include/qemu.inc
34require conf/machine/include/tune-x86_64.inc
35{{ if qemuarch == "arm": }}
36require conf/machine/include/qemu.inc
37require conf/machine/include/tune-arm926ejs.inc
38{{ if qemuarch == "powerpc": }}
39require conf/machine/include/qemu.inc
40require conf/machine/include/tune-ppc603e.inc
41{{ if qemuarch == "mips": }}
42require conf/machine/include/qemu.inc
43require conf/machine/include/tune-mips32.inc
44
45{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
46MACHINE_FEATURES += "x86"
47KERNEL_IMAGETYPE = "bzImage"
48SERIAL_CONSOLE = "115200 ttyS0"
49XSERVER = "xserver-xorg \
50 ${@base_contains('DISTRO_FEATURES', 'opengl', 'mesa-driver-swrast', '', d)} \
51 xf86-input-vmmouse \
52 xf86-input-keyboard \
53 xf86-input-evdev \
54 xf86-video-vmware"
55
56{{ if qemuarch == "arm": }}
57KERNEL_IMAGETYPE = "zImage"
58SERIAL_CONSOLE = "115200 ttyAMA0"
59
60{{ if qemuarch == "powerpc": }}
61KERNEL_IMAGETYPE = "vmlinux"
62SERIAL_CONSOLE = "115200 ttyS0"
63
64{{ if qemuarch == "mips": }}
65KERNEL_IMAGETYPE = "vmlinux"
66KERNEL_ALT_IMAGETYPE = "vmlinux.bin"
67SERIAL_CONSOLE = "115200 ttyS0"
68MACHINE_EXTRA_RRECOMMENDS = " kernel-modules"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/{{=machine}}/interfaces b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/{{=machine}}/interfaces
new file mode 100644
index 0000000000..16967763e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown/{{=machine}}/interfaces
@@ -0,0 +1,5 @@
1# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
2
3# The loopback interface
4auto lo
5iface lo inet loopback
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend
new file mode 100644
index 0000000000..72d991c7e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-core/init-ifupdown/init-ifupdown_1.0.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/xorg.conf b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/xorg.conf
new file mode 100644
index 0000000000..13519804bc
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/xorg.conf
@@ -0,0 +1,77 @@
1
2Section "Files"
3EndSection
4
5Section "InputDevice"
6 Identifier "Generic Keyboard"
7 Driver "evdev"
8 Option "CoreKeyboard"
9 Option "Device" "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
10 Option "XkbRules" "xorg"
11 Option "XkbModel" "evdev"
12 Option "XkbLayout" "us"
13EndSection
14
15Section "InputDevice"
16 Identifier "Configured Mouse"
17{{ if qemuarch == "arm" or qemuarch == "powerpc" or qemuarch == "mips": }}
18 Driver "mouse"
19{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
20 Driver "vmmouse"
21
22 Option "CorePointer"
23 Option "Device" "/dev/input/mice"
24 Option "Protocol" "ImPS/2"
25 Option "ZAxisMapping" "4 5"
26 Option "Emulate3Buttons" "true"
27EndSection
28
29Section "InputDevice"
30 Identifier "Qemu Tablet"
31 Driver "evdev"
32 Option "CorePointer"
33 Option "Device" "/dev/input/touchscreen0"
34 Option "USB" "on"
35EndSection
36
37Section "Device"
38 Identifier "Graphics Controller"
39{{ if qemuarch == "arm" or qemuarch == "powerpc" or qemuarch == "mips": }}
40 Driver "fbdev"
41{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
42 Driver "vmware"
43
44EndSection
45
46Section "Monitor"
47 Identifier "Generic Monitor"
48 Option "DPMS"
49 # 1024x600 59.85 Hz (CVT) hsync: 37.35 kHz; pclk: 49.00 MHz
50 Modeline "1024x600_60.00" 49.00 1024 1072 1168 1312 600 603 613 624 -hsync +vsync
51 # 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
52 ModeLine "640x480" 25.2 640 656 752 800 480 490 492 525 -hsync -vsync
53 # 640x480 @ 72Hz (VESA) hsync: 37.9kHz
54 ModeLine "640x480" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync
55 # 640x480 @ 75Hz (VESA) hsync: 37.5kHz
56 ModeLine "640x480" 31.5 640 656 720 840 480 481 484 500 -hsync -vsync
57 # 640x480 @ 85Hz (VESA) hsync: 43.3kHz
58 ModeLine "640x480" 36.0 640 696 752 832 480 481 484 509 -hsync -vsync
59EndSection
60
61Section "Screen"
62 Identifier "Default Screen"
63 Device "Graphics Controller"
64 Monitor "Generic Monitor"
65 SubSection "Display"
66 Modes "640x480"
67 EndSubSection
68EndSection
69
70Section "ServerLayout"
71 Identifier "Default Layout"
72 Screen "Default Screen"
73 InputDevice "Generic Keyboard"
74 # InputDevice "Configured Mouse"
75 InputDevice "QEMU Tablet"
76 Option "AllowEmptyInput" "no"
77EndSection
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000000..72d991c7e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..af34437d0a
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH {{=qemuarch}}
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..0e20023764
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,16 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH {{=qemuarch}}
4
5{{ if qemuarch == "i386" or qemuarch == "x86_64": }}
6include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
7{{ if qemuarch == "arm": }}
8include bsp/arm-versatile-926ejs/arm-versatile-926ejs-standard
9{{ if qemuarch == "powerpc": }}
10include bsp/qemu-ppc32/qemu-ppc32-standard
11{{ if qemuarch == "mips": }}
12include bsp/mti-malta32/mti-malta32-be-standard
13{{ if need_new_kbranch == "y": }}
14branch {{=machine}}
15
16include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..10c4dac44d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH {{=qemuarch}}
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..f3739be1e6
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,4 @@
1kconf hardware {{=machine}}.cfg
2
3kconf hardware {{=machine}}-user-config.cfg
4include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..7599ecb0a5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,49 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base your new BSP branch on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose an existing machine branch to use for this BSP:" default:"standard/arm-versatile-926ejs" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/qemuppc" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/mti-malta32" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-standard.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..73b6e34839
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,55 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/qemuppc" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-preempt-rt.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
50
51# uncomment and replace these SRCREVs with the real commit ids once you've had
52# the appropriate changes committed to the upstream linux-yocto repo
53#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
54#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
55#LINUX_VERSION = "3.10.35"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..da4e61ef83
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,55 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/common-pc" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-tiny.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
50
51# uncomment and replace these SRCREVs with the real commit ids once you've had
52# the appropriate changes committed to the upstream linux-yocto repo
53#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
54#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
55#LINUX_VERSION = "3.10.35"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.4.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.4.bbappend
new file mode 100644
index 0000000000..013883ffeb
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.4.bbappend
@@ -0,0 +1,55 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"arm" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/common-pc" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-tiny.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
50
51# uncomment and replace these SRCREVs with the real commit ids once you've had
52# the appropriate changes committed to the upstream linux-yocto repo
53#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "0143c6ebb4a2d63b241df5f608b19f483f7eb9e0"
54#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "8f55bee2403176a50cc0dd41811aa60fcf07243c"
55#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..392ace6694
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,55 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base your new BSP branch on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose an existing machine branch to use for this BSP:" default:"standard/arm-versatile-926ejs" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/qemuppc" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/mti-malta32" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-standard.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
50
51# uncomment and replace these SRCREVs with the real commit ids once you've had
52# the appropriate changes committed to the upstream linux-yocto repo
53#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "b170394a475b96ecc92cbc9e4b002bed0a9f69c5"
54#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "c2ed0f16fdec628242a682897d5d86df4547cf24"
55#LINUX_VERSION = "3.10.35"
diff --git a/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..2cc9b87cf2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,55 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y" and qemuarch == "arm": }}
9{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base your new BSP branch on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n" and qemuarch == "arm": }}
12{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose an existing machine branch to use for this BSP:" default:"standard/arm-versatile-926ejs" }}
13
14{{ if need_new_kbranch == "y" and qemuarch == "powerpc": }}
15{{ input type:"choicelist" name:"new_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
16
17{{ if need_new_kbranch == "n" and qemuarch == "powerpc": }}
18{{ input type:"choicelist" name:"existing_kbranch" nameappend:"powerpc" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/qemuppc" }}
19
20{{ if need_new_kbranch == "y" and qemuarch == "i386": }}
21{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
22
23{{ if need_new_kbranch == "n" and qemuarch == "i386": }}
24{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc/base" }}
25
26{{ if need_new_kbranch == "y" and qemuarch == "x86_64": }}
27{{ input type:"choicelist" name:"new_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
28
29{{ if need_new_kbranch == "n" and qemuarch == "x86_64": }}
30{{ input type:"choicelist" name:"existing_kbranch" nameappend:"x86_64" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
31
32{{ if need_new_kbranch == "y" and qemuarch == "mips": }}
33{{ input type:"choicelist" name:"new_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
34
35{{ if need_new_kbranch == "n" and qemuarch == "mips": }}
36{{ input type:"choicelist" name:"existing_kbranch" nameappend:"mips" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/mti-malta32" }}
37
38{{ if need_new_kbranch == "n": }}
39KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
40
41{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
42{{ if smp == "y": }}
43KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
44
45SRC_URI += "file://{{=machine}}-standard.scc \
46 file://{{=machine}}-user-config.cfg \
47 file://{{=machine}}-user-patches.scc \
48 file://{{=machine}}-user-features.scc \
49 "
50
51# uncomment and replace these SRCREVs with the real commit ids once you've had
52# the appropriate changes committed to the upstream linux-yocto repo
53#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "0143c6ebb4a2d63b241df5f608b19f483f7eb9e0"
54#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "8f55bee2403176a50cc0dd41811aa60fcf07243c"
55#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/conf/machine/{{=machine}}.conf b/scripts/lib/bsp/substrate/target/arch/x86_64/conf/machine/{{=machine}}.conf
new file mode 100644
index 0000000000..53e8e92e6d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/conf/machine/{{=machine}}.conf
@@ -0,0 +1,58 @@
1#@TYPE: Machine
2#@NAME: {{=machine}}
3
4#@DESCRIPTION: Machine configuration for {{=machine}} systems
5
6{{ if kernel_choice == "custom": preferred_kernel = "linux-yocto-custom" }}
7{{ if kernel_choice == "linux-yocto-dev": preferred_kernel = "linux-yocto-dev" }}
8{{ if kernel_choice == "custom" or kernel_choice == "linux-yocto-dev" : }}
9PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
10
11{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel = kernel_choice.split('_')[0] }}
12{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": preferred_kernel_version = kernel_choice.split('_')[1] }}
13{{ if kernel_choice != "custom" and kernel_choice != "linux-yocto-dev": }}
14PREFERRED_PROVIDER_virtual/kernel ?= "{{=preferred_kernel}}"
15PREFERRED_VERSION_{{=preferred_kernel}} ?= "{{=preferred_kernel_version}}%"
16
17{{ input type:"choicelist" name:"tunefile" prio:"40" msg:"Which machine tuning would you like to use?" default:"tune_core2" }}
18{{ input type:"choice" val:"tune_core2" msg:"Core2 tuning optimizations" }}
19{{ input type:"choice" val:"tune_corei7" msg:"Corei7 tuning optimizations" }}
20{{ if tunefile == "tune_core2": }}
21DEFAULTTUNE ?= "core2-64"
22require conf/machine/include/tune-core2.inc
23{{ if tunefile == "tune_corei7": }}
24DEFAULTTUNE ?= "corei7-64"
25require conf/machine/include/tune-corei7.inc
26
27require conf/machine/include/x86-base.inc
28
29MACHINE_FEATURES += "wifi efi pcbios"
30
31{{ input type:"boolean" name:"xserver" prio:"50" msg:"Do you need support for X? (y/n)" default:"y" }}
32
33{{ if xserver == "y": }}
34{{ input type:"choicelist" name:"xserver_choice" prio:"50" msg:"Please select an xserver for this machine:" default:"xserver_i915" }}
35
36{{ input type:"choice" val:"xserver_vesa" msg:"VESA xserver support" }}
37{{ input type:"choice" val:"xserver_i915" msg:"i915 xserver support" }}
38{{ input type:"choice" val:"xserver_i965" msg:"i965 xserver support" }}
39{{ if xserver == "y": }}
40XSERVER ?= "${XSERVER_X86_BASE} \
41 ${XSERVER_X86_EXT} \
42{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
43 ${XSERVER_X86_VESA} \
44{{ if xserver == "y" and xserver_choice == "xserver_i915": }}
45 ${XSERVER_X86_I915} \
46{{ if xserver == "y" and xserver_choice == "xserver_i965": }}
47 ${XSERVER_X86_I965} \
48{{ if xserver == "y": }}
49 "
50
51MACHINE_EXTRA_RRECOMMENDS += "linux-firmware v86d"
52
53GLIBC_ADDONS = "nptl"
54
55EXTRA_OECONF_append_pn-matchbox-panel-2 = " --with-battery=acpi"
56
57{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
58APPEND += "video=vesafb vga=0x318"
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/xserver-xf86-config/{{=machine}}/{{ if xserver == "y": }} xorg.conf
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000000..72d991c7e5
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-graphics/xorg-xserver/{{ if xserver == "y": }} xserver-xf86-config_0.1.bbappend
@@ -0,0 +1 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/kernel-list.noinstall b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/kernel-list.noinstall
new file mode 100644
index 0000000000..a04e6c7852
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/kernel-list.noinstall
@@ -0,0 +1,5 @@
1{{ if kernel_choice != "custom": }}
2{{ input type:"boolean" name:"use_default_kernel" prio:"10" msg:"Would you like to use the default (3.14) kernel? (y/n)" default:"y"}}
3
4{{ if kernel_choice != "custom" and use_default_kernel == "n": }}
5{{ input type:"choicelist" name:"kernel_choice" gen:"bsp.kernel.kernels" prio:"10" msg:"Please choose the kernel to use in this BSP:" default:"linux-yocto_3.14"}}
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
new file mode 100644
index 0000000000..c9882590a8
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-preempt-rt.scc
@@ -0,0 +1,15 @@
1define KMACHINE {{=machine}}
2define KTYPE preempt-rt
3define KARCH x86_64
4
5include {{=map_preempt_rt_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for preempt-rt kernels
12include cfg/usb-mass-storage.scc
13include cfg/boot-live.scc
14include features/latencytop/latencytop.scc
15include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
new file mode 100644
index 0000000000..e500bad4b2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-standard.scc
@@ -0,0 +1,15 @@
1define KMACHINE {{=machine}}
2define KTYPE standard
3define KARCH x86_64
4
5include {{=map_standard_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
10
11# default policy for standard kernels
12include cfg/usb-mass-storage.scc
13include cfg/boot-live.scc
14include features/latencytop/latencytop.scc
15include features/profiling/profiling.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
new file mode 100644
index 0000000000..e8e3c1c04d
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-tiny.scc
@@ -0,0 +1,9 @@
1define KMACHINE {{=machine}}
2define KTYPE tiny
3define KARCH x86_64
4
5include {{=map_tiny_kbranch(need_new_kbranch, new_kbranch, existing_kbranch)}}
6{{ if need_new_kbranch == "y": }}
7branch {{=machine}}
8
9include {{=machine}}.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-config.cfg
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-features.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
new file mode 100644
index 0000000000..b4b82d7ca0
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.cfg
@@ -0,0 +1,47 @@
1CONFIG_PRINTK=y
2
3# Basic hardware support for the box - network, USB, PCI, sound
4CONFIG_NETDEVICES=y
5CONFIG_ATA=y
6CONFIG_ATA_GENERIC=y
7CONFIG_ATA_SFF=y
8CONFIG_PCI=y
9CONFIG_MMC=y
10CONFIG_MMC_SDHCI=y
11CONFIG_USB_SUPPORT=y
12CONFIG_USB=y
13CONFIG_USB_ARCH_HAS_EHCI=y
14CONFIG_R8169=y
15CONFIG_PATA_SCH=y
16CONFIG_MMC_SDHCI_PCI=y
17CONFIG_USB_EHCI_HCD=y
18CONFIG_PCIEPORTBUS=y
19CONFIG_NET=y
20CONFIG_USB_UHCI_HCD=y
21CONFIG_BLK_DEV_SD=y
22CONFIG_CHR_DEV_SG=y
23CONFIG_SOUND=y
24CONFIG_SND=y
25CONFIG_SND_HDA_INTEL=y
26
27# Make sure these are on, otherwise the bootup won't be fun
28CONFIG_EXT3_FS=y
29CONFIG_UNIX=y
30CONFIG_INET=y
31CONFIG_MODULES=y
32CONFIG_SHMEM=y
33CONFIG_TMPFS=y
34CONFIG_PACKET=y
35
36CONFIG_I2C=y
37CONFIG_AGP=y
38CONFIG_PM=y
39CONFIG_ACPI=y
40CONFIG_INPUT=y
41
42# Needed for booting (and using) USB memory sticks
43CONFIG_BLK_DEV_LOOP=y
44CONFIG_NLS_CODEPAGE_437=y
45CONFIG_NLS_ISO8859_1=y
46
47CONFIG_RD_GZIP=y
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
new file mode 100644
index 0000000000..db45140381
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice != "custom": }} files/{{=machine}}.scc
@@ -0,0 +1,13 @@
1kconf hardware {{=machine}}.cfg
2
3include features/serial/8250.scc
4{{ if xserver == "y" and xserver_choice == "xserver_vesa": }}
5include cfg/vesafb.scc
6{{ if xserver == "y" and xserver_choice == "xserver_i915" or xserver_choice == "xserver_i965": }}
7include features/i915/i915.scc
8
9include cfg/usb-mass-storage.scc
10include features/power/intel.scc
11
12kconf hardware {{=machine}}-user-config.cfg
13include {{=machine}}-user-patches.scc
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
new file mode 100644
index 0000000000..25c87a85ac
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-dev": }} linux-yocto-dev.bbappend
@@ -0,0 +1,25 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
7
8{{ if need_new_kbranch == "y": }}
9{{ input type:"choicelist" name:"new_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
10
11{{ if need_new_kbranch == "n": }}
12{{ input type:"choicelist" name:"existing_kbranch" nameappend:"i386" gen:"bsp.kernel.all_branches" branches_base:"standard" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/base" }}
13
14{{ if need_new_kbranch == "n": }}
15KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
16
17{{ input type:"boolean" name:"smp" prio:"30" msg:"Would you like SMP support? (y/n)" default:"y"}}
18{{ if smp == "y": }}
19KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
20
21SRC_URI += "file://{{=machine}}-standard.scc \
22 file://{{=machine}}-user-config.cfg \
23 file://{{=machine}}-user-patches.scc \
24 file://{{=machine}}-user-features.scc \
25 "
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
new file mode 100644
index 0000000000..00c8c68933
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-rt_3.10": }} linux-yocto-rt_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/preempt-rt" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/preempt-rt/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-preempt-rt.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-rt_{{=machine}} ?= "f35992f80c81dc5fa1a97165dfd5cbb84661f7cb"
31#SRCREV_meta_pn-linux-yocto-rt_{{=machine}} ?= "1b534b2f8bbe9b8a773268cfa30a4850346f6f5f"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
new file mode 100644
index 0000000000..bc6968d832
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.10": }} linux-yocto-tiny_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.10.9"
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
new file mode 100644
index 0000000000..d221d5f2a4
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto-tiny_3.14": }} linux-yocto-tiny_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard/tiny" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/tiny/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-tiny.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto-tiny_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto-tiny_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
new file mode 100644
index 0000000000..162348114f
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.10": }} linux-yocto_3.10.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "b170394a475b96ecc92cbc9e4b002bed0a9f69c5"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "c2ed0f16fdec628242a682897d5d86df4547cf24"
32#LINUX_VERSION = "3.10.9" \ No newline at end of file
diff --git a/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
new file mode 100644
index 0000000000..81e528bc33
--- /dev/null
+++ b/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel/linux/{{ if kernel_choice == "linux-yocto_3.14": }} linux-yocto_3.14.bbappend
@@ -0,0 +1,32 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
2
3PR := "${PR}.1"
4
5COMPATIBLE_MACHINE_{{=machine}} = "{{=machine}}"
6
7{{ input type:"boolean" name:"need_new_kbranch" prio:"20" msg:"Do you need a new machine branch for this BSP (the alternative is to re-use an existing branch)? [y/n]" default:"y" }}
8
9{{ if need_new_kbranch == "y": }}
10{{ input type:"choicelist" name:"new_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
11
12{{ if need_new_kbranch == "n": }}
13{{ input type:"choicelist" name:"existing_kbranch" gen:"bsp.kernel.all_branches" branches_base:"standard:standard/common-pc-64" prio:"20" msg:"Please choose a machine branch to base this BSP on:" default:"standard/common-pc-64/base" }}
14
15{{ if need_new_kbranch == "n": }}
16KBRANCH_{{=machine}} = "{{=existing_kbranch}}"
17
18{{ input type:"boolean" name:"smp" prio:"30" msg:"Do you need SMP support? (y/n)" default:"y"}}
19{{ if smp == "y": }}
20KERNEL_FEATURES_append_{{=machine}} += " cfg/smp.scc"
21
22SRC_URI += "file://{{=machine}}-standard.scc \
23 file://{{=machine}}-user-config.cfg \
24 file://{{=machine}}-user-patches.scc \
25 file://{{=machine}}-user-features.scc \
26 "
27
28# uncomment and replace these SRCREVs with the real commit ids once you've had
29# the appropriate changes committed to the upstream linux-yocto repo
30#SRCREV_machine_pn-linux-yocto_{{=machine}} ?= "840bb8c059418c4753415df56c9aff1c0d5354c8"
31#SRCREV_meta_pn-linux-yocto_{{=machine}} ?= "4fd76cc4f33e0afd8f906b1e8f231b6d13b6c993"
32#LINUX_VERSION = "3.14"
diff --git a/scripts/lib/bsp/tags.py b/scripts/lib/bsp/tags.py
new file mode 100644
index 0000000000..6d5feb0a59
--- /dev/null
+++ b/scripts/lib/bsp/tags.py
@@ -0,0 +1,47 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2012, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module provides a place to define common constants for the
22# Yocto BSP Tools.
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] intel.com>
26#
27
28OPEN_TAG = "{{"
29CLOSE_TAG = "}}"
30ASSIGN_TAG = "{{="
31INPUT_TAG = "input"
32IF_TAG = "if"
33
34INDENT_STR = " "
35
36BLANKLINE_STR = "of.write(\"\\n\")"
37NORMAL_START = "of.write"
38OPEN_START = "current_file ="
39
40INPUT_TYPE_PROPERTY = "type"
41
42SRC_URI_FILE = "file://"
43
44GIT_CHECK_URI = "git://git.yoctoproject.org/linux-yocto-dev.git"
45
46
47
diff --git a/scripts/lib/image/__init__.py b/scripts/lib/image/__init__.py
new file mode 100644
index 0000000000..1ff814e761
--- /dev/null
+++ b/scripts/lib/image/__init__.py
@@ -0,0 +1,22 @@
1#
2# OpenEmbedded Image tools library
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# AUTHORS
21# Tom Zanussi <tom.zanussi (at] linux.intel.com>
22#
diff --git a/scripts/lib/image/canned-wks/directdisk.wks b/scripts/lib/image/canned-wks/directdisk.wks
new file mode 100644
index 0000000000..397a929c74
--- /dev/null
+++ b/scripts/lib/image/canned-wks/directdisk.wks
@@ -0,0 +1,10 @@
1# short-description: Create a 'pcbios' direct disk image
2# long-description: Creates a partitioned legacy BIOS disk image that the user
3# can directly dd to boot media.
4
5
6part /boot --source bootimg-pcbios --ondisk sda --fstype=msdos --label boot --active --align 1024
7part / --source rootfs --ondisk sda --fstype=ext3 --label platform --align 1024
8
9bootloader --timeout=0 --append="rootwait rootfstype=ext3 video=vesafb vga=0x318 console=tty0"
10
diff --git a/scripts/lib/image/canned-wks/mkefidisk.wks b/scripts/lib/image/canned-wks/mkefidisk.wks
new file mode 100644
index 0000000000..e976bc80dd
--- /dev/null
+++ b/scripts/lib/image/canned-wks/mkefidisk.wks
@@ -0,0 +1,11 @@
1# short-description: Create an EFI disk image
2# long-description: Creates a partitioned EFI disk image that the user
3# can directly dd to boot media.
4
5part /boot --source bootimg-efi --ondisk sda --fstype=msdos --label msdos --active --align 1024
6
7part / --source rootfs --ondisk sda --fstype=ext3 --label platform --align 1024
8
9part swap --ondisk sda --size 44 --label swap1 --fstype=swap
10
11bootloader --timeout=10 --append="rootwait rootfstype=ext3 console=ttyPCH0,115200 console=tty0 vmalloc=256MB snd-hda-intel.enable_msi=0"
diff --git a/scripts/lib/image/canned-wks/uboot.wks b/scripts/lib/image/canned-wks/uboot.wks
new file mode 100644
index 0000000000..7de0572d0f
--- /dev/null
+++ b/scripts/lib/image/canned-wks/uboot.wks
@@ -0,0 +1,17 @@
1# short-description: . Create a ramdisk image for U-Boot
2# long-description: Creates a ramdisk image for U-Boot that user
3# can directly load it into ram through tftp
4#
5# part - is a wic command that drive the process of generating a valid file system
6# - --source=uboot : wic plugin that generates a ramdisk image for U-Boot
7# - --fstype=ext2 : file system type( ext2 / ext3 / ext 4)
8#
9# %packages %end - option to provide a list of packages that will be installed
10# into rootfs. All packages dependencies will be installed by
11# package manager(default opkg).
12
13
14part / --source=uboot --fstype=ext2 --label imageName --align 1024
15
16%packages
17%end
diff --git a/scripts/lib/image/config/wic.conf b/scripts/lib/image/config/wic.conf
new file mode 100644
index 0000000000..2a2750b4ee
--- /dev/null
+++ b/scripts/lib/image/config/wic.conf
@@ -0,0 +1,11 @@
1[common]
2; general settings
3distro_name = OpenEmbedded
4
5[create]
6; settings for create subcommand
7; repourl=http://linux.com/ipk/all http://linux.com/ipk/target http://linux.com/ipk/arch
8arch=powerpc
9pkgmgr=opkg
10runtime=native
11install_pkgs=source
diff --git a/scripts/lib/image/engine.py b/scripts/lib/image/engine.py
new file mode 100644
index 0000000000..0643780f1a
--- /dev/null
+++ b/scripts/lib/image/engine.py
@@ -0,0 +1,287 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21
22# This module implements the image creation engine used by 'wic' to
23# create images. The engine parses through the OpenEmbedded kickstart
24# (wks) file specified and generates images that can then be directly
25# written onto media.
26#
27# AUTHORS
28# Tom Zanussi <tom.zanussi (at] linux.intel.com>
29#
30
31import os
32import sys
33from abc import ABCMeta, abstractmethod
34import shlex
35import json
36import subprocess
37import shutil
38
39import os, sys, errno
40from mic import msger, creator
41from mic.utils import cmdln, misc, errors
42from mic.conf import configmgr
43from mic.plugin import pluginmgr
44from mic.__version__ import VERSION
45from mic.utils.oe.misc import *
46
47
48def verify_build_env():
49 """
50 Verify that the build environment is sane.
51
52 Returns True if it is, false otherwise
53 """
54 try:
55 builddir = os.environ["BUILDDIR"]
56 except KeyError:
57 print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
58 sys.exit(1)
59
60 return True
61
62
63def find_bitbake_env_lines(image_name):
64 """
65 If image_name is empty, plugins might still be able to use the
66 environment, so set it regardless.
67 """
68 if image_name:
69 bitbake_env_cmd = "bitbake -e %s" % image_name
70 else:
71 bitbake_env_cmd = "bitbake -e"
72 rc, bitbake_env_lines = exec_cmd(bitbake_env_cmd)
73 if rc != 0:
74 print "Couldn't get '%s' output." % bitbake_env_cmd
75 return None
76
77 return bitbake_env_lines
78
79
80def find_artifacts(image_name):
81 """
82 Gather the build artifacts for the current image (the image_name
83 e.g. core-image-minimal) for the current MACHINE set in local.conf
84 """
85 bitbake_env_lines = get_bitbake_env_lines()
86
87 rootfs_dir = kernel_dir = hdddir = staging_data_dir = native_sysroot = ""
88
89 for line in bitbake_env_lines.split('\n'):
90 if (get_line_val(line, "IMAGE_ROOTFS")):
91 rootfs_dir = get_line_val(line, "IMAGE_ROOTFS")
92 continue
93 if (get_line_val(line, "STAGING_KERNEL_DIR")):
94 kernel_dir = get_line_val(line, "STAGING_KERNEL_DIR")
95 continue
96 if (get_line_val(line, "HDDDIR")):
97 hdddir = get_line_val(line, "HDDDIR")
98 continue
99 if (get_line_val(line, "STAGING_DATADIR")):
100 staging_data_dir = get_line_val(line, "STAGING_DATADIR")
101 continue
102 if (get_line_val(line, "STAGING_DIR_NATIVE")):
103 native_sysroot = get_line_val(line, "STAGING_DIR_NATIVE")
104 continue
105
106 return (rootfs_dir, kernel_dir, hdddir, staging_data_dir, native_sysroot)
107
108
109CANNED_IMAGE_DIR = "lib/image/canned-wks" # relative to scripts
110
111def find_canned_image(scripts_path, wks_file):
112 """
113 Find a .wks file with the given name in the canned files dir.
114
115 Return False if not found
116 """
117 canned_wks_dir = os.path.join(scripts_path, CANNED_IMAGE_DIR)
118
119 for root, dirs, files in os.walk(canned_wks_dir):
120 for file in files:
121 if file.endswith("~") or file.endswith("#"):
122 continue
123 if file.endswith(".wks") and wks_file + ".wks" == file:
124 fullpath = os.path.join(canned_wks_dir, file)
125 return fullpath
126 return None
127
128
129def list_canned_images(scripts_path):
130 """
131 List the .wks files in the canned image dir, minus the extension.
132 """
133 canned_wks_dir = os.path.join(scripts_path, CANNED_IMAGE_DIR)
134
135 for root, dirs, files in os.walk(canned_wks_dir):
136 for file in files:
137 if file.endswith("~") or file.endswith("#"):
138 continue
139 if file.endswith(".wks"):
140 fullpath = os.path.join(canned_wks_dir, file)
141 f = open(fullpath, "r")
142 lines = f.readlines()
143 for line in lines:
144 desc = ""
145 idx = line.find("short-description:")
146 if idx != -1:
147 desc = line[idx + len("short-description:"):].strip()
148 break
149 basename = os.path.splitext(file)[0]
150 print " %s\t\t%s" % (basename, desc)
151
152
153def list_canned_image_help(scripts_path, fullpath):
154 """
155 List the help and params in the specified canned image.
156 """
157 canned_wks_dir = os.path.join(scripts_path, CANNED_IMAGE_DIR)
158
159 f = open(fullpath, "r")
160 lines = f.readlines()
161 found = False
162 for line in lines:
163 if not found:
164 idx = line.find("long-description:")
165 if idx != -1:
166 print
167 print line[idx + len("long-description:"):].strip()
168 found = True
169 continue
170 if not line.strip():
171 break
172 idx = line.find("#")
173 if idx != -1:
174 print line[idx + len("#:"):].rstrip()
175 else:
176 break
177
178
179def wic_create(args, wks_file, rootfs_dir, bootimg_dir, kernel_dir,
180 native_sysroot, hdddir, staging_data_dir, scripts_path,
181 image_output_dir, debug, properties_file, properties=None):
182 """
183 Create image
184
185 wks_file - user-defined OE kickstart file
186 rootfs_dir - absolute path to the build's /rootfs dir
187 bootimg_dir - absolute path to the build's boot artifacts directory
188 kernel_dir - absolute path to the build's kernel directory
189 native_sysroot - absolute path to the build's native sysroots dir
190 hdddir - absolute path to the build's HDDDIR dir
191 staging_data_dir - absolute path to the build's STAGING_DATA_DIR dir
192 scripts_path - absolute path to /scripts dir
193 image_output_dir - dirname to create for image
194 properties_file - use values from this file if nonempty i.e no prompting
195 properties - use values from this string if nonempty i.e no prompting
196
197 Normally, the values for the build artifacts values are determined
198 by 'wic -e' from the output of the 'bitbake -e' command given an
199 image name e.g. 'core-image-minimal' and a given machine set in
200 local.conf. If that's the case, the variables get the following
201 values from the output of 'bitbake -e':
202
203 rootfs_dir: IMAGE_ROOTFS
204 kernel_dir: STAGING_KERNEL_DIR
205 native_sysroot: STAGING_DIR_NATIVE
206 hdddir: HDDDIR
207 staging_data_dir: STAGING_DATA_DIR
208
209 In the above case, bootimg_dir remains unset and the image
210 creation code determines which of the passed-in directories to
211 use.
212
213 In the case where the values are passed in explicitly i.e 'wic -e'
214 is not used but rather the individual 'wic' options are used to
215 explicitly specify these values, hdddir and staging_data_dir will
216 be unset, but bootimg_dir must be explicit i.e. explicitly set to
217 either hdddir or staging_data_dir, depending on the image being
218 generated. The other values (rootfs_dir, kernel_dir, and
219 native_sysroot) correspond to the same values found above via
220 'bitbake -e').
221
222 """
223 try:
224 oe_builddir = os.environ["BUILDDIR"]
225 except KeyError:
226 print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
227 sys.exit(1)
228
229 direct_args = list()
230 direct_args.insert(0, oe_builddir)
231 direct_args.insert(0, image_output_dir)
232 direct_args.insert(0, wks_file)
233 direct_args.insert(0, rootfs_dir)
234 direct_args.insert(0, bootimg_dir)
235 direct_args.insert(0, kernel_dir)
236 direct_args.insert(0, native_sysroot)
237 direct_args.insert(0, hdddir)
238 direct_args.insert(0, staging_data_dir)
239 direct_args.insert(0, "direct")
240
241 if debug:
242 msger.set_loglevel('debug')
243
244 cr = creator.Creator()
245
246 cr.main(direct_args)
247
248 print "\nThe image(s) were created using OE kickstart file:\n %s" % wks_file
249
250
251def wic_list(args, scripts_path, properties_file):
252 """
253 Print the complete list of properties defined by the image, or the
254 possible values for a particular image property.
255 """
256 if len(args) < 1:
257 return False
258
259 if len(args) == 1:
260 if args[0] == "images":
261 list_canned_images(scripts_path)
262 return True
263 elif args[0] == "properties":
264 return True
265 else:
266 return False
267
268 if len(args) == 2:
269 if args[0] == "properties":
270 wks_file = args[1]
271 print "print properties contained in wks file: %s" % wks_file
272 return True
273 elif args[0] == "property":
274 print "print property values for property: %s" % args[1]
275 return True
276 elif args[1] == "help":
277 wks_file = args[0]
278 fullpath = find_canned_image(scripts_path, wks_file)
279 if not fullpath:
280 print "No image named %s found, exiting. (Use 'wic list images' to list available images, or specify a fully-qualified OE kickstart (.wks) filename)\n" % wks_file
281 sys.exit(1)
282 list_canned_image_help(scripts_path, fullpath)
283 return True
284 else:
285 return False
286
287 return False
diff --git a/scripts/lib/image/help.py b/scripts/lib/image/help.py
new file mode 100644
index 0000000000..cb3112cf08
--- /dev/null
+++ b/scripts/lib/image/help.py
@@ -0,0 +1,311 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module implements some basic help invocation functions along
22# with the bulk of the help topic text for the OE Core Image Tools.
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] linux.intel.com>
26#
27
28import subprocess
29import logging
30
31
32def subcommand_error(args):
33 logging.info("invalid subcommand %s" % args[0])
34
35
36def display_help(subcommand, subcommands):
37 """
38 Display help for subcommand.
39 """
40 if subcommand not in subcommands:
41 return False
42
43 help = subcommands.get(subcommand, subcommand_error)[2]
44 pager = subprocess.Popen('less', stdin=subprocess.PIPE)
45 pager.communicate(help)
46
47 return True
48
49
50def wic_help(args, usage_str, subcommands):
51 """
52 Subcommand help dispatcher.
53 """
54 if len(args) == 1 or not display_help(args[1], subcommands):
55 print(usage_str)
56
57
58def invoke_subcommand(args, parser, main_command_usage, subcommands):
59 """
60 Dispatch to subcommand handler borrowed from combo-layer.
61 Should use argparse, but has to work in 2.6.
62 """
63 if not args:
64 logging.error("No subcommand specified, exiting")
65 parser.print_help()
66 elif args[0] == "help":
67 wic_help(args, main_command_usage, subcommands)
68 elif args[0] not in subcommands:
69 logging.error("Unsupported subcommand %s, exiting\n" % (args[0]))
70 parser.print_help()
71 else:
72 usage = subcommands.get(args[0], subcommand_error)[1]
73 subcommands.get(args[0], subcommand_error)[0](args[1:], usage)
74
75
76##
77# wic help and usage strings
78##
79
80wic_usage = """
81
82 Create a customized OpenEmbedded image
83
84 usage: wic [--version] [--help] COMMAND [ARGS]
85
86 Current 'wic' commands are:
87 create Create a new OpenEmbedded image
88 list List available values for options and image properties
89
90 See 'wic help COMMAND' for more information on a specific command.
91"""
92
93wic_help_usage = """
94
95 usage: wic help <subcommand>
96
97 This command displays detailed help for the specified subcommand.
98"""
99
100wic_create_usage = """
101
102 Create a new OpenEmbedded image
103
104 usage: wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>]
105 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
106 [-e | --image-name] [-r, --rootfs-dir] [-b, --bootimg-dir]
107 [-k, --kernel-dir] [-n, --native-sysroot] [-s, --skip-build-check]
108
109 This command creates an OpenEmbedded image based on the 'OE kickstart
110 commands' found in the <wks file>.
111
112 The -o option can be used to place the image in a directory with a
113 different name and location.
114
115 See 'wic help create' for more detailed instructions.
116"""
117
118wic_create_help = """
119
120NAME
121 wic create - Create a new OpenEmbedded image
122
123SYNOPSIS
124 wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>]
125 [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
126 [-e | --image-name] [-r, --rootfs-dir] [-b, --bootimg-dir]
127 [-k, --kernel-dir] [-n, --native-sysroot] [-s, --skip-build-check]
128
129DESCRIPTION
130 This command creates an OpenEmbedded image based on the 'OE
131 kickstart commands' found in the <wks file>.
132
133 In order to do this, wic needs to know the locations of the
134 various build artifacts required to build the image.
135
136 Users can explicitly specify the build artifact locations using
137 the -r, -b, -k, and -n options. See below for details on where
138 the corresponding artifacts are typically found in a normal
139 OpenEmbedded build.
140
141 Alternatively, users can use the -e option to have 'mic' determine
142 those locations for a given image. If the -e option is used, the
143 user needs to have set the appropriate MACHINE variable in
144 local.conf, and have sourced the build environment.
145
146 The -e option is used to specify the name of the image to use the
147 artifacts from e.g. core-image-sato.
148
149 The -r option is used to specify the path to the /rootfs dir to
150 use as the .wks rootfs source.
151
152 The -b option is used to specify the path to the dir containing
153 the boot artifacts (e.g. /EFI or /syslinux dirs) to use as the
154 .wks bootimg source.
155
156 The -k option is used to specify the path to the dir containing
157 the kernel to use in the .wks bootimg.
158
159 The -n option is used to specify the path to the native sysroot
160 containing the tools to use to build the image.
161
162 The -s option is used to skip the build check. The build check is
163 a simple sanity check used to determine whether the user has
164 sourced the build environment so that the -e option can operate
165 correctly. If the user has specified the build artifact locations
166 explicitly, 'wic' assumes the user knows what he or she is doing
167 and skips the build check.
168
169 When 'wic -e' is used, the locations for the build artifacts
170 values are determined by 'wic -e' from the output of the 'bitbake
171 -e' command given an image name e.g. 'core-image-minimal' and a
172 given machine set in local.conf. In that case, the image is
173 created as if the following 'bitbake -e' variables were used:
174
175 -r: IMAGE_ROOTFS
176 -k: STAGING_KERNEL_DIR
177 -n: STAGING_DIR_NATIVE
178 -b: HDDDIR and STAGING_DATA_DIR (handlers decide which to use)
179
180 If 'wic -e' is not used, the user needs to select the appropriate
181 value for -b (as well as -r, -k, and -n).
182
183 The -o option can be used to place the image in a directory with a
184 different name and location.
185
186 As an alternative to the wks file, the image-specific properties
187 that define the values that will be used to generate a particular
188 image can be specified on the command-line using the -i option and
189 supplying a JSON object consisting of the set of name:value pairs
190 needed by image creation.
191
192 The set of properties available for a given image type can be
193 listed using the 'wic list' command.
194"""
195
196wic_list_usage = """
197
198 List available OpenEmbedded image properties and values
199
200 usage: wic list images
201 wic list <image> help
202 wic list properties
203 wic list properties <wks file>
204 wic list property <property>
205 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
206
207 This command enumerates the set of available canned images as well as
208 help for those images. It also can be used to enumerate the complete
209 set of possible values for a specified option or property needed by
210 the image creation process.
211
212 The first form enumerates all the available 'canned' images.
213
214 The second form lists the detailed help information for a specific
215 'canned' image.
216
217 The third form enumerates all the possible values that exist and can
218 be specified in an OE kickstart (wks) file.
219
220 The fourth form enumerates all the possible options that exist for
221 the set of properties specified in a given OE kickstart (ks) file.
222
223 The final form enumerates all the possible values that exist and can
224 be specified for any given OE kickstart (wks) property.
225
226 See 'wic help list' for more details.
227"""
228
229wic_list_help = """
230
231NAME
232 wic list - List available OpenEmbedded image properties and values
233
234SYNOPSIS
235 wic list images
236 wic list <image> help
237 wic list properties
238 wic list properties <wks file>
239 wic list property <property>
240 [-o <JSON PROPERTY FILE> | --outfile <JSON PROPERTY_FILE>]
241
242DESCRIPTION
243 This command enumerates the complete set of possible values for a
244 specified option or property needed by the image creation process.
245
246 This command enumerates the set of available canned images as well
247 as help for those images. It also can be used to enumerate the
248 complete set of possible values for a specified option or property
249 needed by the image creation process.
250
251 The first form enumerates all the available 'canned' images.
252 These are actually just the set of .wks files that have been moved
253 into the /scripts/lib/image/canned-wks directory).
254
255 The second form lists the detailed help information for a specific
256 'canned' image.
257
258 The third form enumerates all the possible values that exist and
259 can be specified in a OE kickstart (wks) file. The output of this
260 can be used by the third form to print the description and
261 possible values of a specific property.
262
263 The fourth form enumerates all the possible options that exist for
264 the set of properties specified in a given OE kickstart (wks)
265 file. If the -o option is specified, the list of properties, in
266 addition to being displayed, will be written to the specified file
267 as a JSON object. In this case, the object will consist of the
268 set of name:value pairs corresponding to the (possibly nested)
269 dictionary of properties defined by the input statements used by
270 the image. Some example output for the 'list <wks file>' command:
271
272 $ wic list test.ks
273 "part" : {
274 "mountpoint" : "/"
275 "fstype" : "ext3"
276 }
277 "part" : {
278 "mountpoint" : "/home"
279 "fstype" : "ext3"
280 "offset" : "10000"
281 }
282 "bootloader" : {
283 "type" : "efi"
284 }
285 .
286 .
287 .
288
289 Each entry in the output consists of the name of the input element
290 e.g. "part", followed by the properties defined for that
291 element enclosed in braces. This information should provide
292 sufficient information to create a complete user interface with.
293
294 The final form enumerates all the possible values that exist and
295 can be specified for any given OE kickstart (wks) property. If
296 the -o option is specified, the list of values for the given
297 property, in addition to being displayed, will be written to the
298 specified file as a JSON object. In this case, the object will
299 consist of the set of name:value pairs corresponding to the array
300 of property values associated with the property.
301
302 $ wic list property part
303 ["mountpoint", "where the partition should be mounted"]
304 ["fstype", "filesytem type of the partition"]
305 ["ext3"]
306 ["ext4"]
307 ["btrfs"]
308 ["swap"]
309 ["offset", "offset of the partition within the image"]
310
311"""
diff --git a/scripts/lib/mic/3rdparty/pykickstart/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/__init__.py
diff --git a/scripts/lib/mic/3rdparty/pykickstart/base.py b/scripts/lib/mic/3rdparty/pykickstart/base.py
new file mode 100644
index 0000000000..e6c8f56f9d
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/base.py
@@ -0,0 +1,466 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20"""
21Base classes for creating commands and syntax version object.
22
23This module exports several important base classes:
24
25 BaseData - The base abstract class for all data objects. Data objects
26 are contained within a BaseHandler object.
27
28 BaseHandler - The base abstract class from which versioned kickstart
29 handler are derived. Subclasses of BaseHandler hold
30 BaseData and KickstartCommand objects.
31
32 DeprecatedCommand - An abstract subclass of KickstartCommand that should
33 be further subclassed by users of this module. When
34 a subclass is used, a warning message will be
35 printed.
36
37 KickstartCommand - The base abstract class for all kickstart commands.
38 Command objects are contained within a BaseHandler
39 object.
40"""
41import gettext
42gettext.textdomain("pykickstart")
43_ = lambda x: gettext.ldgettext("pykickstart", x)
44
45import types
46import warnings
47from pykickstart.errors import *
48from pykickstart.ko import *
49from pykickstart.parser import Packages
50from pykickstart.version import versionToString
51
52###
53### COMMANDS
54###
55class KickstartCommand(KickstartObject):
56 """The base class for all kickstart commands. This is an abstract class."""
57 removedKeywords = []
58 removedAttrs = []
59
60 def __init__(self, writePriority=0, *args, **kwargs):
61 """Create a new KickstartCommand instance. This method must be
62 provided by all subclasses, but subclasses must call
63 KickstartCommand.__init__ first. Instance attributes:
64
65 currentCmd -- The name of the command in the input file that
66 caused this handler to be run.
67 currentLine -- The current unprocessed line from the input file
68 that caused this handler to be run.
69 handler -- A reference to the BaseHandler subclass this
70 command is contained withing. This is needed to
71 allow referencing of Data objects.
72 lineno -- The current line number in the input file.
73 writePriority -- An integer specifying when this command should be
74 printed when iterating over all commands' __str__
75 methods. The higher the number, the later this
76 command will be written. All commands with the
77 same priority will be written alphabetically.
78 """
79
80 # We don't want people using this class by itself.
81 if self.__class__ is KickstartCommand:
82 raise TypeError, "KickstartCommand is an abstract class."
83
84 KickstartObject.__init__(self, *args, **kwargs)
85
86 self.writePriority = writePriority
87
88 # These will be set by the dispatcher.
89 self.currentCmd = ""
90 self.currentLine = ""
91 self.handler = None
92 self.lineno = 0
93
94 # If a subclass provides a removedKeywords list, remove all the
95 # members from the kwargs list before we start processing it. This
96 # ensures that subclasses don't continue to recognize arguments that
97 # were removed.
98 for arg in filter(kwargs.has_key, self.removedKeywords):
99 kwargs.pop(arg)
100
101 def __call__(self, *args, **kwargs):
102 """Set multiple attributes on a subclass of KickstartCommand at once
103 via keyword arguments. Valid attributes are anything specified in
104 a subclass, but unknown attributes will be ignored.
105 """
106 for (key, val) in kwargs.items():
107 # Ignore setting attributes that were removed in a subclass, as
108 # if they were unknown attributes.
109 if key in self.removedAttrs:
110 continue
111
112 if hasattr(self, key):
113 setattr(self, key, val)
114
115 def __str__(self):
116 """Return a string formatted for output to a kickstart file. This
117 method must be provided by all subclasses.
118 """
119 return KickstartObject.__str__(self)
120
121 def parse(self, args):
122 """Parse the list of args and set data on the KickstartCommand object.
123 This method must be provided by all subclasses.
124 """
125 raise TypeError, "parse() not implemented for KickstartCommand"
126
127 def apply(self, instroot="/"):
128 """Write out the configuration related to the KickstartCommand object.
129 Subclasses which do not provide this method will not have their
130 configuration written out.
131 """
132 return
133
134 def dataList(self):
135 """For commands that can occur multiple times in a single kickstart
136 file (like network, part, etc.), return the list that we should
137 append more data objects to.
138 """
139 return None
140
141 def deleteRemovedAttrs(self):
142 """Remove all attributes from self that are given in the removedAttrs
143 list. This method should be called from __init__ in a subclass,
144 but only after the superclass's __init__ method has been called.
145 """
146 for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
147 delattr(self, attr)
148
149 # Set the contents of the opts object (an instance of optparse.Values
150 # returned by parse_args) as attributes on the KickstartCommand object.
151 # It's useful to call this from KickstartCommand subclasses after parsing
152 # the arguments.
153 def _setToSelf(self, optParser, opts):
154 self._setToObj(optParser, opts, self)
155
156 # Sets the contents of the opts object (an instance of optparse.Values
157 # returned by parse_args) as attributes on the provided object obj. It's
158 # useful to call this from KickstartCommand subclasses that handle lists
159 # of objects (like partitions, network devices, etc.) and need to populate
160 # a Data object.
161 def _setToObj(self, optParser, opts, obj):
162 for key in filter (lambda k: getattr(opts, k) != None, optParser.keys()):
163 setattr(obj, key, getattr(opts, key))
164
165class DeprecatedCommand(KickstartCommand):
166 """Specify that a command is deprecated and no longer has any function.
167 Any command that is deprecated should be subclassed from this class,
168 only specifying an __init__ method that calls the superclass's __init__.
169 This is an abstract class.
170 """
171 def __init__(self, writePriority=None, *args, **kwargs):
172 # We don't want people using this class by itself.
173 if self.__class__ is KickstartCommand:
174 raise TypeError, "DeprecatedCommand is an abstract class."
175
176 # Create a new DeprecatedCommand instance.
177 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
178
179 def __str__(self):
180 """Placeholder since DeprecatedCommands don't work anymore."""
181 return ""
182
183 def parse(self, args):
184 """Print a warning message if the command is seen in the input file."""
185 mapping = {"lineno": self.lineno, "cmd": self.currentCmd}
186 warnings.warn(_("Ignoring deprecated command on line %(lineno)s: The %(cmd)s command has been deprecated and no longer has any effect. It may be removed from future releases, which will result in a fatal error from kickstart. Please modify your kickstart file to remove this command.") % mapping, DeprecationWarning)
187
188
189###
190### HANDLERS
191###
192class BaseHandler(KickstartObject):
193 """Each version of kickstart syntax is provided by a subclass of this
194 class. These subclasses are what users will interact with for parsing,
195 extracting data, and writing out kickstart files. This is an abstract
196 class.
197
198 version -- The version this syntax handler supports. This is set by
199 a class attribute of a BaseHandler subclass and is used to
200 set up the command dict. It is for read-only use.
201 """
202 version = None
203
204 def __init__(self, mapping=None, dataMapping=None, commandUpdates=None,
205 dataUpdates=None, *args, **kwargs):
206 """Create a new BaseHandler instance. This method must be provided by
207 all subclasses, but subclasses must call BaseHandler.__init__ first.
208
209 mapping -- A custom map from command strings to classes,
210 useful when creating your own handler with
211 special command objects. It is otherwise unused
212 and rarely needed. If you give this argument,
213 the mapping takes the place of the default one
214 and so must include all commands you want
215 recognized.
216 dataMapping -- This is the same as mapping, but for data
217 objects. All the same comments apply.
218 commandUpdates -- This is similar to mapping, but does not take
219 the place of the defaults entirely. Instead,
220 this mapping is applied after the defaults and
221 updates it with just the commands you want to
222 modify.
223 dataUpdates -- This is the same as commandUpdates, but for
224 data objects.
225
226
227 Instance attributes:
228
229 commands -- A mapping from a string command to a KickstartCommand
230 subclass object that handles it. Multiple strings can
231 map to the same object, but only one instance of the
232 command object should ever exist. Most users should
233 never have to deal with this directly, as it is
234 manipulated internally and called through dispatcher.
235 currentLine -- The current unprocessed line from the input file
236 that caused this handler to be run.
237 packages -- An instance of pykickstart.parser.Packages which
238 describes the packages section of the input file.
239 platform -- A string describing the hardware platform, which is
240 needed only by system-config-kickstart.
241 scripts -- A list of pykickstart.parser.Script instances, which is
242 populated by KickstartParser.addScript and describes the
243 %pre/%post/%traceback script section of the input file.
244 """
245
246 # We don't want people using this class by itself.
247 if self.__class__ is BaseHandler:
248 raise TypeError, "BaseHandler is an abstract class."
249
250 KickstartObject.__init__(self, *args, **kwargs)
251
252 # This isn't really a good place for these, but it's better than
253 # everything else I can think of.
254 self.scripts = []
255 self.packages = Packages()
256 self.platform = ""
257
258 # These will be set by the dispatcher.
259 self.commands = {}
260 self.currentLine = 0
261
262 # A dict keyed by an integer priority number, with each value being a
263 # list of KickstartCommand subclasses. This dict is maintained by
264 # registerCommand and used in __str__. No one else should be touching
265 # it.
266 self._writeOrder = {}
267
268 self._registerCommands(mapping, dataMapping, commandUpdates, dataUpdates)
269
270 def __str__(self):
271 """Return a string formatted for output to a kickstart file."""
272 retval = ""
273
274 if self.platform != "":
275 retval += "#platform=%s\n" % self.platform
276
277 retval += "#version=%s\n" % versionToString(self.version)
278
279 lst = self._writeOrder.keys()
280 lst.sort()
281
282 for prio in lst:
283 for obj in self._writeOrder[prio]:
284 retval += obj.__str__()
285
286 for script in self.scripts:
287 retval += script.__str__()
288
289 retval += self.packages.__str__()
290
291 return retval
292
293 def _insertSorted(self, lst, obj):
294 length = len(lst)
295 i = 0
296
297 while i < length:
298 # If the two classes have the same name, it's because we are
299 # overriding an existing class with one from a later kickstart
300 # version, so remove the old one in favor of the new one.
301 if obj.__class__.__name__ > lst[i].__class__.__name__:
302 i += 1
303 elif obj.__class__.__name__ == lst[i].__class__.__name__:
304 lst[i] = obj
305 return
306 elif obj.__class__.__name__ < lst[i].__class__.__name__:
307 break
308
309 if i >= length:
310 lst.append(obj)
311 else:
312 lst.insert(i, obj)
313
314 def _setCommand(self, cmdObj):
315 # Add an attribute on this version object. We need this to provide a
316 # way for clients to access the command objects. We also need to strip
317 # off the version part from the front of the name.
318 if cmdObj.__class__.__name__.find("_") != -1:
319 name = unicode(cmdObj.__class__.__name__.split("_", 1)[1])
320 else:
321 name = unicode(cmdObj.__class__.__name__).lower()
322
323 setattr(self, name.lower(), cmdObj)
324
325 # Also, add the object into the _writeOrder dict in the right place.
326 if cmdObj.writePriority is not None:
327 if self._writeOrder.has_key(cmdObj.writePriority):
328 self._insertSorted(self._writeOrder[cmdObj.writePriority], cmdObj)
329 else:
330 self._writeOrder[cmdObj.writePriority] = [cmdObj]
331
332 def _registerCommands(self, mapping=None, dataMapping=None, commandUpdates=None,
333 dataUpdates=None):
334 if mapping == {} or mapping == None:
335 from pykickstart.handlers.control import commandMap
336 cMap = commandMap[self.version]
337 else:
338 cMap = mapping
339
340 if dataMapping == {} or dataMapping == None:
341 from pykickstart.handlers.control import dataMap
342 dMap = dataMap[self.version]
343 else:
344 dMap = dataMapping
345
346 if type(commandUpdates) == types.DictType:
347 cMap.update(commandUpdates)
348
349 if type(dataUpdates) == types.DictType:
350 dMap.update(dataUpdates)
351
352 for (cmdName, cmdClass) in cMap.iteritems():
353 # First make sure we haven't instantiated this command handler
354 # already. If we have, we just need to make another mapping to
355 # it in self.commands.
356 cmdObj = None
357
358 for (key, val) in self.commands.iteritems():
359 if val.__class__.__name__ == cmdClass.__name__:
360 cmdObj = val
361 break
362
363 # If we didn't find an instance in self.commands, create one now.
364 if cmdObj == None:
365 cmdObj = cmdClass()
366 self._setCommand(cmdObj)
367
368 # Finally, add the mapping to the commands dict.
369 self.commands[cmdName] = cmdObj
370 self.commands[cmdName].handler = self
371
372 # We also need to create attributes for the various data objects.
373 # No checks here because dMap is a bijection. At least, that's what
374 # the comment says. Hope no one screws that up.
375 for (dataName, dataClass) in dMap.iteritems():
376 setattr(self, dataName, dataClass)
377
378 def dispatcher(self, args, lineno):
379 """Call the appropriate KickstartCommand handler for the current line
380 in the kickstart file. A handler for the current command should
381 be registered, though a handler of None is not an error. Returns
382 the data object returned by KickstartCommand.parse.
383
384 args -- A list of arguments to the current command
385 lineno -- The line number in the file, for error reporting
386 """
387 cmd = args[0]
388
389 if not self.commands.has_key(cmd):
390 raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown command: %s" % cmd))
391 elif self.commands[cmd] != None:
392 self.commands[cmd].currentCmd = cmd
393 self.commands[cmd].currentLine = self.currentLine
394 self.commands[cmd].lineno = lineno
395
396 # The parser returns the data object that was modified. This could
397 # be a BaseData subclass that should be put into a list, or it
398 # could be the command handler object itself.
399 obj = self.commands[cmd].parse(args[1:])
400 lst = self.commands[cmd].dataList()
401 if lst is not None:
402 lst.append(obj)
403
404 return obj
405
406 def maskAllExcept(self, lst):
407 """Set all entries in the commands dict to None, except the ones in
408 the lst. All other commands will not be processed.
409 """
410 self._writeOrder = {}
411
412 for (key, val) in self.commands.iteritems():
413 if not key in lst:
414 self.commands[key] = None
415
416 def hasCommand(self, cmd):
417 """Return true if there is a handler for the string cmd."""
418 return hasattr(self, cmd)
419
420
421###
422### DATA
423###
424class BaseData(KickstartObject):
425 """The base class for all data objects. This is an abstract class."""
426 removedKeywords = []
427 removedAttrs = []
428
429 def __init__(self, *args, **kwargs):
430 """Create a new BaseData instance.
431
432 lineno -- Line number in the ks-file where this object was defined
433 """
434
435 # We don't want people using this class by itself.
436 if self.__class__ is BaseData:
437 raise TypeError, "BaseData is an abstract class."
438
439 KickstartObject.__init__(self, *args, **kwargs)
440 self.lineno = 0
441
442 def __str__(self):
443 """Return a string formatted for output to a kickstart file."""
444 return ""
445
446 def __call__(self, *args, **kwargs):
447 """Set multiple attributes on a subclass of BaseData at once via
448 keyword arguments. Valid attributes are anything specified in a
449 subclass, but unknown attributes will be ignored.
450 """
451 for (key, val) in kwargs.items():
452 # Ignore setting attributes that were removed in a subclass, as
453 # if they were unknown attributes.
454 if key in self.removedAttrs:
455 continue
456
457 if hasattr(self, key):
458 setattr(self, key, val)
459
460 def deleteRemovedAttrs(self):
461 """Remove all attributes from self that are given in the removedAttrs
462 list. This method should be called from __init__ in a subclass,
463 but only after the superclass's __init__ method has been called.
464 """
465 for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
466 delattr(self, attr)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py
new file mode 100644
index 0000000000..da48ff50d5
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/__init__.py
@@ -0,0 +1,26 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20import authconfig, autopart, autostep, bootloader, clearpart, device
21import deviceprobe, displaymode, dmraid, driverdisk, fcoe, firewall, firstboot
22import group, ignoredisk, interactive, iscsi, iscsiname, key, keyboard, lang
23import langsupport, lilocheck, logging, logvol, mediacheck, method, monitor
24import mouse, multipath, network, partition, raid, reboot, repo, rescue, rootpw
25import selinux, services, skipx, sshpw, timezone, updates, upgrade, user, vnc
26import volgroup, xconfig, zerombr, zfcp
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/authconfig.py b/scripts/lib/mic/3rdparty/pykickstart/commands/authconfig.py
new file mode 100644
index 0000000000..9af9c0ff14
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/authconfig.py
@@ -0,0 +1,40 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21
22class FC3_Authconfig(KickstartCommand):
23 removedKeywords = KickstartCommand.removedKeywords
24 removedAttrs = KickstartCommand.removedAttrs
25
26 def __init__(self, writePriority=0, *args, **kwargs):
27 KickstartCommand.__init__(self, *args, **kwargs)
28 self.authconfig = kwargs.get("authconfig", "")
29
30 def __str__(self):
31 retval = KickstartCommand.__str__(self)
32
33 if self.authconfig:
34 retval += "# System authorization information\nauth %s\n" % self.authconfig
35
36 return retval
37
38 def parse(self, args):
39 self.authconfig = self.currentLine[len(self.currentCmd):].strip()
40 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/autopart.py b/scripts/lib/mic/3rdparty/pykickstart/commands/autopart.py
new file mode 100644
index 0000000000..cf28b5c7f7
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/autopart.py
@@ -0,0 +1,119 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_AutoPart(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=100, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.autopart = kwargs.get("autopart", False)
34
35 def __str__(self):
36 retval = KickstartCommand.__str__(self)
37
38 if self.autopart:
39 retval += "autopart\n"
40
41 return retval
42
43 def parse(self, args):
44 if len(args) > 0:
45 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "autopart")
46
47 self.autopart = True
48 return self
49
50class F9_AutoPart(FC3_AutoPart):
51 removedKeywords = FC3_AutoPart.removedKeywords
52 removedAttrs = FC3_AutoPart.removedAttrs
53
54 def __init__(self, writePriority=100, *args, **kwargs):
55 FC3_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
56 self.encrypted = kwargs.get("encrypted", False)
57 self.passphrase = kwargs.get("passphrase", "")
58
59 self.op = self._getParser()
60
61 def __str__(self):
62 retval = KickstartCommand.__str__(self)
63
64 if self.autopart:
65 retval += "autopart"
66
67 if self.encrypted:
68 retval += " --encrypted"
69
70 if self.passphrase != "":
71 retval += " --passphrase=\"%s\""% self.passphrase
72
73 if retval != "":
74 retval += "\n"
75
76 return retval
77
78 def _getParser(self):
79 op = KSOptionParser()
80 op.add_option("--encrypted", action="store_true", default=False)
81 op.add_option("--passphrase")
82 return op
83
84 def parse(self, args):
85 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
86 self._setToSelf(self.op, opts)
87 self.autopart = True
88 return self
89
90class F12_AutoPart(F9_AutoPart):
91 removedKeywords = F9_AutoPart.removedKeywords
92 removedAttrs = F9_AutoPart.removedAttrs
93
94 def __init__(self, writePriority=100, *args, **kwargs):
95 F9_AutoPart.__init__(self, writePriority=writePriority, *args, **kwargs)
96
97 self.escrowcert = kwargs.get("escrowcert", "")
98 self.backuppassphrase = kwargs.get("backuppassphrase", False)
99
100 def __str__(self):
101 retval = F9_AutoPart.__str__(self)
102
103 if self.encrypted and self.escrowcert != "":
104 retval = retval.strip()
105
106 retval += " --escrowcert=\"%s\"" % self.escrowcert
107
108 if self.backuppassphrase:
109 retval += " --backuppassphrase"
110
111 retval += "\n"
112
113 return retval
114
115 def _getParser(self):
116 op = F9_AutoPart._getParser(self)
117 op.add_option("--escrowcert")
118 op.add_option("--backuppassphrase", action="store_true", default=False)
119 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/autostep.py b/scripts/lib/mic/3rdparty/pykickstart/commands/autostep.py
new file mode 100644
index 0000000000..e6ae71cefc
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/autostep.py
@@ -0,0 +1,55 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23class FC3_AutoStep(KickstartCommand):
24 removedKeywords = KickstartCommand.removedKeywords
25 removedAttrs = KickstartCommand.removedAttrs
26
27 def __init__(self, writePriority=0, *args, **kwargs):
28 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
29 self.op = self._getParser()
30
31 self.autostep = kwargs.get("autostep", False)
32 self.autoscreenshot = kwargs.get("autoscreenshot", False)
33
34 def __str__(self):
35 retval = KickstartCommand.__str__(self)
36
37 if self.autostep:
38 if self.autoscreenshot:
39 retval += "autostep --autoscreenshot\n"
40 else:
41 retval += "autostep\n"
42
43 return retval
44
45 def _getParser(self):
46 op = KSOptionParser()
47 op.add_option("--autoscreenshot", dest="autoscreenshot",
48 action="store_true", default=False)
49 return op
50
51 def parse(self, args):
52 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
53 self._setToSelf(self.op, opts)
54 self.autostep = True
55 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py b/scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py
new file mode 100644
index 0000000000..b227fac3be
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/bootloader.py
@@ -0,0 +1,265 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23class FC3_Bootloader(KickstartCommand):
24 removedKeywords = KickstartCommand.removedKeywords
25 removedAttrs = KickstartCommand.removedAttrs
26
27 def __init__(self, writePriority=10, *args, **kwargs):
28 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
29 self.op = self._getParser()
30
31 self.driveorder = kwargs.get("driveorder", [])
32 self.appendLine = kwargs.get("appendLine", "")
33 self.forceLBA = kwargs.get("forceLBA", False)
34 self.linear = kwargs.get("linear", True)
35 self.location = kwargs.get("location", "")
36 self.md5pass = kwargs.get("md5pass", "")
37 self.password = kwargs.get("password", "")
38 self.upgrade = kwargs.get("upgrade", False)
39 self.useLilo = kwargs.get("useLilo", False)
40
41 self.deleteRemovedAttrs()
42
43 def _getArgsAsStr(self):
44 retval = ""
45
46 if self.appendLine != "":
47 retval += " --append=\"%s\"" % self.appendLine
48 if self.linear:
49 retval += " --linear"
50 if self.location:
51 retval += " --location=%s" % self.location
52 if hasattr(self, "forceLBA") and self.forceLBA:
53 retval += " --lba32"
54 if self.password != "":
55 retval += " --password=\"%s\"" % self.password
56 if self.md5pass != "":
57 retval += " --md5pass=\"%s\"" % self.md5pass
58 if self.upgrade:
59 retval += " --upgrade"
60 if self.useLilo:
61 retval += " --useLilo"
62 if len(self.driveorder) > 0:
63 retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
64
65 return retval
66
67 def __str__(self):
68 retval = KickstartCommand.__str__(self)
69
70 if self.location != "":
71 retval += "# System bootloader configuration\nbootloader"
72 retval += self._getArgsAsStr() + "\n"
73
74 return retval
75
76 def _getParser(self):
77 def driveorder_cb (option, opt_str, value, parser):
78 for d in value.split(','):
79 parser.values.ensure_value(option.dest, []).append(d)
80
81 op = KSOptionParser()
82 op.add_option("--append", dest="appendLine")
83 op.add_option("--linear", dest="linear", action="store_true",
84 default=True)
85 op.add_option("--nolinear", dest="linear", action="store_false")
86 op.add_option("--location", dest="location", type="choice",
87 default="mbr",
88 choices=["mbr", "partition", "none", "boot"])
89 op.add_option("--lba32", dest="forceLBA", action="store_true",
90 default=False)
91 op.add_option("--password", dest="password", default="")
92 op.add_option("--md5pass", dest="md5pass", default="")
93 op.add_option("--upgrade", dest="upgrade", action="store_true",
94 default=False)
95 op.add_option("--useLilo", dest="useLilo", action="store_true",
96 default=False)
97 op.add_option("--driveorder", dest="driveorder", action="callback",
98 callback=driveorder_cb, nargs=1, type="string")
99 return op
100
101 def parse(self, args):
102 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
103 self._setToSelf(self.op, opts)
104
105 if self.currentCmd == "lilo":
106 self.useLilo = True
107
108 return self
109
110class FC4_Bootloader(FC3_Bootloader):
111 removedKeywords = FC3_Bootloader.removedKeywords + ["linear", "useLilo"]
112 removedAttrs = FC3_Bootloader.removedAttrs + ["linear", "useLilo"]
113
114 def __init__(self, writePriority=10, *args, **kwargs):
115 FC3_Bootloader.__init__(self, writePriority, *args, **kwargs)
116
117 def _getArgsAsStr(self):
118 retval = ""
119 if self.appendLine != "":
120 retval += " --append=\"%s\"" % self.appendLine
121 if self.location:
122 retval += " --location=%s" % self.location
123 if hasattr(self, "forceLBA") and self.forceLBA:
124 retval += " --lba32"
125 if self.password != "":
126 retval += " --password=\"%s\"" % self.password
127 if self.md5pass != "":
128 retval += " --md5pass=\"%s\"" % self.md5pass
129 if self.upgrade:
130 retval += " --upgrade"
131 if len(self.driveorder) > 0:
132 retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
133 return retval
134
135 def _getParser(self):
136 op = FC3_Bootloader._getParser(self)
137 op.remove_option("--linear")
138 op.remove_option("--nolinear")
139 op.remove_option("--useLilo")
140 return op
141
142 def parse(self, args):
143 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
144 self._setToSelf(self.op, opts)
145 return self
146
147class F8_Bootloader(FC4_Bootloader):
148 removedKeywords = FC4_Bootloader.removedKeywords
149 removedAttrs = FC4_Bootloader.removedAttrs
150
151 def __init__(self, writePriority=10, *args, **kwargs):
152 FC4_Bootloader.__init__(self, writePriority, *args, **kwargs)
153
154 self.timeout = kwargs.get("timeout", None)
155 self.default = kwargs.get("default", "")
156
157 def _getArgsAsStr(self):
158 ret = FC4_Bootloader._getArgsAsStr(self)
159
160 if self.timeout is not None:
161 ret += " --timeout=%d" %(self.timeout,)
162 if self.default:
163 ret += " --default=%s" %(self.default,)
164
165 return ret
166
167 def _getParser(self):
168 op = FC4_Bootloader._getParser(self)
169 op.add_option("--timeout", dest="timeout", type="int")
170 op.add_option("--default", dest="default")
171 return op
172
173class F12_Bootloader(F8_Bootloader):
174 removedKeywords = F8_Bootloader.removedKeywords
175 removedAttrs = F8_Bootloader.removedAttrs
176
177 def _getParser(self):
178 op = F8_Bootloader._getParser(self)
179 op.add_option("--lba32", dest="forceLBA", deprecated=1, action="store_true")
180 return op
181
182class F14_Bootloader(F12_Bootloader):
183 removedKeywords = F12_Bootloader.removedKeywords + ["forceLBA"]
184 removedAttrs = F12_Bootloader.removedKeywords + ["forceLBA"]
185
186 def _getParser(self):
187 op = F12_Bootloader._getParser(self)
188 op.remove_option("--lba32")
189 return op
190
191class F15_Bootloader(F14_Bootloader):
192 removedKeywords = F14_Bootloader.removedKeywords
193 removedAttrs = F14_Bootloader.removedAttrs
194
195 def __init__(self, writePriority=10, *args, **kwargs):
196 F14_Bootloader.__init__(self, writePriority, *args, **kwargs)
197
198 self.isCrypted = kwargs.get("isCrypted", False)
199
200 def _getArgsAsStr(self):
201 ret = F14_Bootloader._getArgsAsStr(self)
202
203 if self.isCrypted:
204 ret += " --iscrypted"
205
206 return ret
207
208 def _getParser(self):
209 def password_cb(option, opt_str, value, parser):
210 parser.values.isCrypted = True
211 parser.values.password = value
212
213 op = F14_Bootloader._getParser(self)
214 op.add_option("--iscrypted", dest="isCrypted", action="store_true", default=False)
215 op.add_option("--md5pass", action="callback", callback=password_cb, nargs=1, type="string")
216 return op
217
218class RHEL5_Bootloader(FC4_Bootloader):
219 removedKeywords = FC4_Bootloader.removedKeywords
220 removedAttrs = FC4_Bootloader.removedAttrs
221
222 def __init__(self, writePriority=10, *args, **kwargs):
223 FC4_Bootloader.__init__(self, writePriority, *args, **kwargs)
224
225 self.hvArgs = kwargs.get("hvArgs", "")
226
227 def _getArgsAsStr(self):
228 ret = FC4_Bootloader._getArgsAsStr(self)
229
230 if self.hvArgs:
231 ret += " --hvargs=\"%s\"" %(self.hvArgs,)
232
233 return ret
234
235 def _getParser(self):
236 op = FC4_Bootloader._getParser(self)
237 op.add_option("--hvargs", dest="hvArgs", type="string")
238 return op
239
240class RHEL6_Bootloader(F12_Bootloader):
241 removedKeywords = F12_Bootloader.removedKeywords
242 removedAttrs = F12_Bootloader.removedAttrs
243
244 def __init__(self, writePriority=10, *args, **kwargs):
245 F12_Bootloader.__init__(self, writePriority, *args, **kwargs)
246
247 self.isCrypted = kwargs.get("isCrypted", False)
248
249 def _getArgsAsStr(self):
250 ret = F12_Bootloader._getArgsAsStr(self)
251
252 if self.isCrypted:
253 ret += " --iscrypted"
254
255 return ret
256
257 def _getParser(self):
258 def password_cb(option, opt_str, value, parser):
259 parser.values.isCrypted = True
260 parser.values.password = value
261
262 op = F12_Bootloader._getParser(self)
263 op.add_option("--iscrypted", dest="isCrypted", action="store_true", default=False)
264 op.add_option("--md5pass", action="callback", callback=password_cb, nargs=1, type="string")
265 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/clearpart.py b/scripts/lib/mic/3rdparty/pykickstart/commands/clearpart.py
new file mode 100644
index 0000000000..a8089fcb99
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/clearpart.py
@@ -0,0 +1,86 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25class FC3_ClearPart(KickstartCommand):
26 removedKeywords = KickstartCommand.removedKeywords
27 removedAttrs = KickstartCommand.removedAttrs
28
29 def __init__(self, writePriority=120, *args, **kwargs):
30 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
31 self.op = self._getParser()
32
33 self.drives = kwargs.get("drives", [])
34 self.initAll = kwargs.get("initAll", False)
35 self.type = kwargs.get("type", None)
36
37 def __str__(self):
38 retval = KickstartCommand.__str__(self)
39
40 if self.type is None:
41 return retval
42
43 if self.type == CLEARPART_TYPE_NONE:
44 clearstr = "--none"
45 elif self.type == CLEARPART_TYPE_LINUX:
46 clearstr = "--linux"
47 elif self.type == CLEARPART_TYPE_ALL:
48 clearstr = "--all"
49 else:
50 clearstr = ""
51
52 if self.initAll:
53 initstr = "--initlabel"
54 else:
55 initstr = ""
56
57 if len(self.drives) > 0:
58 drivestr = "--drives=" + ",".join(self.drives)
59 else:
60 drivestr = ""
61
62 retval += "# Partition clearing information\nclearpart %s %s %s\n" % (clearstr, initstr, drivestr)
63 return retval
64
65 def _getParser(self):
66 def drive_cb (option, opt_str, value, parser):
67 for d in value.split(','):
68 parser.values.ensure_value(option.dest, []).append(d)
69
70 op = KSOptionParser()
71 op.add_option("--all", dest="type", action="store_const",
72 const=CLEARPART_TYPE_ALL)
73 op.add_option("--drives", dest="drives", action="callback",
74 callback=drive_cb, nargs=1, type="string")
75 op.add_option("--initlabel", dest="initAll", action="store_true",
76 default=False)
77 op.add_option("--linux", dest="type", action="store_const",
78 const=CLEARPART_TYPE_LINUX)
79 op.add_option("--none", dest="type", action="store_const",
80 const=CLEARPART_TYPE_NONE)
81 return op
82
83 def parse(self, args):
84 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
85 self._setToSelf(self.op, opts)
86 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/device.py b/scripts/lib/mic/3rdparty/pykickstart/commands/device.py
new file mode 100644
index 0000000000..321410e2e2
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/device.py
@@ -0,0 +1,125 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24import warnings
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class F8_DeviceData(BaseData):
28 removedKeywords = BaseData.removedKeywords
29 removedAttrs = BaseData.removedAttrs
30
31 def __init__(self, *args, **kwargs):
32 BaseData.__init__(self, *args, **kwargs)
33 self.moduleName = kwargs.get("moduleName", "")
34 self.moduleOpts = kwargs.get("moduleOpts", "")
35
36 def __eq__(self, y):
37 return self.moduleName == y.moduleName
38
39 def __str__(self):
40 retval = BaseData.__str__(self)
41
42 if self.moduleName != "":
43 retval += "device %s" % self.moduleName
44
45 if self.moduleOpts != "":
46 retval += " --opts=\"%s\"" % self.moduleOpts
47
48 return retval + "\n"
49
50class FC3_Device(KickstartCommand):
51 removedKeywords = KickstartCommand.removedKeywords
52 removedAttrs = KickstartCommand.removedAttrs
53
54 def __init__(self, writePriority=0, *args, **kwargs):
55 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
56 self.op = self._getParser()
57
58 self.type = kwargs.get("type", "")
59 self.moduleName = kwargs.get("moduleName", "")
60 self.moduleOpts = kwargs.get("moduleOpts", "")
61
62 def __eq__(self, y):
63 return self.moduleName == y.moduleName
64
65 def __str__(self):
66 retval = KickstartCommand.__str__(self)
67
68 if self.moduleName != "":
69 retval += "device %s %s" % (self.type, self.moduleName)
70
71 if self.moduleOpts != "":
72 retval += " --opts=\"%s\"" % self.moduleOpts
73
74 return retval + "\n"
75
76 def _getParser(self):
77 op = KSOptionParser()
78 op.add_option("--opts", dest="moduleOpts", default="")
79 return op
80
81 def parse(self, args):
82 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
83
84 if len(extra) != 2:
85 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("device command requires two arguments: module type and name"))
86
87 self.moduleOpts = opts.moduleOpts
88 self.type = extra[0]
89 self.moduleName = extra[1]
90 return self
91
92class F8_Device(FC3_Device):
93 removedKeywords = FC3_Device.removedKeywords
94 removedAttrs = FC3_Device.removedAttrs
95
96 def __init__(self, writePriority=0, *args, **kwargs):
97 FC3_Device.__init__(self, writePriority, *args, **kwargs)
98 self.deviceList = kwargs.get("deviceList", [])
99
100 def __str__(self):
101 retval = ""
102 for device in self.deviceList:
103 retval += device.__str__()
104
105 return retval
106
107 def parse(self, args):
108 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
109
110 if len(extra) != 1:
111 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("%s command requires a single argument: %s") % ("device", "module name"))
112
113 dd = F8_DeviceData()
114 self._setToObj(self.op, opts, dd)
115 dd.lineno = self.lineno
116 dd.moduleName = extra[0]
117
118 # Check for duplicates in the data list.
119 if dd in self.dataList():
120 warnings.warn(_("A module with the name %s has already been defined.") % dd.moduleName)
121
122 return dd
123
124 def dataList(self):
125 return self.deviceList
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/deviceprobe.py b/scripts/lib/mic/3rdparty/pykickstart/commands/deviceprobe.py
new file mode 100644
index 0000000000..9f462fdff7
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/deviceprobe.py
@@ -0,0 +1,40 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21
22class FC3_DeviceProbe(KickstartCommand):
23 removedKeywords = KickstartCommand.removedKeywords
24 removedAttrs = KickstartCommand.removedAttrs
25
26 def __init__(self, writePriority=0, *args, **kwargs):
27 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
28 self.deviceprobe = kwargs.get("deviceprobe", "")
29
30 def __str__(self):
31 retval = KickstartCommand.__str__(self)
32
33 if self.deviceprobe != "":
34 retval += "deviceprobe %s\n" % self.deviceprobe
35
36 return retval
37
38 def parse(self, args):
39 self.deviceprobe = " ".join(args)
40 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/displaymode.py b/scripts/lib/mic/3rdparty/pykickstart/commands/displaymode.py
new file mode 100644
index 0000000000..6a12d58ec2
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/displaymode.py
@@ -0,0 +1,68 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_DisplayMode(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.displayMode = kwargs.get("displayMode", None)
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.displayMode is None:
40 return retval
41
42 if self.displayMode == DISPLAY_MODE_CMDLINE:
43 retval += "cmdline\n"
44 elif self.displayMode == DISPLAY_MODE_GRAPHICAL:
45 retval += "# Use graphical install\ngraphical\n"
46 elif self.displayMode == DISPLAY_MODE_TEXT:
47 retval += "# Use text mode install\ntext\n"
48
49 return retval
50
51 def _getParser(self):
52 op = KSOptionParser()
53 return op
54
55 def parse(self, args):
56 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
57
58 if len(extra) > 0:
59 raise KickstartParseError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % self.currentCmd)
60
61 if self.currentCmd == "cmdline":
62 self.displayMode = DISPLAY_MODE_CMDLINE
63 elif self.currentCmd == "graphical":
64 self.displayMode = DISPLAY_MODE_GRAPHICAL
65 elif self.currentCmd == "text":
66 self.displayMode = DISPLAY_MODE_TEXT
67
68 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/dmraid.py b/scripts/lib/mic/3rdparty/pykickstart/commands/dmraid.py
new file mode 100644
index 0000000000..993575a041
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/dmraid.py
@@ -0,0 +1,91 @@
1#
2# Chris Lumens <clumens@redhat.com>
3# Peter Jones <pjones@redhat.com>
4#
5# Copyright 2006, 2007 Red Hat, Inc.
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
17# trademarks that are incorporated in the source code or documentation are not
18# subject to the GNU General Public License and may only be used or replicated
19# with the express permission of Red Hat, Inc.
20#
21from pykickstart.base import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26import warnings
27_ = lambda x: gettext.ldgettext("pykickstart", x)
28
29class FC6_DmRaidData(BaseData):
30 removedKeywords = BaseData.removedKeywords
31 removedAttrs = BaseData.removedAttrs
32
33 def __init__(self, *args, **kwargs):
34 BaseData.__init__(self, *args, **kwargs)
35
36 self.name = kwargs.get("name", "")
37 self.devices = kwargs.get("devices", [])
38 self.dmset = kwargs.get("dmset", None)
39
40 def __eq__(self, y):
41 return self.name == y.name and self.devices == y.devices
42
43 def __str__(self):
44 retval = BaseData.__str__(self)
45 retval += "dmraid --name=%s" % self.name
46
47 for dev in self.devices:
48 retval += " --dev=\"%s\"" % dev
49
50 return retval + "\n"
51
52class FC6_DmRaid(KickstartCommand):
53 removedKeywords = KickstartCommand.removedKeywords
54 removedAttrs = KickstartCommand.removedAttrs
55
56 def __init__(self, writePriority=60, *args, **kwargs):
57 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
58 self.op = self._getParser()
59
60 self.dmraids = kwargs.get("dmraids", [])
61
62 def __str__(self):
63 retval = ""
64 for dm in self.dmraids:
65 retval += dm.__str__()
66
67 return retval
68
69 def _getParser(self):
70 op = KSOptionParser()
71 op.add_option("--name", dest="name", action="store", type="string",
72 required=1)
73 op.add_option("--dev", dest="devices", action="append", type="string",
74 required=1)
75 return op
76
77 def parse(self, args):
78 dm = FC6_DmRaidData()
79 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
80 dm.name = dm.name.split('/')[-1]
81 self._setToObj(self.op, opts, dm)
82 dm.lineno = self.lineno
83
84 # Check for duplicates in the data list.
85 if dm in self.dataList():
86 warnings.warn(_("A DM RAID device with the name %s and devices %s has already been defined.") % (dm.name, dm.devices))
87
88 return dm
89
90 def dataList(self):
91 return self.dmraids
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/driverdisk.py b/scripts/lib/mic/3rdparty/pykickstart/commands/driverdisk.py
new file mode 100644
index 0000000000..82a58c0e28
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/driverdisk.py
@@ -0,0 +1,184 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24_ = lambda x: gettext.ldgettext("pykickstart", x)
25
26class FC3_DriverDiskData(BaseData):
27 removedKeywords = BaseData.removedKeywords
28 removedAttrs = BaseData.removedAttrs
29
30 def __init__(self, writePriority=0, *args, **kwargs):
31 BaseData.__init__(self, *args, **kwargs)
32
33 self.partition = kwargs.get("partition", "")
34 self.source = kwargs.get("source", "")
35 self.type = kwargs.get("type", "")
36
37 def _getArgsAsStr(self):
38 retval = ""
39
40 if self.partition:
41 retval += "%s" % self.partition
42
43 if hasattr(self, "type") and self.type:
44 retval += " --type=%s" % self.type
45 elif self.source:
46 retval += "--source=%s" % self.source
47 return retval
48
49 def __str__(self):
50 retval = BaseData.__str__(self)
51 retval += "driverdisk %s\n" % self._getArgsAsStr()
52 return retval
53
54class FC4_DriverDiskData(FC3_DriverDiskData):
55 removedKeywords = FC3_DriverDiskData.removedKeywords
56 removedAttrs = FC3_DriverDiskData.removedAttrs
57
58 def __init__(self, writePriority=0, *args, **kwargs):
59 FC3_DriverDiskData.__init__(self, *args, **kwargs)
60 self.deleteRemovedAttrs()
61
62 self.biospart = kwargs.get("biospart", "")
63
64 def _getArgsAsStr(self):
65 retval = ""
66
67 if self.partition:
68 retval += "%s" % self.partition
69
70 if hasattr(self, "type") and self.type:
71 retval += " --type=%s" % self.type
72 elif self.source:
73 retval += "--source=%s" % self.source
74 elif self.biospart:
75 retval += "--biospart=%s" % self.biospart
76
77 return retval
78
79class F12_DriverDiskData(FC4_DriverDiskData):
80 removedKeywords = FC4_DriverDiskData.removedKeywords + ["type"]
81 removedAttrs = FC4_DriverDiskData.removedAttrs + ["type"]
82
83 def __init__(self, *args, **kwargs):
84 FC4_DriverDiskData.__init__(self, *args, **kwargs)
85 self.deleteRemovedAttrs()
86
87F14_DriverDiskData = F12_DriverDiskData
88
89class FC3_DriverDisk(KickstartCommand):
90 removedKeywords = KickstartCommand.removedKeywords
91 removedAttrs = KickstartCommand.removedAttrs
92
93 def __init__(self, writePriority=0, *args, **kwargs):
94 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
95 self.op = self._getParser()
96
97 self.driverdiskList = kwargs.get("driverdiskList", [])
98
99 def __str__(self):
100 retval = ""
101 for dd in self.driverdiskList:
102 retval += dd.__str__()
103
104 return retval
105
106 def _getParser(self):
107 op = KSOptionParser()
108 op.add_option("--source")
109 op.add_option("--type")
110 return op
111
112 def parse(self, args):
113 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
114
115 if len(extra) > 1:
116 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one partition may be specified for driverdisk command."))
117
118 if len(extra) == 1 and opts.source:
119 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --source and partition may be specified for driverdisk command."))
120
121 if not extra and not opts.source:
122 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of --source or partition must be specified for driverdisk command."))
123
124 ddd = self.handler.DriverDiskData()
125 self._setToObj(self.op, opts, ddd)
126 ddd.lineno = self.lineno
127 if len(extra) == 1:
128 ddd.partition = extra[0]
129
130 return ddd
131
132 def dataList(self):
133 return self.driverdiskList
134
135class FC4_DriverDisk(FC3_DriverDisk):
136 removedKeywords = FC3_DriverDisk.removedKeywords
137 removedAttrs = FC3_DriverDisk.removedKeywords
138
139 def _getParser(self):
140 op = FC3_DriverDisk._getParser(self)
141 op.add_option("--biospart")
142 return op
143
144 def parse(self, args):
145 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
146
147 if len(extra) > 1:
148 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one partition may be specified for driverdisk command."))
149
150 if len(extra) == 1 and opts.source:
151 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --source and partition may be specified for driverdisk command."))
152 elif len(extra) == 1 and opts.biospart:
153 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --biospart and partition may be specified for driverdisk command."))
154 elif opts.source and opts.biospart:
155 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --biospart and --source may be specified for driverdisk command."))
156
157 if not extra and not opts.source and not opts.biospart:
158 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of --source, --biospart, or partition must be specified for driverdisk command."))
159
160 ddd = self.handler.DriverDiskData()
161 self._setToObj(self.op, opts, ddd)
162 ddd.lineno = self.lineno
163 if len(extra) == 1:
164 ddd.partition = extra[0]
165
166 return ddd
167
168class F12_DriverDisk(FC4_DriverDisk):
169 removedKeywords = FC4_DriverDisk.removedKeywords
170 removedAttrs = FC4_DriverDisk.removedKeywords
171
172 def _getParser(self):
173 op = FC4_DriverDisk._getParser(self)
174 op.add_option("--type", deprecated=1)
175 return op
176
177class F14_DriverDisk(F12_DriverDisk):
178 removedKeywords = F12_DriverDisk.removedKeywords
179 removedAttrs = F12_DriverDisk.removedKeywords
180
181 def _getParser(self):
182 op = F12_DriverDisk._getParser(self)
183 op.remove_option("--type")
184 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/fcoe.py b/scripts/lib/mic/3rdparty/pykickstart/commands/fcoe.py
new file mode 100644
index 0000000000..33208499b3
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/fcoe.py
@@ -0,0 +1,114 @@
1#
2# Hans de Goede <hdegoede@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24import warnings
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class F12_FcoeData(BaseData):
28 removedKeywords = BaseData.removedKeywords
29 removedAttrs = BaseData.removedAttrs
30
31 def __init__(self, *args, **kwargs):
32 BaseData.__init__(self, *args, **kwargs)
33 self.nic = kwargs.get("nic", None)
34
35 def __eq__(self, y):
36 return self.nic == y.nic
37
38 def _getArgsAsStr(self):
39 retval = ""
40
41 if self.nic:
42 retval += " --nic=%s" % self.nic
43
44 return retval
45
46 def __str__(self):
47 retval = BaseData.__str__(self)
48 retval += "fcoe%s\n" % self._getArgsAsStr()
49 return retval
50
51class F13_FcoeData(F12_FcoeData):
52 removedKeywords = F12_FcoeData.removedKeywords
53 removedAttrs = F12_FcoeData.removedAttrs
54
55 def __init__(self, *args, **kwargs):
56 F12_FcoeData.__init__(self, *args, **kwargs)
57 self.dcb = kwargs.get("dcb", False)
58
59 def _getArgsAsStr(self):
60 retval = F12_FcoeData._getArgsAsStr(self)
61
62 if self.dcb:
63 retval += " --dcb"
64
65 return retval
66
67class F12_Fcoe(KickstartCommand):
68 removedKeywords = KickstartCommand.removedKeywords
69 removedAttrs = KickstartCommand.removedAttrs
70
71 def __init__(self, writePriority=71, *args, **kwargs):
72 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
73 self.op = self._getParser()
74 self.fcoe = kwargs.get("fcoe", [])
75
76 def __str__(self):
77 retval = ""
78 for fcoe in self.fcoe:
79 retval += fcoe.__str__()
80
81 return retval
82
83 def _getParser(self):
84 op = KSOptionParser()
85 op.add_option("--nic", dest="nic", required=1)
86 return op
87
88 def parse(self, args):
89 zd = self.handler.FcoeData()
90 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
91 if len(extra) > 0:
92 mapping = {"command": "fcoe", "options": extra}
93 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
94
95 self._setToObj(self.op, opts, zd)
96 zd.lineno = self.lineno
97
98 # Check for duplicates in the data list.
99 if zd in self.dataList():
100 warnings.warn(_("A FCOE device with the name %s has already been defined.") % zd.nic)
101
102 return zd
103
104 def dataList(self):
105 return self.fcoe
106
107class F13_Fcoe(F12_Fcoe):
108 removedKeywords = F12_Fcoe.removedKeywords
109 removedAttrs = F12_Fcoe.removedAttrs
110
111 def _getParser(self):
112 op = F12_Fcoe._getParser(self)
113 op.add_option("--dcb", dest="dcb", action="store_true", default=False)
114 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/firewall.py b/scripts/lib/mic/3rdparty/pykickstart/commands/firewall.py
new file mode 100644
index 0000000000..24a01bd610
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/firewall.py
@@ -0,0 +1,193 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Firewall(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.enabled = kwargs.get("enabled", None)
36 self.ports = kwargs.get("ports", [])
37 self.trusts = kwargs.get("trusts", [])
38
39 def __str__(self):
40 extra = []
41 filteredPorts = []
42
43 retval = KickstartCommand.__str__(self)
44
45 if self.enabled is None:
46 return retval
47
48 if self.enabled:
49 # It's possible we have words in the ports list instead of
50 # port:proto (s-c-kickstart may do this). So, filter those
51 # out into their own list leaving what we expect.
52 for port in self.ports:
53 if port == "ssh":
54 extra.append(" --ssh")
55 elif port == "telnet":
56 extra.append(" --telnet")
57 elif port == "smtp":
58 extra.append(" --smtp")
59 elif port == "http":
60 extra.append(" --http")
61 elif port == "ftp":
62 extra.append(" --ftp")
63 else:
64 filteredPorts.append(port)
65
66 # All the port:proto strings go into a comma-separated list.
67 portstr = ",".join(filteredPorts)
68 if len(portstr) > 0:
69 portstr = " --port=" + portstr
70 else:
71 portstr = ""
72
73 extrastr = "".join(extra)
74 truststr = ",".join(self.trusts)
75
76 if len(truststr) > 0:
77 truststr = " --trust=" + truststr
78
79 # The output port list consists only of port:proto for
80 # everything that we don't recognize, and special options for
81 # those that we do.
82 retval += "# Firewall configuration\nfirewall --enabled%s%s%s\n" % (extrastr, portstr, truststr)
83 else:
84 retval += "# Firewall configuration\nfirewall --disabled\n"
85
86 return retval
87
88 def _getParser(self):
89 def firewall_port_cb (option, opt_str, value, parser):
90 for p in value.split(","):
91 p = p.strip()
92 if p.find(":") == -1:
93 p = "%s:tcp" % p
94 parser.values.ensure_value(option.dest, []).append(p)
95
96 op = KSOptionParser(mapping={"ssh":["22:tcp"], "telnet":["23:tcp"],
97 "smtp":["25:tcp"], "http":["80:tcp", "443:tcp"],
98 "ftp":["21:tcp"]})
99
100 op.add_option("--disable", "--disabled", dest="enabled",
101 action="store_false")
102 op.add_option("--enable", "--enabled", dest="enabled",
103 action="store_true", default=True)
104 op.add_option("--ftp", "--http", "--smtp", "--ssh", "--telnet",
105 dest="ports", action="map_extend")
106 op.add_option("--high", deprecated=1)
107 op.add_option("--medium", deprecated=1)
108 op.add_option("--port", dest="ports", action="callback",
109 callback=firewall_port_cb, nargs=1, type="string")
110 op.add_option("--trust", dest="trusts", action="append")
111 return op
112
113 def parse(self, args):
114 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
115
116 if len(extra) != 0:
117 mapping = {"command": "firewall", "options": extra}
118 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
119
120 self._setToSelf(self.op, opts)
121 return self
122
123class F9_Firewall(FC3_Firewall):
124 removedKeywords = FC3_Firewall.removedKeywords
125 removedAttrs = FC3_Firewall.removedAttrs
126
127 def _getParser(self):
128 op = FC3_Firewall._getParser(self)
129 op.remove_option("--high")
130 op.remove_option("--medium")
131 return op
132
133class F10_Firewall(F9_Firewall):
134 removedKeywords = F9_Firewall.removedKeywords
135 removedAttrs = F9_Firewall.removedAttrs
136
137 def __init__(self, writePriority=0, *args, **kwargs):
138 F9_Firewall.__init__(self, writePriority, *args, **kwargs)
139 self.services = kwargs.get("services", [])
140
141 def __str__(self):
142 if self.enabled is None:
143 return ""
144
145 retval = F9_Firewall.__str__(self)
146 if self.enabled:
147 retval = retval.strip()
148
149 svcstr = ",".join(self.services)
150 if len(svcstr) > 0:
151 svcstr = " --service=" + svcstr
152 else:
153 svcstr = ""
154
155 return retval + "%s\n" % svcstr
156 else:
157 return retval
158
159 def _getParser(self):
160 def service_cb (option, opt_str, value, parser):
161 # python2.4 does not support action="append_const" that we were
162 # using for these options. Instead, we have to fake it by
163 # appending whatever the option string is to the service list.
164 if not value:
165 parser.values.ensure_value(option.dest, []).append(opt_str[2:])
166 return
167
168 for p in value.split(","):
169 p = p.strip()
170 parser.values.ensure_value(option.dest, []).append(p)
171
172 op = F9_Firewall._getParser(self)
173 op.add_option("--service", dest="services", action="callback",
174 callback=service_cb, nargs=1, type="string")
175 op.add_option("--ftp", dest="services", action="callback",
176 callback=service_cb)
177 op.add_option("--http", dest="services", action="callback",
178 callback=service_cb)
179 op.add_option("--smtp", dest="services", action="callback",
180 callback=service_cb)
181 op.add_option("--ssh", dest="services", action="callback",
182 callback=service_cb)
183 op.add_option("--telnet", deprecated=1)
184 return op
185
186class F14_Firewall(F10_Firewall):
187 removedKeywords = F10_Firewall.removedKeywords + ["telnet"]
188 removedAttrs = F10_Firewall.removedAttrs + ["telnet"]
189
190 def _getParser(self):
191 op = F10_Firewall._getParser(self)
192 op.remove_option("--telnet")
193 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/firstboot.py b/scripts/lib/mic/3rdparty/pykickstart/commands/firstboot.py
new file mode 100644
index 0000000000..05c0ac11c6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/firstboot.py
@@ -0,0 +1,62 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.options import *
23
24class FC3_Firstboot(KickstartCommand):
25 removedKeywords = KickstartCommand.removedKeywords
26 removedAttrs = KickstartCommand.removedAttrs
27
28 def __init__(self, writePriority=0, *args, **kwargs):
29 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
30 self.op = self._getParser()
31
32 self.firstboot = kwargs.get("firstboot", None)
33
34 def __str__(self):
35 retval = KickstartCommand.__str__(self)
36
37 if self.firstboot is None:
38 return retval
39
40 if self.firstboot == FIRSTBOOT_SKIP:
41 retval += "firstboot --disable\n"
42 elif self.firstboot == FIRSTBOOT_DEFAULT:
43 retval += "# Run the Setup Agent on first boot\nfirstboot --enable\n"
44 elif self.firstboot == FIRSTBOOT_RECONFIG:
45 retval += "# Run the Setup Agent on first boot\nfirstboot --reconfig\n"
46
47 return retval
48
49 def _getParser(self):
50 op = KSOptionParser()
51 op.add_option("--disable", "--disabled", dest="firstboot",
52 action="store_const", const=FIRSTBOOT_SKIP)
53 op.add_option("--enable", "--enabled", dest="firstboot",
54 action="store_const", const=FIRSTBOOT_DEFAULT)
55 op.add_option("--reconfig", dest="firstboot", action="store_const",
56 const=FIRSTBOOT_RECONFIG)
57 return op
58
59 def parse(self, args):
60 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
61 self.firstboot = opts.firstboot
62 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/group.py b/scripts/lib/mic/3rdparty/pykickstart/commands/group.py
new file mode 100644
index 0000000000..80ba5bdca6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/group.py
@@ -0,0 +1,88 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26import warnings
27_ = lambda x: gettext.ldgettext("pykickstart", x)
28
29class F12_GroupData(BaseData):
30 removedKeywords = BaseData.removedKeywords
31 removedAttrs = BaseData.removedAttrs
32
33 def __init__(self, *args, **kwargs):
34 BaseData.__init__(self, *args, **kwargs)
35 self.name = kwargs.get("name", "")
36 self.gid = kwargs.get("gid", None)
37
38 def __eq__(self, y):
39 return self.name == y.name
40
41 def __str__(self):
42 retval = BaseData.__str__(self)
43 retval += "group"
44
45 if self.name:
46 retval += " --name=%s" % self.name
47 if self.gid:
48 retval += " --gid=%s" % self.gid
49
50 return retval + "\n"
51
52class F12_Group(KickstartCommand):
53 removedKeywords = KickstartCommand.removedKeywords
54 removedAttrs = KickstartCommand.removedAttrs
55
56 def __init__(self, writePriority=0, *args, **kwargs):
57 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
58 self.op = self._getParser()
59
60 self.groupList = kwargs.get("groupList", [])
61
62 def __str__(self):
63 retval = ""
64 for user in self.groupList:
65 retval += user.__str__()
66
67 return retval
68
69 def _getParser(self):
70 op = KSOptionParser()
71 op.add_option("--name", required=1)
72 op.add_option("--gid", type="int")
73 return op
74
75 def parse(self, args):
76 gd = self.handler.GroupData()
77 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
78 self._setToObj(self.op, opts, gd)
79 gd.lineno = self.lineno
80
81 # Check for duplicates in the data list.
82 if gd in self.dataList():
83 warnings.warn(_("A group with the name %s has already been defined.") % gd.name)
84
85 return gd
86
87 def dataList(self):
88 return self.groupList
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/ignoredisk.py b/scripts/lib/mic/3rdparty/pykickstart/commands/ignoredisk.py
new file mode 100644
index 0000000000..676d080836
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/ignoredisk.py
@@ -0,0 +1,139 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24_ = lambda x: gettext.ldgettext("pykickstart", x)
25
26class FC3_IgnoreDisk(KickstartCommand):
27 removedKeywords = KickstartCommand.removedKeywords
28 removedAttrs = KickstartCommand.removedAttrs
29
30 def __init__(self, writePriority=0, *args, **kwargs):
31 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
32 self.op = self._getParser()
33
34 self.ignoredisk = kwargs.get("ignoredisk", [])
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if len(self.ignoredisk) > 0:
40 retval += "ignoredisk --drives=%s\n" % ",".join(self.ignoredisk)
41
42 return retval
43
44 def _getParser(self):
45 def drive_cb (option, opt_str, value, parser):
46 for d in value.split(','):
47 parser.values.ensure_value(option.dest, []).append(d)
48
49 op = KSOptionParser()
50 op.add_option("--drives", dest="ignoredisk", action="callback",
51 callback=drive_cb, nargs=1, type="string", required=1)
52 return op
53
54 def parse(self, args):
55 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
56 self._setToSelf(self.op, opts)
57 return self
58
59class F8_IgnoreDisk(FC3_IgnoreDisk):
60 removedKeywords = FC3_IgnoreDisk.removedKeywords
61 removedAttrs = FC3_IgnoreDisk.removedAttrs
62
63 def __init__(self, writePriority=0, *args, **kwargs):
64 FC3_IgnoreDisk.__init__(self, writePriority, *args, **kwargs)
65
66 self.onlyuse = kwargs.get("onlyuse", [])
67
68 def __str__(self):
69 retval = KickstartCommand.__str__(self)
70
71 if len(self.ignoredisk) > 0:
72 retval += "ignoredisk --drives=%s\n" % ",".join(self.ignoredisk)
73 elif len(self.onlyuse) > 0:
74 retval += "ignoredisk --only-use=%s\n" % ",".join(self.onlyuse)
75
76 return retval
77
78 def parse(self, args, errorCheck=True):
79 retval = FC3_IgnoreDisk.parse(self, args)
80
81 if errorCheck:
82 if (len(self.ignoredisk) == 0 and len(self.onlyuse) == 0) or (len(self.ignoredisk) > 0 and (len(self.onlyuse) > 0)):
83 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of --drives or --only-use must be specified for ignoredisk command."))
84
85 return retval
86
87 def _getParser(self):
88 def drive_cb (option, opt_str, value, parser):
89 for d in value.split(','):
90 parser.values.ensure_value(option.dest, []).append(d)
91
92 op = FC3_IgnoreDisk._getParser(self)
93 op.add_option("--drives", dest="ignoredisk", action="callback",
94 callback=drive_cb, nargs=1, type="string")
95 op.add_option("--only-use", dest="onlyuse", action="callback",
96 callback=drive_cb, nargs=1, type="string")
97 return op
98
99class RHEL6_IgnoreDisk(F8_IgnoreDisk):
100 removedKeywords = F8_IgnoreDisk.removedKeywords
101 removedAttrs = F8_IgnoreDisk.removedAttrs
102
103 def __init__(self, writePriority=0, *args, **kwargs):
104 F8_IgnoreDisk.__init__(self, writePriority, *args, **kwargs)
105
106 self.interactive = kwargs.get("interactive", False)
107 if self.interactive:
108 self.ignoredisk = []
109
110 def __str__(self):
111 retval = F8_IgnoreDisk.__str__(self)
112
113 if self.interactive:
114 retval = "ignoredisk --interactive\n"
115
116 return retval
117
118 def parse(self, args):
119 retval = F8_IgnoreDisk.parse(self, args, errorCheck=False)
120
121 howmany = 0
122 if len(self.ignoredisk) > 0:
123 howmany += 1
124 if len(self.onlyuse) > 0:
125 howmany += 1
126 if self.interactive:
127 howmany += 1
128 if howmany != 1:
129 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of --drives , --only-use , or --interactive must be specified for ignoredisk command."))
130
131 return retval
132
133 def _getParser(self):
134 op = F8_IgnoreDisk._getParser(self)
135 op.add_option("--interactive", dest="interactive", action="store_true",
136 default=False)
137 return op
138
139F14_IgnoreDisk = RHEL6_IgnoreDisk
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/interactive.py b/scripts/lib/mic/3rdparty/pykickstart/commands/interactive.py
new file mode 100644
index 0000000000..fa3dc025b1
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/interactive.py
@@ -0,0 +1,58 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Interactive(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.interactive = kwargs.get("interactive", False)
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.interactive:
40 retval += "# Use interactive kickstart installation method\ninteractive\n"
41
42 return retval
43
44 def _getParser(self):
45 op = KSOptionParser()
46 return op
47
48 def parse(self, args):
49 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
50 if len(extra) > 0:
51 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "interactive")
52
53 self.interactive = True
54 return self
55
56class F14_Interactive(DeprecatedCommand):
57 def __init__(self):
58 DeprecatedCommand.__init__(self)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/iscsi.py b/scripts/lib/mic/3rdparty/pykickstart/commands/iscsi.py
new file mode 100644
index 0000000000..da5a544e86
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/iscsi.py
@@ -0,0 +1,133 @@
1#
2# Chris Lumens <clumens@redhat.com>
3# Peter Jones <pjones@redhat.com>
4#
5# Copyright 2005, 2006, 2007 Red Hat, Inc.
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
17# trademarks that are incorporated in the source code or documentation are not
18# subject to the GNU General Public License and may only be used or replicated
19# with the express permission of Red Hat, Inc.
20#
21from pykickstart.base import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC6_IscsiData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
31
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.ipaddr = kwargs.get("ipaddr", "")
35 self.port = kwargs.get("port", "3260")
36 self.target = kwargs.get("target", "")
37 self.user = kwargs.get("user", None)
38 self.password = kwargs.get("password", None)
39
40 def _getArgsAsStr(self):
41 retval = ""
42
43 if self.target != "":
44 retval += " --target=%s" % self.target
45 if self.ipaddr != "":
46 retval += " --ipaddr=%s" % self.ipaddr
47 if self.port != "3260":
48 retval += " --port=%s" % self.port
49 if self.user is not None:
50 retval += " --user=%s" % self.user
51 if self.password is not None:
52 retval += " --password=%s" % self.password
53
54 return retval
55
56 def __str__(self):
57 retval = BaseData.__str__(self)
58 retval += "iscsi%s\n" % self._getArgsAsStr()
59 return retval
60
61class F10_IscsiData(FC6_IscsiData):
62 removedKeywords = FC6_IscsiData.removedKeywords
63 removedAttrs = FC6_IscsiData.removedAttrs
64
65 def __init__(self, *args, **kwargs):
66 FC6_IscsiData.__init__(self, *args, **kwargs)
67 self.user_in = kwargs.get("user_in", None)
68 self.password_in = kwargs.get("password_in", None)
69
70 def _getArgsAsStr(self):
71 retval = FC6_IscsiData._getArgsAsStr(self)
72
73 if self.user_in is not None:
74 retval += " --reverse-user=%s" % self.user_in
75 if self.password_in is not None:
76 retval += " --reverse-password=%s" % self.password_in
77
78 return retval
79
80class FC6_Iscsi(KickstartCommand):
81 removedKeywords = KickstartCommand.removedKeywords
82 removedAttrs = KickstartCommand.removedAttrs
83
84 def __init__(self, writePriority=71, *args, **kwargs):
85 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
86 self.op = self._getParser()
87
88 self.iscsi = kwargs.get("iscsi", [])
89
90 def __str__(self):
91 retval = ""
92 for iscsi in self.iscsi:
93 retval += iscsi.__str__()
94
95 return retval
96
97 def _getParser(self):
98 op = KSOptionParser()
99 op.add_option("--target", dest="target", action="store", type="string")
100 op.add_option("--ipaddr", dest="ipaddr", action="store", type="string",
101 required=1)
102 op.add_option("--port", dest="port", action="store", type="string")
103 op.add_option("--user", dest="user", action="store", type="string")
104 op.add_option("--password", dest="password", action="store",
105 type="string")
106 return op
107
108 def parse(self, args):
109 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
110
111 if len(extra) != 0:
112 mapping = {"command": "iscsi", "options": extra}
113 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
114
115 dd = self.handler.IscsiData()
116 self._setToObj(self.op, opts, dd)
117 dd.lineno = self.lineno
118 return dd
119
120 def dataList(self):
121 return self.iscsi
122
123class F10_Iscsi(FC6_Iscsi):
124 removedKeywords = FC6_Iscsi.removedKeywords
125 removedAttrs = FC6_Iscsi.removedAttrs
126
127 def _getParser(self):
128 op = FC6_Iscsi._getParser(self)
129 op.add_option("--reverse-user", dest="user_in", action="store",
130 type="string")
131 op.add_option("--reverse-password", dest="password_in", action="store",
132 type="string")
133 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/iscsiname.py b/scripts/lib/mic/3rdparty/pykickstart/commands/iscsiname.py
new file mode 100644
index 0000000000..a87d0637d6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/iscsiname.py
@@ -0,0 +1,54 @@
1#
2# Chris Lumens <clumens@redhat.com>
3# Peter Jones <pjones@redhat.com>
4#
5# Copyright 2006, 2007 Red Hat, Inc.
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
17# trademarks that are incorporated in the source code or documentation are not
18# subject to the GNU General Public License and may only be used or replicated
19# with the express permission of Red Hat, Inc.
20#
21from pykickstart.base import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC6_IscsiName(KickstartCommand):
29 removedKeywords = KickstartCommand.removedKeywords
30 removedAttrs = KickstartCommand.removedAttrs
31
32 def __init__(self, writePriority=70, *args, **kwargs):
33 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
34 self.op = self._getParser()
35 self.iscsiname = kwargs.get("iscsiname", "")
36
37 def __str__(self):
38 retval = KickstartCommand.__str__(self)
39
40 if self.iscsiname != "":
41 retval += "iscsiname %s\n" % self.iscsiname
42
43 return retval
44
45 def _getParser(self):
46 op = KSOptionParser()
47 return op
48
49 def parse(self, args):
50 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
51 if len(extra) != 1:
52 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "iscsiname")
53 self.iscsiname = extra[0]
54 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/key.py b/scripts/lib/mic/3rdparty/pykickstart/commands/key.py
new file mode 100644
index 0000000000..c20c4231f6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/key.py
@@ -0,0 +1,64 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class RHEL5_Key(KickstartCommand):
29 removedKeywords = KickstartCommand.removedKeywords
30 removedAttrs = KickstartCommand.removedAttrs
31
32 def __init__(self, writePriority=0, *args, **kwargs):
33 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
34 self.op = self._getParser()
35 self.key = kwargs.get("key", "")
36 self.skip = kwargs.get("skip", False)
37
38 def __str__(self):
39 retval = KickstartCommand.__str__(self)
40
41 if self.key == KS_INSTKEY_SKIP:
42 retval += "key --skip\n"
43 elif self.key != "":
44 retval += "key %s\n" % self.key
45
46 return retval
47
48 def _getParser(self):
49 op = KSOptionParser()
50 op.add_option("--skip", action="store_true", default=False)
51 return op
52
53 def parse(self, args):
54 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
55 self._setToSelf(self.op, opts)
56
57 if self.skip:
58 self.key = KS_INSTKEY_SKIP
59 elif len(extra) != 1:
60 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "key")
61 else:
62 self.key = extra[0]
63
64 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/keyboard.py b/scripts/lib/mic/3rdparty/pykickstart/commands/keyboard.py
new file mode 100644
index 0000000000..babc2acd4c
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/keyboard.py
@@ -0,0 +1,55 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Keyboard(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.keyboard = kwargs.get("keyboard", "")
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.keyboard != "":
40 retval += "# System keyboard\nkeyboard %s\n" % self.keyboard
41
42 return retval
43
44 def _getParser(self):
45 op = KSOptionParser()
46 return op
47
48 def parse(self, args):
49 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
50
51 if len(extra) != 1:
52 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "keyboard")
53
54 self.keyboard = extra[0]
55 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/lang.py b/scripts/lib/mic/3rdparty/pykickstart/commands/lang.py
new file mode 100644
index 0000000000..cf5e46cda7
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/lang.py
@@ -0,0 +1,60 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Lang(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.lang = kwargs.get("lang", "")
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.lang != "":
40 retval += "# System language\nlang %s\n" % self.lang
41
42 return retval
43
44 def _getParser(self):
45 op = KSOptionParser()
46 return op
47
48 def parse(self, args):
49 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
50 if len(extra) != 1:
51 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "lang")
52
53 self.lang = extra[0]
54 return self
55
56 def apply(self, instroot="/"):
57 if self.lang == "": return
58 f = open(instroot + "/etc/sysconfig/i18n", "w+")
59 f.write("LANG=\"%s\"\n" %(self.lang,))
60 f.close()
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/langsupport.py b/scripts/lib/mic/3rdparty/pykickstart/commands/langsupport.py
new file mode 100644
index 0000000000..73a9e537a9
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/langsupport.py
@@ -0,0 +1,58 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23class FC3_LangSupport(KickstartCommand):
24 removedKeywords = KickstartCommand.removedKeywords
25 removedAttrs = KickstartCommand.removedAttrs
26
27 def __init__(self, writePriority=0, *args, **kwargs):
28 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
29 self.op = self._getParser()
30
31 self.deflang = kwargs.get("deflang", "")
32 self.supported = kwargs.get("supported", [])
33
34 def __str__(self):
35 retval = KickstartCommand.__str__(self)
36
37 if self.deflang:
38 retval += "langsupport --default=%s" % self.deflang
39
40 if self.supported:
41 retval += " %s" % " ".join(self.supported)
42
43 return retval + "\n"
44
45 def _getParser(self):
46 op = KSOptionParser()
47 op.add_option("--default", dest="deflang", default="en_US.UTF-8")
48 return op
49
50 def parse(self, args):
51 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
52 self._setToSelf(self.op, opts)
53 self.supported = extra
54 return self
55
56class FC5_LangSupport(DeprecatedCommand):
57 def __init__(self):
58 DeprecatedCommand.__init__(self)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/lilocheck.py b/scripts/lib/mic/3rdparty/pykickstart/commands/lilocheck.py
new file mode 100644
index 0000000000..92b3f930b6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/lilocheck.py
@@ -0,0 +1,54 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_LiloCheck(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.check = kwargs.get("check", False)
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.check:
40 retval += "lilocheck\n"
41
42 return retval
43
44 def _getParser(self):
45 op = KSOptionParser()
46 return op
47
48 def parse(self, args):
49 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
50 if len(extra) > 0:
51 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "lilocheck")
52
53 self.check = True
54 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/logging.py b/scripts/lib/mic/3rdparty/pykickstart/commands/logging.py
new file mode 100644
index 0000000000..698561994d
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/logging.py
@@ -0,0 +1,66 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007, 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC6_Logging(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.host = kwargs.get("host", "")
36 self.level = kwargs.get("level", "info")
37 self.port = kwargs.get("port", "")
38
39 def __str__(self):
40 retval = KickstartCommand.__str__(self)
41 retval += "# Installation logging level\nlogging --level=%s" % self.level
42
43 if self.host != "":
44 retval += " --host=%s" % self.host
45
46 if self.port != "":
47 retval += " --port=%s" % self.port
48
49 return retval + "\n"
50
51 def _getParser(self):
52 op = KSOptionParser()
53 op.add_option("--host")
54 op.add_option("--level", type="choice", default="info",
55 choices=["debug", "info", "warning", "error", "critical"])
56 op.add_option("--port")
57 return op
58
59 def parse(self, args):
60 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
61
62 if opts.port and not opts.host:
63 raise KickstartParseError, formatErrorMsg(self.lineno, msg=_("Can't specify --port without --host."))
64
65 self._setToSelf(self.op, opts)
66 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/logvol.py b/scripts/lib/mic/3rdparty/pykickstart/commands/logvol.py
new file mode 100644
index 0000000000..c1b9cc3a61
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/logvol.py
@@ -0,0 +1,304 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25import warnings
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC3_LogVolData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
31
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.fstype = kwargs.get("fstype", "")
35 self.grow = kwargs.get("grow", False)
36 self.maxSizeMB = kwargs.get("maxSizeMB", 0)
37 self.name = kwargs.get("name", "")
38 self.format = kwargs.get("format", True)
39 self.percent = kwargs.get("percent", 0)
40 self.recommended = kwargs.get("recommended", False)
41 self.size = kwargs.get("size", None)
42 self.preexist = kwargs.get("preexist", False)
43 self.vgname = kwargs.get("vgname", "")
44 self.mountpoint = kwargs.get("mountpoint", "")
45
46 def __eq__(self, y):
47 return self.vgname == y.vgname and self.name == y.name
48
49 def _getArgsAsStr(self):
50 retval = ""
51
52 if self.fstype != "":
53 retval += " --fstype=\"%s\"" % self.fstype
54 if self.grow:
55 retval += " --grow"
56 if self.maxSizeMB > 0:
57 retval += " --maxsize=%d" % self.maxSizeMB
58 if not self.format:
59 retval += " --noformat"
60 if self.percent > 0:
61 retval += " --percent=%d" % self.percent
62 if self.recommended:
63 retval += " --recommended"
64 if self.size > 0:
65 retval += " --size=%d" % self.size
66 if self.preexist:
67 retval += " --useexisting"
68
69 return retval
70
71 def __str__(self):
72 retval = BaseData.__str__(self)
73 retval += "logvol %s %s --name=%s --vgname=%s\n" % (self.mountpoint, self._getArgsAsStr(), self.name, self.vgname)
74 return retval
75
76class FC4_LogVolData(FC3_LogVolData):
77 removedKeywords = FC3_LogVolData.removedKeywords
78 removedAttrs = FC3_LogVolData.removedAttrs
79
80 def __init__(self, *args, **kwargs):
81 FC3_LogVolData.__init__(self, *args, **kwargs)
82 self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
83 self.fsopts = kwargs.get("fsopts", "")
84
85 def _getArgsAsStr(self):
86 retval = FC3_LogVolData._getArgsAsStr(self)
87
88 if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
89 retval += " --bytes-per-inode=%d" % self.bytesPerInode
90 if self.fsopts != "":
91 retval += " --fsoptions=\"%s\"" % self.fsopts
92
93 return retval
94
95class RHEL5_LogVolData(FC4_LogVolData):
96 removedKeywords = FC4_LogVolData.removedKeywords
97 removedAttrs = FC4_LogVolData.removedAttrs
98
99 def __init__(self, *args, **kwargs):
100 FC4_LogVolData.__init__(self, *args, **kwargs)
101 self.encrypted = kwargs.get("encrypted", False)
102 self.passphrase = kwargs.get("passphrase", "")
103
104 def _getArgsAsStr(self):
105 retval = FC4_LogVolData._getArgsAsStr(self)
106
107 if self.encrypted:
108 retval += " --encrypted"
109
110 if self.passphrase != "":
111 retval += " --passphrase=\"%s\"" % self.passphrase
112
113 return retval
114
115class F9_LogVolData(FC4_LogVolData):
116 removedKeywords = FC4_LogVolData.removedKeywords + ["bytesPerInode"]
117 removedAttrs = FC4_LogVolData.removedAttrs + ["bytesPerInode"]
118
119 def __init__(self, *args, **kwargs):
120 FC4_LogVolData.__init__(self, *args, **kwargs)
121 self.deleteRemovedAttrs()
122
123 self.fsopts = kwargs.get("fsopts", "")
124 self.fsprofile = kwargs.get("fsprofile", "")
125 self.encrypted = kwargs.get("encrypted", False)
126 self.passphrase = kwargs.get("passphrase", "")
127
128 def _getArgsAsStr(self):
129 retval = FC4_LogVolData._getArgsAsStr(self)
130
131 if self.fsprofile != "":
132 retval += " --fsprofile=\"%s\"" % self.fsprofile
133 if self.encrypted:
134 retval += " --encrypted"
135
136 if self.passphrase != "":
137 retval += " --passphrase=\"%s\"" % self.passphrase
138
139 return retval
140
141class F12_LogVolData(F9_LogVolData):
142 removedKeywords = F9_LogVolData.removedKeywords
143 removedAttrs = F9_LogVolData.removedAttrs
144
145 def __init__(self, *args, **kwargs):
146 F9_LogVolData.__init__(self, *args, **kwargs)
147 self.deleteRemovedAttrs()
148
149 self.escrowcert = kwargs.get("escrowcert", "")
150 self.backuppassphrase = kwargs.get("backuppassphrase", False)
151
152 def _getArgsAsStr(self):
153 retval = F9_LogVolData._getArgsAsStr(self)
154
155 if self.encrypted and self.escrowcert != "":
156 retval += " --escrowcert=\"%s\"" % self.escrowcert
157
158 if self.backuppassphrase:
159 retval += " --backuppassphrase"
160
161 return retval
162
163F14_LogVolData = F12_LogVolData
164
165class F15_LogVolData(F14_LogVolData):
166 removedKeywords = F14_LogVolData.removedKeywords
167 removedAttrs = F14_LogVolData.removedAttrs
168
169 def __init__(self, *args, **kwargs):
170 F14_LogVolData.__init__(self, *args, **kwargs)
171 self.label = kwargs.get("label", "")
172
173 def _getArgsAsStr(self):
174 retval = F14_LogVolData._getArgsAsStr(self)
175
176 if self.label != "":
177 retval += " --label=\"%s\"" % self.label
178
179 return retval
180
181class FC3_LogVol(KickstartCommand):
182 removedKeywords = KickstartCommand.removedKeywords
183 removedAttrs = KickstartCommand.removedAttrs
184
185 def __init__(self, writePriority=133, *args, **kwargs):
186 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
187 self.op = self._getParser()
188
189 self.lvList = kwargs.get("lvList", [])
190
191 def __str__(self):
192 retval = ""
193
194 for part in self.lvList:
195 retval += part.__str__()
196
197 return retval
198
199 def _getParser(self):
200 def lv_cb (option, opt_str, value, parser):
201 parser.values.format = False
202 parser.values.preexist = True
203
204 op = KSOptionParser()
205 op.add_option("--fstype", dest="fstype")
206 op.add_option("--grow", dest="grow", action="store_true",
207 default=False)
208 op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
209 nargs=1)
210 op.add_option("--name", dest="name", required=1)
211 op.add_option("--noformat", action="callback", callback=lv_cb,
212 dest="format", default=True, nargs=0)
213 op.add_option("--percent", dest="percent", action="store", type="int",
214 nargs=1)
215 op.add_option("--recommended", dest="recommended", action="store_true",
216 default=False)
217 op.add_option("--size", dest="size", action="store", type="int",
218 nargs=1)
219 op.add_option("--useexisting", dest="preexist", action="store_true",
220 default=False)
221 op.add_option("--vgname", dest="vgname", required=1)
222 return op
223
224 def parse(self, args):
225 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
226
227 if len(extra) == 0:
228 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "logvol")
229
230 lvd = self.handler.LogVolData()
231 self._setToObj(self.op, opts, lvd)
232 lvd.lineno = self.lineno
233 lvd.mountpoint=extra[0]
234
235 # Check for duplicates in the data list.
236 if lvd in self.dataList():
237 warnings.warn(_("A logical volume with the name %s has already been defined in volume group %s.") % (lvd.device, lvd.vgname))
238
239 return lvd
240
241 def dataList(self):
242 return self.lvList
243
244class FC4_LogVol(FC3_LogVol):
245 removedKeywords = FC3_LogVol.removedKeywords
246 removedAttrs = FC3_LogVol.removedAttrs
247
248 def _getParser(self):
249 op = FC3_LogVol._getParser(self)
250 op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
251 type="int", nargs=1)
252 op.add_option("--fsoptions", dest="fsopts")
253 return op
254
255class RHEL5_LogVol(FC4_LogVol):
256 removedKeywords = FC4_LogVol.removedKeywords
257 removedAttrs = FC4_LogVol.removedAttrs
258
259 def _getParser(self):
260 op = FC4_LogVol._getParser(self)
261 op.add_option("--encrypted", action="store_true", default=False)
262 op.add_option("--passphrase")
263 return op
264
265class F9_LogVol(FC4_LogVol):
266 removedKeywords = FC4_LogVol.removedKeywords
267 removedAttrs = FC4_LogVol.removedAttrs
268
269 def _getParser(self):
270 op = FC4_LogVol._getParser(self)
271 op.add_option("--bytes-per-inode", deprecated=1)
272 op.add_option("--fsprofile", dest="fsprofile", action="store",
273 type="string", nargs=1)
274 op.add_option("--encrypted", action="store_true", default=False)
275 op.add_option("--passphrase")
276 return op
277
278class F12_LogVol(F9_LogVol):
279 removedKeywords = F9_LogVol.removedKeywords
280 removedAttrs = F9_LogVol.removedAttrs
281
282 def _getParser(self):
283 op = F9_LogVol._getParser(self)
284 op.add_option("--escrowcert")
285 op.add_option("--backuppassphrase", action="store_true", default=False)
286 return op
287
288class F14_LogVol(F12_LogVol):
289 removedKeywords = F12_LogVol.removedKeywords
290 removedAttrs = F12_LogVol.removedAttrs
291
292 def _getParser(self):
293 op = F12_LogVol._getParser(self)
294 op.remove_option("--bytes-per-inode")
295 return op
296
297class F15_LogVol(F14_LogVol):
298 removedKeywords = F14_LogVol.removedKeywords
299 removedAttrs = F14_LogVol.removedAttrs
300
301 def _getParser(self):
302 op = F14_LogVol._getParser(self)
303 op.add_option("--label")
304 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/mediacheck.py b/scripts/lib/mic/3rdparty/pykickstart/commands/mediacheck.py
new file mode 100644
index 0000000000..388823a839
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/mediacheck.py
@@ -0,0 +1,53 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC4_MediaCheck(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.mediacheck = kwargs.get("mediacheck", False)
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38 if self.mediacheck:
39 retval += "mediacheck\n"
40
41 return retval
42
43 def _getParser(self):
44 op = KSOptionParser()
45 return op
46
47 def parse(self, args):
48 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
49 if len(extra) > 0:
50 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "mediacheck")
51
52 self.mediacheck = True
53 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/method.py b/scripts/lib/mic/3rdparty/pykickstart/commands/method.py
new file mode 100644
index 0000000000..e21064acda
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/method.py
@@ -0,0 +1,186 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007, 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Method(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.method = kwargs.get("method", "")
34
35 # Set all these attributes so calls to this command's __call__
36 # method can set them. However we don't want to provide them as
37 # arguments to __init__ because method is special.
38 self.biospart = None
39 self.partition = None
40 self.server = None
41 self.dir = None
42 self.url = None
43
44 def __str__(self):
45 retval = KickstartCommand.__str__(self)
46
47 if self.method == "cdrom":
48 retval += "# Use CDROM installation media\ncdrom\n"
49 elif self.method == "harddrive":
50 msg = "# Use hard drive installation media\nharddrive --dir=%s" % self.dir
51
52 if self.biospart is not None:
53 retval += msg + " --biospart=%s\n" % self.biospart
54 else:
55 retval += msg + " --partition=%s\n" % self.partition
56 elif self.method == "nfs":
57 retval += "# Use NFS installation media\nnfs --server=%s --dir=%s\n" % (self.server, self.dir)
58 elif self.method == "url":
59 retval += "# Use network installation\nurl --url=\"%s\"\n" % self.url
60
61 return retval
62
63 def _getParser(self):
64 op = KSOptionParser()
65
66 # method = "cdrom" falls through to the return
67 if self.currentCmd == "harddrive":
68 op.add_option("--biospart", dest="biospart")
69 op.add_option("--partition", dest="partition")
70 op.add_option("--dir", dest="dir", required=1)
71 elif self.currentCmd == "nfs":
72 op.add_option("--server", dest="server", required=1)
73 op.add_option("--dir", dest="dir", required=1)
74 elif self.currentCmd == "url":
75 op.add_option("--url", dest="url", required=1)
76
77 return op
78
79 def parse(self, args):
80 self.method = self.currentCmd
81
82 op = self._getParser()
83 (opts, extra) = op.parse_args(args=args, lineno=self.lineno)
84 self._setToSelf(op, opts)
85
86 if self.currentCmd == "harddrive":
87 if self.biospart is None and self.partition is None or \
88 self.biospart is not None and self.partition is not None:
89 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of biospart or partition options must be specified."))
90
91 return self
92
93class FC6_Method(FC3_Method):
94 removedKeywords = FC3_Method.removedKeywords
95 removedAttrs = FC3_Method.removedAttrs
96
97 def __init__(self, writePriority=0, *args, **kwargs):
98 FC3_Method.__init__(self, writePriority, *args, **kwargs)
99
100 # Same reason for this attribute as the comment in FC3_Method.
101 self.opts = None
102
103 def __str__(self):
104 retval = KickstartCommand.__str__(self)
105
106 if self.method == "cdrom":
107 retval += "# Use CDROM installation media\ncdrom\n"
108 elif self.method == "harddrive":
109 msg = "# Use hard drive installation media\nharddrive --dir=%s" % self.dir
110
111 if self.biospart is not None:
112 retval += msg + " --biospart=%s\n" % self.biospart
113 else:
114 retval += msg + " --partition=%s\n" % self.partition
115 elif self.method == "nfs":
116 retval += "# Use NFS installation media\nnfs --server=%s --dir=%s" % (self.server, self.dir)
117 if self.opts is not None:
118 retval += " --opts=\"%s\"" % self.opts
119 retval += "\n"
120 elif self.method == "url":
121 retval += "# Use network installation\nurl --url=\"%s\"\n" % self.url
122
123 return retval
124
125 def _getParser(self):
126 op = FC3_Method._getParser(self)
127
128 if self.currentCmd == "nfs":
129 op.add_option("--opts", dest="opts")
130
131 return op
132
133class F13_Method(FC6_Method):
134 removedKeywords = FC6_Method.removedKeywords
135 removedAttrs = FC6_Method.removedAttrs
136
137 def __init__(self, *args, **kwargs):
138 FC6_Method.__init__(self, *args, **kwargs)
139
140 # And same as all the other __init__ methods.
141 self.proxy = ""
142
143 def __str__(self):
144 retval = FC6_Method.__str__(self)
145
146 if self.method == "url" and self.proxy:
147 retval = retval.strip()
148 retval += " --proxy=\"%s\"\n" % self.proxy
149
150 return retval
151
152 def _getParser(self):
153 op = FC6_Method._getParser(self)
154
155 if self.currentCmd == "url":
156 op.add_option("--proxy")
157
158 return op
159
160class F14_Method(F13_Method):
161 removedKeywords = F13_Method.removedKeywords
162 removedAttrs = F13_Method.removedAttrs
163
164 def __init__(self, *args, **kwargs):
165 F13_Method.__init__(self, *args, **kwargs)
166
167 self.noverifyssl = False
168
169 def __str__(self):
170 retval = F13_Method.__str__(self)
171
172 if self.method == "url" and self.noverifyssl:
173 retval = retval.strip()
174 retval += " --noverifyssl\n"
175
176 return retval
177
178 def _getParser(self):
179 op = F13_Method._getParser(self)
180
181 if self.currentCmd == "url":
182 op.add_option("--noverifyssl", action="store_true", default=False)
183
184 return op
185
186RHEL6_Method = F14_Method
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/monitor.py b/scripts/lib/mic/3rdparty/pykickstart/commands/monitor.py
new file mode 100644
index 0000000000..8c8c2c4fc9
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/monitor.py
@@ -0,0 +1,106 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Monitor(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.hsync = kwargs.get("hsync", "")
36 self.monitor = kwargs.get("monitor", "")
37 self.vsync = kwargs.get("vsync", "")
38
39 def __str__(self):
40 retval = KickstartCommand.__str__(self)
41 retval += "monitor"
42
43 if self.hsync != "":
44 retval += " --hsync=%s" % self.hsync
45 if self.monitor != "":
46 retval += " --monitor=\"%s\"" % self.monitor
47 if self.vsync != "":
48 retval += " --vsync=%s" % self.vsync
49
50 if retval != "monitor":
51 return retval + "\n"
52 else:
53 return ""
54
55 def _getParser(self):
56 op = KSOptionParser()
57 op.add_option("--hsync")
58 op.add_option("--monitor")
59 op.add_option("--vsync")
60 return op
61
62 def parse(self, args):
63 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
64
65 if extra:
66 mapping = {"cmd": "monitor", "options": extra}
67 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(cmd)s command: %(options)s") % mapping)
68
69 self._setToSelf(self.op, opts)
70 return self
71
72class FC6_Monitor(FC3_Monitor):
73 removedKeywords = FC3_Monitor.removedKeywords
74 removedAttrs = FC3_Monitor.removedAttrs
75
76 def __init__(self, writePriority=0, *args, **kwargs):
77 FC3_Monitor.__init__(self, writePriority, *args, **kwargs)
78 self.probe = kwargs.get("probe", True)
79
80 def __str__(self):
81 retval = KickstartCommand.__str__(self)
82 retval += "monitor"
83
84 if self.hsync != "":
85 retval += " --hsync=%s" % self.hsync
86 if self.monitor != "":
87 retval += " --monitor=\"%s\"" % self.monitor
88 if not self.probe:
89 retval += " --noprobe"
90 if self.vsync != "":
91 retval += " --vsync=%s" % self.vsync
92
93 if retval != "monitor":
94 return retval + "\n"
95 else:
96 return ""
97
98 def _getParser(self):
99 op = FC3_Monitor._getParser(self)
100 op.add_option("--noprobe", dest="probe", action="store_false",
101 default=True)
102 return op
103
104class F10_Monitor(DeprecatedCommand):
105 def __init__(self):
106 DeprecatedCommand.__init__(self)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/mouse.py b/scripts/lib/mic/3rdparty/pykickstart/commands/mouse.py
new file mode 100644
index 0000000000..c643bcedc3
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/mouse.py
@@ -0,0 +1,70 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class RHEL3_Mouse(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.device = kwargs.get("device", "")
36 self.emulthree = kwargs.get("emulthree", False)
37 self.mouse = kwargs.get("mouse", "")
38
39 def __str__(self):
40 retval = KickstartCommand.__str__(self)
41
42 opts = ""
43 if self.device:
44 opts += "--device=%s " % self.device
45 if self.emulthree:
46 opts += "--emulthree "
47
48 if self.mouse:
49 retval += "# System mouse\nmouse %s%s\n" % (opts, self.mouse)
50 return retval
51
52 def _getParser(self):
53 op = KSOptionParser()
54 op.add_option("--device", dest="device", default="")
55 op.add_option("--emulthree", dest="emulthree", default=False, action="store_true")
56 return op
57
58 def parse(self, args):
59 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
60 self._setToSelf(self.op, opts)
61
62 if len(extra) != 1:
63 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s requires one argument") % "mouse")
64
65 self.mouse = extra[0]
66 return self
67
68class FC3_Mouse(DeprecatedCommand):
69 def __init__(self):
70 DeprecatedCommand.__init__(self)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/multipath.py b/scripts/lib/mic/3rdparty/pykickstart/commands/multipath.py
new file mode 100644
index 0000000000..84ba755e68
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/multipath.py
@@ -0,0 +1,111 @@
1#
2# Chris Lumens <clumens@redhat.com>
3# Peter Jones <pjones@redhat.com>
4#
5# Copyright 2006, 2007 Red Hat, Inc.
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
17# trademarks that are incorporated in the source code or documentation are not
18# subject to the GNU General Public License and may only be used or replicated
19# with the express permission of Red Hat, Inc.
20#
21from pykickstart.base import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC6_MpPathData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
31
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.mpdev = kwargs.get("mpdev", "")
35 self.device = kwargs.get("device", "")
36 self.rule = kwargs.get("rule", "")
37
38 def __str__(self):
39 return " --device=%s --rule=\"%s\"" % (self.device, self.rule)
40
41class FC6_MultiPathData(BaseData):
42 removedKeywords = BaseData.removedKeywords
43 removedAttrs = BaseData.removedAttrs
44
45 def __init__(self, *args, **kwargs):
46 BaseData.__init__(self, *args, **kwargs)
47 self.name = kwargs.get("name", "")
48 self.paths = kwargs.get("paths", [])
49
50 def __str__(self):
51 retval = BaseData.__str__(self)
52
53 for path in self.paths:
54 retval += "multipath --mpdev=%s %s\n" % (self.name, path.__str__())
55
56 return retval
57
58class FC6_MultiPath(KickstartCommand):
59 removedKeywords = KickstartCommand.removedKeywords
60 removedAttrs = KickstartCommand.removedAttrs
61
62 def __init__(self, writePriority=50, *args, **kwargs):
63 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
64 self.op = self._getParser()
65
66 self.mpaths = kwargs.get("mpaths", [])
67
68 def __str__(self):
69 retval = ""
70 for mpath in self.mpaths:
71 retval += mpath.__str__()
72
73 return retval
74
75 def _getParser(self):
76 op = KSOptionParser()
77 op.add_option("--name", dest="name", action="store", type="string",
78 required=1)
79 op.add_option("--device", dest="device", action="store", type="string",
80 required=1)
81 op.add_option("--rule", dest="rule", action="store", type="string",
82 required=1)
83 return op
84
85 def parse(self, args):
86 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
87 dd = FC6_MpPathData()
88 self._setToObj(self.op, opts, dd)
89 dd.lineno = self.lineno
90 dd.mpdev = dd.mpdev.split('/')[-1]
91
92 parent = None
93 for x in range(0, len(self.mpaths)):
94 mpath = self.mpaths[x]
95 for path in mpath.paths:
96 if path.device == dd.device:
97 mapping = {"device": path.device, "multipathdev": path.mpdev}
98 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Device '%(device)s' is already used in multipath '%(multipathdev)s'") % mapping)
99 if mpath.name == dd.mpdev:
100 parent = x
101
102 if parent is None:
103 mpath = FC6_MultiPathData()
104 return mpath
105 else:
106 mpath = self.mpaths[parent]
107
108 return dd
109
110 def dataList(self):
111 return self.mpaths
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/network.py b/scripts/lib/mic/3rdparty/pykickstart/commands/network.py
new file mode 100644
index 0000000000..9b67f92831
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/network.py
@@ -0,0 +1,363 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26import warnings
27_ = lambda x: gettext.ldgettext("pykickstart", x)
28
29class FC3_NetworkData(BaseData):
30 removedKeywords = BaseData.removedKeywords
31 removedAttrs = BaseData.removedAttrs
32
33 def __init__(self, *args, **kwargs):
34 BaseData.__init__(self, *args, **kwargs)
35 self.bootProto = kwargs.get("bootProto", BOOTPROTO_DHCP)
36 self.dhcpclass = kwargs.get("dhcpclass", "")
37 self.device = kwargs.get("device", "")
38 self.essid = kwargs.get("essid", "")
39 self.ethtool = kwargs.get("ethtool", "")
40 self.gateway = kwargs.get("gateway", "")
41 self.hostname = kwargs.get("hostname", "")
42 self.ip = kwargs.get("ip", "")
43 self.mtu = kwargs.get("mtu", "")
44 self.nameserver = kwargs.get("nameserver", "")
45 self.netmask = kwargs.get("netmask", "")
46 self.nodns = kwargs.get("nodns", False)
47 self.onboot = kwargs.get("onboot", True)
48 self.wepkey = kwargs.get("wepkey", "")
49
50 def __eq__(self, y):
51 return self.device and self.device == y.device
52
53 def _getArgsAsStr(self):
54 retval = ""
55
56 if self.bootProto != "":
57 retval += " --bootproto=%s" % self.bootProto
58 if self.dhcpclass != "":
59 retval += " --dhcpclass=%s" % self.dhcpclass
60 if self.device != "":
61 retval += " --device=%s" % self.device
62 if self.essid != "":
63 retval += " --essid=\"%s\"" % self.essid
64 if self.ethtool != "":
65 retval += " --ethtool=\"%s\"" % self.ethtool
66 if self.gateway != "":
67 retval += " --gateway=%s" % self.gateway
68 if self.hostname != "":
69 retval += " --hostname=%s" % self.hostname
70 if self.ip != "":
71 retval += " --ip=%s" % self.ip
72 if self.mtu != "":
73 retval += " --mtu=%s" % self.mtu
74 if self.nameserver != "":
75 retval += " --nameserver=%s" % self.nameserver
76 if self.netmask != "":
77 retval += " --netmask=%s" % self.netmask
78 if self.nodns:
79 retval += " --nodns"
80 if not self.onboot:
81 retval += " --onboot=off"
82 if self.wepkey != "":
83 retval += " --wepkey=%s" % self.wepkey
84
85 return retval
86
87 def __str__(self):
88 retval = BaseData.__str__(self)
89 retval += "network %s\n" % self._getArgsAsStr()
90 return retval
91
92class FC4_NetworkData(FC3_NetworkData):
93 removedKeywords = FC3_NetworkData.removedKeywords
94 removedAttrs = FC3_NetworkData.removedAttrs
95
96 def __init__(self, *args, **kwargs):
97 FC3_NetworkData.__init__(self, *args, **kwargs)
98 self.notksdevice = kwargs.get("notksdevice", False)
99
100 def _getArgsAsStr(self):
101 retval = FC3_NetworkData._getArgsAsStr(self)
102
103 if self.notksdevice:
104 retval += " --notksdevice"
105
106 return retval
107
108class FC6_NetworkData(FC4_NetworkData):
109 removedKeywords = FC4_NetworkData.removedKeywords
110 removedAttrs = FC4_NetworkData.removedAttrs
111
112 def __init__(self, *args, **kwargs):
113 FC4_NetworkData.__init__(self, *args, **kwargs)
114 self.noipv4 = kwargs.get("noipv4", False)
115 self.noipv6 = kwargs.get("noipv6", False)
116
117 def _getArgsAsStr(self):
118 retval = FC4_NetworkData._getArgsAsStr(self)
119
120 if self.noipv4:
121 retval += " --noipv4"
122 if self.noipv6:
123 retval += " --noipv6"
124
125 return retval
126
127class F8_NetworkData(FC6_NetworkData):
128 removedKeywords = FC6_NetworkData.removedKeywords
129 removedAttrs = FC6_NetworkData.removedAttrs
130
131 def __init__(self, *args, **kwargs):
132 FC6_NetworkData.__init__(self, *args, **kwargs)
133 self.ipv6 = kwargs.get("ipv6", "")
134
135 def _getArgsAsStr(self):
136 retval = FC6_NetworkData._getArgsAsStr(self)
137
138 if self.ipv6 != "":
139 retval += " --ipv6" % self.ipv6
140
141 return retval
142
143class F16_NetworkData(F8_NetworkData):
144 removedKeywords = F8_NetworkData.removedKeywords
145 removedAttrs = F8_NetworkData.removedAttrs
146
147 def __init__(self, *args, **kwargs):
148 F8_NetworkData.__init__(self, *args, **kwargs)
149 self.activate = kwargs.get("activate", False)
150 self.nodefroute = kwargs.get("nodefroute", False)
151 self.wpakey = kwargs.get("wpakey", "")
152
153 def _getArgsAsStr(self):
154 retval = F8_NetworkData._getArgsAsStr(self)
155
156 if self.activate:
157 retval += " --activate"
158 if self.nodefroute:
159 retval += " --nodefroute"
160 if self.wpakey != "":
161 retval += "--wpakey=%s" % self.wpakey
162
163 return retval
164
165class RHEL4_NetworkData(FC3_NetworkData):
166 removedKeywords = FC3_NetworkData.removedKeywords
167 removedAttrs = FC3_NetworkData.removedAttrs
168
169 def __init__(self, *args, **kwargs):
170 FC3_NetworkData.__init__(self, *args, **kwargs)
171 self.notksdevice = kwargs.get("notksdevice", False)
172
173 def _getArgsAsStr(self):
174 retval = FC3_NetworkData._getArgsAsStr(self)
175
176 if self.notksdevice:
177 retval += " --notksdevice"
178
179 return retval
180
181class RHEL6_NetworkData(F8_NetworkData):
182 removedKeywords = F8_NetworkData.removedKeywords
183 removedAttrs = F8_NetworkData.removedAttrs
184
185 def __init__(self, *args, **kwargs):
186 F8_NetworkData.__init__(self, *args, **kwargs)
187 self.activate = kwargs.get("activate", False)
188 self.nodefroute = kwargs.get("nodefroute", False)
189
190 def _getArgsAsStr(self):
191 retval = F8_NetworkData._getArgsAsStr(self)
192
193 if self.activate:
194 retval += " --activate"
195 if self.nodefroute:
196 retval += " --nodefroute"
197
198 return retval
199
200class FC3_Network(KickstartCommand):
201 removedKeywords = KickstartCommand.removedKeywords
202 removedAttrs = KickstartCommand.removedAttrs
203
204 def __init__(self, writePriority=0, *args, **kwargs):
205 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
206 self.bootprotoList = [BOOTPROTO_DHCP, BOOTPROTO_BOOTP,
207 BOOTPROTO_STATIC]
208
209 self.op = self._getParser()
210
211 self.network = kwargs.get("network", [])
212
213 def __str__(self):
214 retval = ""
215
216 for nic in self.network:
217 retval += nic.__str__()
218
219 if retval != "":
220 return "# Network information\n" + retval
221 else:
222 return ""
223
224 def _getParser(self):
225 op = KSOptionParser()
226 op.add_option("--bootproto", dest="bootProto",
227 default=BOOTPROTO_DHCP,
228 choices=self.bootprotoList)
229 op.add_option("--dhcpclass", dest="dhcpclass")
230 op.add_option("--device", dest="device")
231 op.add_option("--essid", dest="essid")
232 op.add_option("--ethtool", dest="ethtool")
233 op.add_option("--gateway", dest="gateway")
234 op.add_option("--hostname", dest="hostname")
235 op.add_option("--ip", dest="ip")
236 op.add_option("--mtu", dest="mtu")
237 op.add_option("--nameserver", dest="nameserver")
238 op.add_option("--netmask", dest="netmask")
239 op.add_option("--nodns", dest="nodns", action="store_true",
240 default=False)
241 op.add_option("--onboot", dest="onboot", action="store",
242 type="ksboolean")
243 op.add_option("--wepkey", dest="wepkey")
244 return op
245
246 def parse(self, args):
247 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
248 nd = self.handler.NetworkData()
249 self._setToObj(self.op, opts, nd)
250 nd.lineno = self.lineno
251
252 # Check for duplicates in the data list.
253 if nd in self.dataList():
254 warnings.warn(_("A network device with the name %s has already been defined.") % nd.device)
255
256 return nd
257
258 def dataList(self):
259 return self.network
260
261class FC4_Network(FC3_Network):
262 removedKeywords = FC3_Network.removedKeywords
263 removedAttrs = FC3_Network.removedAttrs
264
265 def _getParser(self):
266 op = FC3_Network._getParser(self)
267 op.add_option("--notksdevice", dest="notksdevice", action="store_true",
268 default=False)
269 return op
270
271class FC6_Network(FC4_Network):
272 removedKeywords = FC4_Network.removedKeywords
273 removedAttrs = FC4_Network.removedAttrs
274
275 def _getParser(self):
276 op = FC4_Network._getParser(self)
277 op.add_option("--noipv4", dest="noipv4", action="store_true",
278 default=False)
279 op.add_option("--noipv6", dest="noipv6", action="store_true",
280 default=False)
281 return op
282
283class F8_Network(FC6_Network):
284 removedKeywords = FC6_Network.removedKeywords
285 removedAttrs = FC6_Network.removedAttrs
286
287 def _getParser(self):
288 op = FC6_Network._getParser(self)
289 op.add_option("--ipv6", dest="ipv6")
290 return op
291
292class F9_Network(F8_Network):
293 removedKeywords = F8_Network.removedKeywords
294 removedAttrs = F8_Network.removedAttrs
295
296 def __init__(self, writePriority=0, *args, **kwargs):
297 F8_Network.__init__(self, writePriority, *args, **kwargs)
298 self.bootprotoList.append(BOOTPROTO_QUERY)
299
300 def _getParser(self):
301 op = F8_Network._getParser(self)
302 op.add_option("--bootproto", dest="bootProto",
303 default=BOOTPROTO_DHCP,
304 choices=self.bootprotoList)
305 return op
306
307class F16_Network(F9_Network):
308 removedKeywords = F9_Network.removedKeywords
309 removedAttrs = F9_Network.removedAttrs
310
311 def __init__(self, writePriority=0, *args, **kwargs):
312 F9_Network.__init__(self, writePriority, *args, **kwargs)
313 self.bootprotoList.append(BOOTPROTO_IBFT)
314
315 def _getParser(self):
316 op = F9_Network._getParser(self)
317 op.add_option("--activate", dest="activate", action="store_true",
318 default=False)
319 op.add_option("--nodefroute", dest="nodefroute", action="store_true",
320 default=False)
321 op.add_option("--wpakey", dest="wpakey", action="store", default="")
322 return op
323
324class RHEL4_Network(FC3_Network):
325 removedKeywords = FC3_Network.removedKeywords
326 removedAttrs = FC3_Network.removedAttrs
327
328 def _getParser(self):
329 op = FC3_Network._getParser(self)
330 op.add_option("--notksdevice", dest="notksdevice", action="store_true",
331 default=False)
332 return op
333
334class RHEL5_Network(FC6_Network):
335 removedKeywords = FC6_Network.removedKeywords
336 removedAttrs = FC6_Network.removedAttrs
337
338 def __init__(self, writePriority=0, *args, **kwargs):
339 FC6_Network.__init__(self, writePriority, *args, **kwargs)
340 self.bootprotoList.append(BOOTPROTO_QUERY)
341
342 def _getParser(self):
343 op = FC6_Network._getParser(self)
344 op.add_option("--bootproto", dest="bootProto",
345 default=BOOTPROTO_DHCP,
346 choices=self.bootprotoList)
347 return op
348
349class RHEL6_Network(F9_Network):
350 removedKeywords = F9_Network.removedKeywords
351 removedAttrs = F9_Network.removedAttrs
352
353 def __init__(self, writePriority=0, *args, **kwargs):
354 F9_Network.__init__(self, writePriority, *args, **kwargs)
355 self.bootprotoList.append(BOOTPROTO_IBFT)
356
357 def _getParser(self):
358 op = F9_Network._getParser(self)
359 op.add_option("--activate", dest="activate", action="store_true",
360 default=False)
361 op.add_option("--nodefroute", dest="nodefroute", action="store_true",
362 default=False)
363 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/partition.py b/scripts/lib/mic/3rdparty/pykickstart/commands/partition.py
new file mode 100644
index 0000000000..e65e012d02
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/partition.py
@@ -0,0 +1,353 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25import warnings
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC3_PartData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
31
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.active = kwargs.get("active", False)
35 self.primOnly = kwargs.get("primOnly", False)
36 self.end = kwargs.get("end", 0)
37 self.fstype = kwargs.get("fstype", "")
38 self.grow = kwargs.get("grow", False)
39 self.maxSizeMB = kwargs.get("maxSizeMB", 0)
40 self.format = kwargs.get("format", True)
41 self.onbiosdisk = kwargs.get("onbiosdisk", "")
42 self.disk = kwargs.get("disk", "")
43 self.onPart = kwargs.get("onPart", "")
44 self.recommended = kwargs.get("recommended", False)
45 self.size = kwargs.get("size", None)
46 self.start = kwargs.get("start", 0)
47 self.mountpoint = kwargs.get("mountpoint", "")
48
49 def __eq__(self, y):
50 if self.mountpoint:
51 return self.mountpoint == y.mountpoint
52 else:
53 return False
54
55 def _getArgsAsStr(self):
56 retval = ""
57
58 if self.active:
59 retval += " --active"
60 if self.primOnly:
61 retval += " --asprimary"
62 if hasattr(self, "end") and self.end != 0:
63 retval += " --end=%s" % self.end
64 if self.fstype != "":
65 retval += " --fstype=\"%s\"" % self.fstype
66 if self.grow:
67 retval += " --grow"
68 if self.maxSizeMB > 0:
69 retval += " --maxsize=%d" % self.maxSizeMB
70 if not self.format:
71 retval += " --noformat"
72 if self.onbiosdisk != "":
73 retval += " --onbiosdisk=%s" % self.onbiosdisk
74 if self.disk != "":
75 retval += " --ondisk=%s" % self.disk
76 if self.onPart != "":
77 retval += " --onpart=%s" % self.onPart
78 if self.recommended:
79 retval += " --recommended"
80 if self.size and self.size != 0:
81 retval += " --size=%s" % self.size
82 if hasattr(self, "start") and self.start != 0:
83 retval += " --start=%s" % self.start
84
85 return retval
86
87 def __str__(self):
88 retval = BaseData.__str__(self)
89 if self.mountpoint:
90 mountpoint_str = "%s" % self.mountpoint
91 else:
92 mountpoint_str = "(No mount point)"
93 retval += "part %s%s\n" % (mountpoint_str, self._getArgsAsStr())
94 return retval
95
96class FC4_PartData(FC3_PartData):
97 removedKeywords = FC3_PartData.removedKeywords
98 removedAttrs = FC3_PartData.removedAttrs
99
100 def __init__(self, *args, **kwargs):
101 FC3_PartData.__init__(self, *args, **kwargs)
102 self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
103 self.fsopts = kwargs.get("fsopts", "")
104 self.label = kwargs.get("label", "")
105
106 def _getArgsAsStr(self):
107 retval = FC3_PartData._getArgsAsStr(self)
108
109 if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
110 retval += " --bytes-per-inode=%d" % self.bytesPerInode
111 if self.fsopts != "":
112 retval += " --fsoptions=\"%s\"" % self.fsopts
113 if self.label != "":
114 retval += " --label=%s" % self.label
115
116 return retval
117
118class RHEL5_PartData(FC4_PartData):
119 removedKeywords = FC4_PartData.removedKeywords
120 removedAttrs = FC4_PartData.removedAttrs
121
122 def __init__(self, *args, **kwargs):
123 FC4_PartData.__init__(self, *args, **kwargs)
124 self.encrypted = kwargs.get("encrypted", False)
125 self.passphrase = kwargs.get("passphrase", "")
126
127 def _getArgsAsStr(self):
128 retval = FC4_PartData._getArgsAsStr(self)
129
130 if self.encrypted:
131 retval += " --encrypted"
132
133 if self.passphrase != "":
134 retval += " --passphrase=\"%s\"" % self.passphrase
135
136 return retval
137
138class F9_PartData(FC4_PartData):
139 removedKeywords = FC4_PartData.removedKeywords + ["bytesPerInode"]
140 removedAttrs = FC4_PartData.removedAttrs + ["bytesPerInode"]
141
142 def __init__(self, *args, **kwargs):
143 FC4_PartData.__init__(self, *args, **kwargs)
144 self.deleteRemovedAttrs()
145
146 self.fsopts = kwargs.get("fsopts", "")
147 self.label = kwargs.get("label", "")
148 self.fsprofile = kwargs.get("fsprofile", "")
149 self.encrypted = kwargs.get("encrypted", False)
150 self.passphrase = kwargs.get("passphrase", "")
151
152 def _getArgsAsStr(self):
153 retval = FC4_PartData._getArgsAsStr(self)
154
155 if self.fsprofile != "":
156 retval += " --fsprofile=\"%s\"" % self.fsprofile
157 if self.encrypted:
158 retval += " --encrypted"
159
160 if self.passphrase != "":
161 retval += " --passphrase=\"%s\"" % self.passphrase
162
163 return retval
164
165class F11_PartData(F9_PartData):
166 removedKeywords = F9_PartData.removedKeywords + ["start", "end"]
167 removedAttrs = F9_PartData.removedAttrs + ["start", "end"]
168
169class F12_PartData(F11_PartData):
170 removedKeywords = F11_PartData.removedKeywords
171 removedAttrs = F11_PartData.removedAttrs
172
173 def __init__(self, *args, **kwargs):
174 F11_PartData.__init__(self, *args, **kwargs)
175
176 self.escrowcert = kwargs.get("escrowcert", "")
177 self.backuppassphrase = kwargs.get("backuppassphrase", False)
178
179 def _getArgsAsStr(self):
180 retval = F11_PartData._getArgsAsStr(self)
181
182 if self.encrypted and self.escrowcert != "":
183 retval += " --escrowcert=\"%s\"" % self.escrowcert
184
185 if self.backuppassphrase:
186 retval += " --backuppassphrase"
187
188 return retval
189
190F14_PartData = F12_PartData
191
192class FC3_Partition(KickstartCommand):
193 removedKeywords = KickstartCommand.removedKeywords
194 removedAttrs = KickstartCommand.removedAttrs
195
196 def __init__(self, writePriority=130, *args, **kwargs):
197 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
198 self.op = self._getParser()
199
200 self.partitions = kwargs.get("partitions", [])
201
202 def __str__(self):
203 retval = ""
204
205 for part in self.partitions:
206 retval += part.__str__()
207
208 if retval != "":
209 return "# Disk partitioning information\n" + retval
210 else:
211 return ""
212
213 def _getParser(self):
214 def part_cb (option, opt_str, value, parser):
215 if value.startswith("/dev/"):
216 parser.values.ensure_value(option.dest, value[5:])
217 else:
218 parser.values.ensure_value(option.dest, value)
219
220 op = KSOptionParser()
221 op.add_option("--active", dest="active", action="store_true",
222 default=False)
223 op.add_option("--asprimary", dest="primOnly", action="store_true",
224 default=False)
225 op.add_option("--end", dest="end", action="store", type="int",
226 nargs=1)
227 op.add_option("--fstype", "--type", dest="fstype")
228 op.add_option("--grow", dest="grow", action="store_true", default=False)
229 op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
230 nargs=1)
231 op.add_option("--noformat", dest="format", action="store_false",
232 default=True)
233 op.add_option("--onbiosdisk", dest="onbiosdisk")
234 op.add_option("--ondisk", "--ondrive", dest="disk")
235 op.add_option("--onpart", "--usepart", dest="onPart", action="callback",
236 callback=part_cb, nargs=1, type="string")
237 op.add_option("--recommended", dest="recommended", action="store_true",
238 default=False)
239 op.add_option("--size", dest="size", action="store", type="int",
240 nargs=1)
241 op.add_option("--start", dest="start", action="store", type="int",
242 nargs=1)
243 return op
244
245 def parse(self, args):
246 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
247
248 pd = self.handler.PartData()
249 self._setToObj(self.op, opts, pd)
250 pd.lineno = self.lineno
251 if extra:
252 pd.mountpoint = extra[0]
253 if pd in self.dataList():
254 warnings.warn(_("A partition with the mountpoint %s has already been defined.") % pd.mountpoint)
255 else:
256 pd.mountpoint = None
257
258 return pd
259
260 def dataList(self):
261 return self.partitions
262
263class FC4_Partition(FC3_Partition):
264 removedKeywords = FC3_Partition.removedKeywords
265 removedAttrs = FC3_Partition.removedAttrs
266
267 def __init__(self, writePriority=130, *args, **kwargs):
268 FC3_Partition.__init__(self, writePriority, *args, **kwargs)
269
270 def part_cb (option, opt_str, value, parser):
271 if value.startswith("/dev/"):
272 parser.values.ensure_value(option.dest, value[5:])
273 else:
274 parser.values.ensure_value(option.dest, value)
275
276 def _getParser(self):
277 op = FC3_Partition._getParser(self)
278 op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
279 type="int", nargs=1)
280 op.add_option("--fsoptions", dest="fsopts")
281 op.add_option("--label", dest="label")
282 return op
283
284class RHEL5_Partition(FC4_Partition):
285 removedKeywords = FC4_Partition.removedKeywords
286 removedAttrs = FC4_Partition.removedAttrs
287
288 def __init__(self, writePriority=130, *args, **kwargs):
289 FC4_Partition.__init__(self, writePriority, *args, **kwargs)
290
291 def part_cb (option, opt_str, value, parser):
292 if value.startswith("/dev/"):
293 parser.values.ensure_value(option.dest, value[5:])
294 else:
295 parser.values.ensure_value(option.dest, value)
296
297 def _getParser(self):
298 op = FC4_Partition._getParser(self)
299 op.add_option("--encrypted", action="store_true", default=False)
300 op.add_option("--passphrase")
301 return op
302
303class F9_Partition(FC4_Partition):
304 removedKeywords = FC4_Partition.removedKeywords
305 removedAttrs = FC4_Partition.removedAttrs
306
307 def __init__(self, writePriority=130, *args, **kwargs):
308 FC4_Partition.__init__(self, writePriority, *args, **kwargs)
309
310 def part_cb (option, opt_str, value, parser):
311 if value.startswith("/dev/"):
312 parser.values.ensure_value(option.dest, value[5:])
313 else:
314 parser.values.ensure_value(option.dest, value)
315
316 def _getParser(self):
317 op = FC4_Partition._getParser(self)
318 op.add_option("--bytes-per-inode", deprecated=1)
319 op.add_option("--fsprofile")
320 op.add_option("--encrypted", action="store_true", default=False)
321 op.add_option("--passphrase")
322 return op
323
324class F11_Partition(F9_Partition):
325 removedKeywords = F9_Partition.removedKeywords
326 removedAttrs = F9_Partition.removedAttrs
327
328 def _getParser(self):
329 op = F9_Partition._getParser(self)
330 op.add_option("--start", deprecated=1)
331 op.add_option("--end", deprecated=1)
332 return op
333
334class F12_Partition(F11_Partition):
335 removedKeywords = F11_Partition.removedKeywords
336 removedAttrs = F11_Partition.removedAttrs
337
338 def _getParser(self):
339 op = F11_Partition._getParser(self)
340 op.add_option("--escrowcert")
341 op.add_option("--backuppassphrase", action="store_true", default=False)
342 return op
343
344class F14_Partition(F12_Partition):
345 removedKeywords = F12_Partition.removedKeywords
346 removedAttrs = F12_Partition.removedAttrs
347
348 def _getParser(self):
349 op = F12_Partition._getParser(self)
350 op.remove_option("--bytes-per-inode")
351 op.remove_option("--start")
352 op.remove_option("--end")
353 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/raid.py b/scripts/lib/mic/3rdparty/pykickstart/commands/raid.py
new file mode 100644
index 0000000000..0f4c92a107
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/raid.py
@@ -0,0 +1,365 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008, 2011 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25import warnings
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC3_RaidData(BaseData):
29 removedKeywords = BaseData.removedKeywords
30 removedAttrs = BaseData.removedAttrs
31
32 def __init__(self, *args, **kwargs):
33 BaseData.__init__(self, *args, **kwargs)
34 self.device = kwargs.get("device", None)
35 self.fstype = kwargs.get("fstype", "")
36 self.level = kwargs.get("level", "")
37 self.format = kwargs.get("format", True)
38 self.spares = kwargs.get("spares", 0)
39 self.preexist = kwargs.get("preexist", False)
40 self.mountpoint = kwargs.get("mountpoint", "")
41 self.members = kwargs.get("members", [])
42
43 def __eq__(self, y):
44 return self.device == y.device
45
46 def _getArgsAsStr(self):
47 retval = ""
48
49 if self.device != "":
50 retval += " --device=%s" % self.device
51 if self.fstype != "":
52 retval += " --fstype=\"%s\"" % self.fstype
53 if self.level != "":
54 retval += " --level=%s" % self.level
55 if not self.format:
56 retval += " --noformat"
57 if self.spares != 0:
58 retval += " --spares=%d" % self.spares
59 if self.preexist:
60 retval += " --useexisting"
61
62 return retval
63
64 def __str__(self):
65 retval = BaseData.__str__(self)
66 retval += "raid %s%s %s\n" % (self.mountpoint, self._getArgsAsStr(),
67 " ".join(self.members))
68 return retval
69
70class FC4_RaidData(FC3_RaidData):
71 removedKeywords = FC3_RaidData.removedKeywords
72 removedAttrs = FC3_RaidData.removedAttrs
73
74 def __init__(self, *args, **kwargs):
75 FC3_RaidData.__init__(self, *args, **kwargs)
76 self.fsopts = kwargs.get("fsopts", "")
77
78 def _getArgsAsStr(self):
79 retval = FC3_RaidData._getArgsAsStr(self)
80
81 if self.fsopts != "":
82 retval += " --fsoptions=\"%s\"" % self.fsopts
83
84 return retval
85
86class FC5_RaidData(FC4_RaidData):
87 removedKeywords = FC4_RaidData.removedKeywords
88 removedAttrs = FC4_RaidData.removedAttrs
89
90 def __init__(self, *args, **kwargs):
91 FC4_RaidData.__init__(self, *args, **kwargs)
92 self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
93
94 def _getArgsAsStr(self):
95 retval = FC4_RaidData._getArgsAsStr(self)
96
97 if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
98 retval += " --bytes-per-inode=%d" % self.bytesPerInode
99
100 return retval
101
102class RHEL5_RaidData(FC5_RaidData):
103 removedKeywords = FC5_RaidData.removedKeywords
104 removedAttrs = FC5_RaidData.removedAttrs
105
106 def __init__(self, *args, **kwargs):
107 FC5_RaidData.__init__(self, *args, **kwargs)
108 self.encrypted = kwargs.get("encrypted", False)
109 self.passphrase = kwargs.get("passphrase", "")
110
111 def _getArgsAsStr(self):
112 retval = FC5_RaidData._getArgsAsStr(self)
113
114 if self.encrypted:
115 retval += " --encrypted"
116
117 if self.passphrase != "":
118 retval += " --passphrase=\"%s\"" % self.passphrase
119
120 return retval
121
122F7_RaidData = FC5_RaidData
123
124class F9_RaidData(FC5_RaidData):
125 removedKeywords = FC5_RaidData.removedKeywords + ["bytesPerInode"]
126 removedAttrs = FC5_RaidData.removedAttrs + ["bytesPerInode"]
127
128 def __init__(self, *args, **kwargs):
129 FC5_RaidData.__init__(self, *args, **kwargs)
130 self.deleteRemovedAttrs()
131
132 self.fsprofile = kwargs.get("fsprofile", "")
133 self.encrypted = kwargs.get("encrypted", False)
134 self.passphrase = kwargs.get("passphrase", "")
135
136 def _getArgsAsStr(self):
137 retval = FC5_RaidData._getArgsAsStr(self)
138
139 if self.fsprofile != "":
140 retval += " --fsprofile=\"%s\"" % self.fsprofile
141 if self.encrypted:
142 retval += " --encrypted"
143
144 if self.passphrase != "":
145 retval += " --passphrase=\"%s\"" % self.passphrase
146
147 return retval
148
149class F12_RaidData(F9_RaidData):
150 removedKeywords = F9_RaidData.removedKeywords
151 removedAttrs = F9_RaidData.removedAttrs
152
153 def __init__(self, *args, **kwargs):
154 F9_RaidData.__init__(self, *args, **kwargs)
155 self.deleteRemovedAttrs()
156
157 self.escrowcert = kwargs.get("escrowcert", "")
158 self.backuppassphrase = kwargs.get("backuppassphrase", False)
159
160 def _getArgsAsStr(self):
161 retval = F9_RaidData._getArgsAsStr(self)
162
163 if self.encrypted and self.escrowcert != "":
164 retval += " --escrowcert=\"%s\"" % self.escrowcert
165
166 if self.backuppassphrase:
167 retval += " --backuppassphrase"
168 return retval
169
170F13_RaidData = F12_RaidData
171
172F14_RaidData = F13_RaidData
173
174class F15_RaidData(F14_RaidData):
175 removedKeywords = F14_RaidData.removedKeywords
176 removedAttrs = F14_RaidData.removedAttrs
177
178 def __init__(self, *args, **kwargs):
179 F14_RaidData.__init__(self, *args, **kwargs)
180 self.deleteRemovedAttrs()
181
182 self.label = kwargs.get("label", "")
183
184 def _getArgsAsStr(self):
185 retval = F14_RaidData._getArgsAsStr(self)
186
187 if self.label != "":
188 retval += " --label=%s" % self.label
189
190 return retval
191
192class FC3_Raid(KickstartCommand):
193 removedKeywords = KickstartCommand.removedKeywords
194 removedAttrs = KickstartCommand.removedAttrs
195
196 def __init__(self, writePriority=131, *args, **kwargs):
197 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
198 self.op = self._getParser()
199
200 # A dict of all the RAID levels we support. This means that if we
201 # support more levels in the future, subclasses don't have to
202 # duplicate too much.
203 self.levelMap = { "RAID0": "RAID0", "0": "RAID0",
204 "RAID1": "RAID1", "1": "RAID1",
205 "RAID5": "RAID5", "5": "RAID5",
206 "RAID6": "RAID6", "6": "RAID6" }
207
208 self.raidList = kwargs.get("raidList", [])
209
210 def __str__(self):
211 retval = ""
212
213 for raid in self.raidList:
214 retval += raid.__str__()
215
216 return retval
217
218 def _getParser(self):
219 def raid_cb (option, opt_str, value, parser):
220 parser.values.format = False
221 parser.values.preexist = True
222
223 def device_cb (option, opt_str, value, parser):
224 if value[0:2] == "md":
225 parser.values.ensure_value(option.dest, value[2:])
226 else:
227 parser.values.ensure_value(option.dest, value)
228
229 def level_cb (option, opt_str, value, parser):
230 if self.levelMap.has_key(value):
231 parser.values.ensure_value(option.dest, self.levelMap[value])
232
233 op = KSOptionParser()
234 op.add_option("--device", action="callback", callback=device_cb,
235 dest="device", type="string", nargs=1, required=1)
236 op.add_option("--fstype", dest="fstype")
237 op.add_option("--level", dest="level", action="callback",
238 callback=level_cb, type="string", nargs=1)
239 op.add_option("--noformat", action="callback", callback=raid_cb,
240 dest="format", default=True, nargs=0)
241 op.add_option("--spares", dest="spares", action="store", type="int",
242 nargs=1, default=0)
243 op.add_option("--useexisting", dest="preexist", action="store_true",
244 default=False)
245 return op
246
247 def parse(self, args):
248 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
249
250 if len(extra) == 0:
251 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Mount point required for %s") % "raid")
252 if len(extra) == 1:
253 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Partitions required for %s") % "raid")
254
255 rd = self.handler.RaidData()
256 self._setToObj(self.op, opts, rd)
257 rd.lineno = self.lineno
258
259 # --device can't just take an int in the callback above, because it
260 # could be specificed as "mdX", which causes optparse to error when
261 # it runs int().
262 rd.device = int(rd.device)
263 rd.mountpoint = extra[0]
264 rd.members = extra[1:]
265
266 # Check for duplicates in the data list.
267 if rd in self.dataList():
268 warnings.warn(_("A RAID device with the name %s has already been defined.") % rd.device)
269
270 return rd
271
272 def dataList(self):
273 return self.raidList
274
275class FC4_Raid(FC3_Raid):
276 removedKeywords = FC3_Raid.removedKeywords
277 removedAttrs = FC3_Raid.removedAttrs
278
279 def _getParser(self):
280 op = FC3_Raid._getParser(self)
281 op.add_option("--fsoptions", dest="fsopts")
282 return op
283
284class FC5_Raid(FC4_Raid):
285 removedKeywords = FC4_Raid.removedKeywords
286 removedAttrs = FC4_Raid.removedAttrs
287
288 def _getParser(self):
289 op = FC4_Raid._getParser(self)
290 op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
291 type="int", nargs=1)
292 return op
293
294class RHEL5_Raid(FC5_Raid):
295 removedKeywords = FC5_Raid.removedKeywords
296 removedAttrs = FC5_Raid.removedAttrs
297
298 def __init__(self, writePriority=131, *args, **kwargs):
299 FC5_Raid.__init__(self, writePriority, *args, **kwargs)
300
301 self.levelMap.update({"RAID10": "RAID10", "10": "RAID10"})
302
303 def _getParser(self):
304 op = FC5_Raid._getParser(self)
305 op.add_option("--encrypted", action="store_true", default=False)
306 op.add_option("--passphrase")
307 return op
308
309class F7_Raid(FC5_Raid):
310 removedKeywords = FC5_Raid.removedKeywords
311 removedAttrs = FC5_Raid.removedAttrs
312
313 def __init__(self, writePriority=131, *args, **kwargs):
314 FC5_Raid.__init__(self, writePriority, *args, **kwargs)
315
316 self.levelMap.update({"RAID10": "RAID10", "10": "RAID10"})
317
318class F9_Raid(F7_Raid):
319 removedKeywords = F7_Raid.removedKeywords
320 removedAttrs = F7_Raid.removedAttrs
321
322 def _getParser(self):
323 op = F7_Raid._getParser(self)
324 op.add_option("--bytes-per-inode", deprecated=1)
325 op.add_option("--fsprofile")
326 op.add_option("--encrypted", action="store_true", default=False)
327 op.add_option("--passphrase")
328 return op
329
330class F12_Raid(F9_Raid):
331 removedKeywords = F9_Raid.removedKeywords
332 removedAttrs = F9_Raid.removedAttrs
333
334 def _getParser(self):
335 op = F9_Raid._getParser(self)
336 op.add_option("--escrowcert")
337 op.add_option("--backuppassphrase", action="store_true", default=False)
338 return op
339
340class F13_Raid(F12_Raid):
341 removedKeywords = F12_Raid.removedKeywords
342 removedAttrs = F12_Raid.removedAttrs
343
344 def __init__(self, writePriority=131, *args, **kwargs):
345 F12_Raid.__init__(self, writePriority, *args, **kwargs)
346
347 self.levelMap.update({"RAID4": "RAID4", "4": "RAID4"})
348
349class F14_Raid(F13_Raid):
350 removedKeywords = F13_Raid.removedKeywords
351 removedAttrs = F13_Raid.removedAttrs
352
353 def _getParser(self):
354 op = F13_Raid._getParser(self)
355 op.remove_option("--bytes-per-inode")
356 return op
357
358class F15_Raid(F14_Raid):
359 removedKeywords = F14_Raid.removedKeywords
360 removedAttrs = F14_Raid.removedAttrs
361
362 def _getParser(self):
363 op = F14_Raid._getParser(self)
364 op.add_option("--label")
365 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/reboot.py b/scripts/lib/mic/3rdparty/pykickstart/commands/reboot.py
new file mode 100644
index 0000000000..391af14c22
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/reboot.py
@@ -0,0 +1,79 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25class FC3_Reboot(KickstartCommand):
26 removedKeywords = KickstartCommand.removedKeywords
27 removedAttrs = KickstartCommand.removedAttrs
28
29 def __init__(self, writePriority=0, *args, **kwargs):
30 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
31 self.action = kwargs.get("action", None)
32
33 def __str__(self):
34 retval = KickstartCommand.__str__(self)
35
36 if self.action == KS_REBOOT:
37 retval += "# Reboot after installation\nreboot\n"
38 elif self.action == KS_SHUTDOWN:
39 retval += "# Shutdown after installation\nshutdown\n"
40
41 return retval
42
43 def parse(self, args):
44 if self.currentCmd == "reboot":
45 self.action = KS_REBOOT
46 else:
47 self.action = KS_SHUTDOWN
48
49 return self
50
51class FC6_Reboot(FC3_Reboot):
52 removedKeywords = FC3_Reboot.removedKeywords
53 removedAttrs = FC3_Reboot.removedAttrs
54
55 def __init__(self, writePriority=0, *args, **kwargs):
56 FC3_Reboot.__init__(self, writePriority, *args, **kwargs)
57 self.op = self._getParser()
58
59 self.eject = kwargs.get("eject", False)
60
61 def __str__(self):
62 retval = FC3_Reboot.__str__(self).rstrip()
63
64 if self.eject:
65 retval += " --eject"
66
67 return retval + "\n"
68
69 def _getParser(self):
70 op = KSOptionParser()
71 op.add_option("--eject", dest="eject", action="store_true",
72 default=False)
73 return op
74
75 def parse(self, args):
76 FC3_Reboot.parse(self, args)
77 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
78 self._setToSelf(self.op, opts)
79 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/repo.py b/scripts/lib/mic/3rdparty/pykickstart/commands/repo.py
new file mode 100644
index 0000000000..543ef947c1
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/repo.py
@@ -0,0 +1,249 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007, 2008, 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26import warnings
27_ = lambda x: gettext.ldgettext("pykickstart", x)
28
29class FC6_RepoData(BaseData):
30 removedKeywords = BaseData.removedKeywords
31 removedAttrs = BaseData.removedAttrs
32
33 def __init__(self, *args, **kwargs):
34 BaseData.__init__(self, *args, **kwargs)
35 self.baseurl = kwargs.get("baseurl", "")
36 self.mirrorlist = kwargs.get("mirrorlist", None)
37 self.name = kwargs.get("name", "")
38
39 def __eq__(self, y):
40 return self.name == y.name
41
42 def _getArgsAsStr(self):
43 retval = ""
44
45 if self.baseurl:
46 retval += "--baseurl=%s" % self.baseurl
47 elif self.mirrorlist:
48 retval += "--mirrorlist=%s" % self.mirrorlist
49
50 return retval
51
52 def __str__(self):
53 retval = BaseData.__str__(self)
54 retval += "repo --name=\"%s\" %s\n" % (self.name, self._getArgsAsStr())
55 return retval
56
57class F8_RepoData(FC6_RepoData):
58 removedKeywords = FC6_RepoData.removedKeywords
59 removedAttrs = FC6_RepoData.removedAttrs
60
61 def __init__(self, *args, **kwargs):
62 FC6_RepoData.__init__(self, *args, **kwargs)
63 self.cost = kwargs.get("cost", None)
64 self.includepkgs = kwargs.get("includepkgs", [])
65 self.excludepkgs = kwargs.get("excludepkgs", [])
66
67 def _getArgsAsStr(self):
68 retval = FC6_RepoData._getArgsAsStr(self)
69
70 if self.cost:
71 retval += " --cost=%s" % self.cost
72 if self.includepkgs:
73 retval += " --includepkgs=\"%s\"" % ",".join(self.includepkgs)
74 if self.excludepkgs:
75 retval += " --excludepkgs=\"%s\"" % ",".join(self.excludepkgs)
76
77 return retval
78
79class F11_RepoData(F8_RepoData):
80 removedKeywords = F8_RepoData.removedKeywords
81 removedAttrs = F8_RepoData.removedAttrs
82
83 def __init__(self, *args, **kwargs):
84 F8_RepoData.__init__(self, *args, **kwargs)
85 self.ignoregroups = kwargs.get("ignoregroups", None)
86
87 def _getArgsAsStr(self):
88 retval = F8_RepoData._getArgsAsStr(self)
89
90 if self.ignoregroups:
91 retval += " --ignoregroups=true"
92 return retval
93
94class F13_RepoData(F11_RepoData):
95 removedKeywords = F11_RepoData.removedKeywords
96 removedAttrs = F11_RepoData.removedAttrs
97
98 def __init__(self, *args, **kwargs):
99 F11_RepoData.__init__(self, *args, **kwargs)
100 self.proxy = kwargs.get("proxy", "")
101
102 def _getArgsAsStr(self):
103 retval = F11_RepoData._getArgsAsStr(self)
104
105 if self.proxy:
106 retval += " --proxy=\"%s\"" % self.proxy
107
108 return retval
109
110class F14_RepoData(F13_RepoData):
111 removedKeywords = F13_RepoData.removedKeywords
112 removedAttrs = F13_RepoData.removedAttrs
113
114 def __init__(self, *args, **kwargs):
115 F13_RepoData.__init__(self, *args, **kwargs)
116 self.noverifyssl = kwargs.get("noverifyssl", False)
117
118 def _getArgsAsStr(self):
119 retval = F13_RepoData._getArgsAsStr(self)
120
121 if self.noverifyssl:
122 retval += " --noverifyssl"
123
124 return retval
125
126RHEL6_RepoData = F14_RepoData
127
128F15_RepoData = F14_RepoData
129
130class FC6_Repo(KickstartCommand):
131 removedKeywords = KickstartCommand.removedKeywords
132 removedAttrs = KickstartCommand.removedAttrs
133
134 urlRequired = True
135
136 def __init__(self, writePriority=0, *args, **kwargs):
137 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
138 self.op = self._getParser()
139
140 self.repoList = kwargs.get("repoList", [])
141
142 def __str__(self):
143 retval = ""
144 for repo in self.repoList:
145 retval += repo.__str__()
146
147 return retval
148
149 def _getParser(self):
150 op = KSOptionParser()
151 op.add_option("--name", dest="name", required=1)
152 op.add_option("--baseurl")
153 op.add_option("--mirrorlist")
154 return op
155
156 def parse(self, args):
157 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
158
159 if len(extra) != 0:
160 mapping = {"command": "repo", "options": extra}
161 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
162
163 # This is lame, but I can't think of a better way to make sure only
164 # one of these two is specified.
165 if opts.baseurl and opts.mirrorlist:
166 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --baseurl and --mirrorlist may be specified for repo command."))
167
168 if self.urlRequired and not opts.baseurl and not opts.mirrorlist:
169 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("One of --baseurl or --mirrorlist must be specified for repo command."))
170
171 rd = self.handler.RepoData()
172 self._setToObj(self.op, opts, rd)
173 rd.lineno = self.lineno
174
175 # Check for duplicates in the data list.
176 if rd in self.dataList():
177 warnings.warn(_("A repo with the name %s has already been defined.") % rd.name)
178
179 return rd
180
181 def dataList(self):
182 return self.repoList
183
184class F8_Repo(FC6_Repo):
185 removedKeywords = FC6_Repo.removedKeywords
186 removedAttrs = FC6_Repo.removedAttrs
187
188 def __str__(self):
189 retval = ""
190 for repo in self.repoList:
191 retval += repo.__str__()
192
193 return retval
194
195 def _getParser(self):
196 def list_cb (option, opt_str, value, parser):
197 for d in value.split(','):
198 parser.values.ensure_value(option.dest, []).append(d)
199
200 op = FC6_Repo._getParser(self)
201 op.add_option("--cost", action="store", type="int")
202 op.add_option("--excludepkgs", action="callback", callback=list_cb,
203 nargs=1, type="string")
204 op.add_option("--includepkgs", action="callback", callback=list_cb,
205 nargs=1, type="string")
206 return op
207
208 def methodToRepo(self):
209 if not self.handler.method.url:
210 raise KickstartError, formatErrorMsg(self.handler.method.lineno, msg=_("Method must be a url to be added to the repo list."))
211 reponame = "ks-method-url"
212 repourl = self.handler.method.url
213 rd = self.handler.RepoData(name=reponame, baseurl=repourl)
214 return rd
215
216class F11_Repo(F8_Repo):
217 removedKeywords = F8_Repo.removedKeywords
218 removedAttrs = F8_Repo.removedAttrs
219
220 def _getParser(self):
221 op = F8_Repo._getParser(self)
222 op.add_option("--ignoregroups", action="store", type="ksboolean")
223 return op
224
225class F13_Repo(F11_Repo):
226 removedKeywords = F11_Repo.removedKeywords
227 removedAttrs = F11_Repo.removedAttrs
228
229 def _getParser(self):
230 op = F11_Repo._getParser(self)
231 op.add_option("--proxy")
232 return op
233
234class F14_Repo(F13_Repo):
235 removedKeywords = F13_Repo.removedKeywords
236 removedAttrs = F13_Repo.removedAttrs
237
238 def _getParser(self):
239 op = F13_Repo._getParser(self)
240 op.add_option("--noverifyssl", action="store_true", default=False)
241 return op
242
243RHEL6_Repo = F14_Repo
244
245class F15_Repo(F14_Repo):
246 removedKeywords = F14_Repo.removedKeywords
247 removedAttrs = F14_Repo.removedAttrs
248
249 urlRequired = False
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/rescue.py b/scripts/lib/mic/3rdparty/pykickstart/commands/rescue.py
new file mode 100644
index 0000000000..1893d4ea49
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/rescue.py
@@ -0,0 +1,68 @@
1#
2# Alexander Todorov <atodorov@redhat.com>
3#
4# Copyright 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class F10_Rescue(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.rescue = False
36 self.nomount = kwargs.get("nomount", False)
37 self.romount = kwargs.get("romount", False)
38
39 def __str__(self):
40 retval = KickstartCommand.__str__(self)
41
42 if self.rescue:
43 retval += "rescue"
44
45 if self.nomount:
46 retval += " --nomount"
47 if self.romount:
48 retval += " --romount"
49
50 retval = "# Start rescue mode\n%s\n" % retval
51
52 return retval
53
54 def _getParser(self):
55 op = KSOptionParser()
56 op.add_option("--nomount", dest="nomount", action="store_true", default=False)
57 op.add_option("--romount", dest="romount", action="store_true", default=False)
58 return op
59
60 def parse(self, args):
61 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
62
63 if opts.nomount and opts.romount:
64 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Only one of --nomount and --romount may be specified for rescue command."))
65
66 self._setToSelf(self.op, opts)
67 self.rescue = True
68 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/rootpw.py b/scripts/lib/mic/3rdparty/pykickstart/commands/rootpw.py
new file mode 100644
index 0000000000..e038b4525d
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/rootpw.py
@@ -0,0 +1,93 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_RootPw(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.isCrypted = kwargs.get("isCrypted", False)
36 self.password = kwargs.get("password", "")
37
38 def _getArgsAsStr(self):
39 retval = ""
40
41 if self.isCrypted:
42 retval += " --iscrypted"
43
44 return retval
45
46 def __str__(self):
47 retval = KickstartCommand.__str__(self)
48
49 if self.password != "":
50 retval += "# Root password\nrootpw%s %s\n" % (self._getArgsAsStr(), self.password)
51
52 return retval
53
54 def _getParser(self):
55 op = KSOptionParser()
56 op.add_option("--iscrypted", dest="isCrypted", action="store_true",
57 default=False)
58 return op
59
60 def parse(self, args):
61 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
62 self._setToSelf(self.op, opts)
63
64 if len(extra) != 1:
65 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "rootpw")
66
67 self.password = extra[0]
68 return self
69
70class F8_RootPw(FC3_RootPw):
71 removedKeywords = FC3_RootPw.removedKeywords
72 removedAttrs = FC3_RootPw.removedAttrs
73
74 def __init__(self, writePriority=0, *args, **kwargs):
75 FC3_RootPw.__init__(self, writePriority, *args, **kwargs)
76 self.lock = kwargs.get("lock", False)
77
78 def _getArgsAsStr(self):
79 retval = FC3_RootPw._getArgsAsStr(self)
80
81 if self.lock:
82 retval += " --lock"
83
84 if not self.isCrypted:
85 retval += " --plaintext"
86
87 return retval
88
89 def _getParser(self):
90 op = FC3_RootPw._getParser(self)
91 op.add_option("--lock", dest="lock", action="store_true", default=False)
92 op.add_option("--plaintext", dest="isCrypted", action="store_false")
93 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/selinux.py b/scripts/lib/mic/3rdparty/pykickstart/commands/selinux.py
new file mode 100644
index 0000000000..9f8059c76b
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/selinux.py
@@ -0,0 +1,64 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.options import *
23
24class FC3_SELinux(KickstartCommand):
25 removedKeywords = KickstartCommand.removedKeywords
26 removedAttrs = KickstartCommand.removedAttrs
27
28 def __init__(self, writePriority=0, *args, **kwargs):
29 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
30 self.op = self._getParser()
31
32 self.selinux = kwargs.get("selinux", None)
33
34 def __str__(self):
35 retval = KickstartCommand.__str__(self)
36
37 if not retval and self.selinux is None:
38 return ""
39
40 retval += "# SELinux configuration\n"
41
42 if self.selinux == SELINUX_DISABLED:
43 retval += "selinux --disabled\n"
44 elif self.selinux == SELINUX_ENFORCING:
45 retval += "selinux --enforcing\n"
46 elif self.selinux == SELINUX_PERMISSIVE:
47 retval += "selinux --permissive\n"
48
49 return retval
50
51 def _getParser(self):
52 op = KSOptionParser()
53 op.add_option("--disabled", dest="selinux", action="store_const",
54 const=SELINUX_DISABLED)
55 op.add_option("--enforcing", dest="selinux", action="store_const",
56 const=SELINUX_ENFORCING)
57 op.add_option("--permissive", dest="selinux", action="store_const",
58 const=SELINUX_PERMISSIVE)
59 return op
60
61 def parse(self, args):
62 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
63 self._setToSelf(self.op, opts)
64 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/services.py b/scripts/lib/mic/3rdparty/pykickstart/commands/services.py
new file mode 100644
index 0000000000..2e0eab8007
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/services.py
@@ -0,0 +1,71 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC6_Services(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.disabled = kwargs.get("disabled", [])
36 self.enabled = kwargs.get("enabled", [])
37
38 def __str__(self):
39 retval = KickstartCommand.__str__(self)
40 args = ""
41
42 if len(self.disabled) > 0:
43 args += " --disabled=\"%s\"" % ",".join(self.disabled)
44 if len(self.enabled) > 0:
45 args += " --enabled=\"%s\"" % ",".join(self.enabled)
46
47 if args != "":
48 retval += "# System services\nservices%s\n" % args
49
50 return retval
51
52 def _getParser(self):
53 def services_cb (option, opt_str, value, parser):
54 for d in value.split(','):
55 parser.values.ensure_value(option.dest, []).append(d.strip())
56
57 op = KSOptionParser()
58 op.add_option("--disabled", dest="disabled", action="callback",
59 callback=services_cb, nargs=1, type="string")
60 op.add_option("--enabled", dest="enabled", action="callback",
61 callback=services_cb, nargs=1, type="string")
62 return op
63
64 def parse(self, args):
65 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
66 self._setToSelf(self.op, opts)
67
68 if len(self.disabled) == 0 and len(self.enabled) == 0:
69 raise KickstartParseError, formatErrorMsg(self.lineno, msg=_("One of --disabled or --enabled must be provided."))
70
71 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/skipx.py b/scripts/lib/mic/3rdparty/pykickstart/commands/skipx.py
new file mode 100644
index 0000000000..36d1a8d5ba
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/skipx.py
@@ -0,0 +1,54 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_SkipX(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.skipx = kwargs.get("skipx", False)
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.skipx:
40 retval += "# Do not configure the X Window System\nskipx\n"
41
42 return retval
43
44 def _getParser(self):
45 op = KSOptionParser()
46 return op
47
48 def parse(self, args):
49 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
50 if len(extra) > 0:
51 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "skipx")
52
53 self.skipx = True
54 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/sshpw.py b/scripts/lib/mic/3rdparty/pykickstart/commands/sshpw.py
new file mode 100644
index 0000000000..e7867ebfb2
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/sshpw.py
@@ -0,0 +1,105 @@
1#
2# Peter Jones <pjones@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class F13_SshPwData(BaseData):
28 removedKeywords = BaseData.removedKeywords
29 removedAttrs = BaseData.removedAttrs
30
31 def __init__(self, *args, **kwargs):
32 BaseData.__init__(self, *args, **kwargs)
33 self.username = kwargs.get("username", None)
34 self.isCrypted = kwargs.get("isCrypted", False)
35 self.password = kwargs.get("password", "")
36 self.lock = kwargs.get("lock", False)
37
38 def __eq__(self, y):
39 return self.username == y.username
40
41 def __str__(self):
42 retval = BaseData.__str__(self)
43
44 retval += "sshpw"
45 retval += self._getArgsAsStr() + '\n'
46
47 return retval
48
49 def _getArgsAsStr(self):
50 retval = ""
51
52 retval += " --username=%s" % self.username
53 if self.lock:
54 retval += " --lock"
55 if self.isCrypted:
56 retval += " --iscrypted"
57 else:
58 retval += " --plaintext"
59
60 retval += " %s" % self.password
61 return retval
62
63class F13_SshPw(KickstartCommand):
64 removedKeywords = KickstartCommand.removedKeywords
65 removedAttrs = KickstartCommand.removedAttrs
66
67 def __init__(self, writePriority=0, *args, **kwargs):
68 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
69 self.op = self._getParser()
70
71 self.sshUserList = kwargs.get("sshUserList", [])
72
73 def __str__(self):
74 retval = ""
75 for user in self.sshUserList:
76 retval += user.__str__()
77
78 return retval
79
80 def _getParser(self):
81 op = KSOptionParser()
82 op.add_option("--username", dest="username", required=True)
83 op.add_option("--iscrypted", dest="isCrypted", action="store_true",
84 default=False)
85 op.add_option("--plaintext", dest="isCrypted", action="store_false")
86 op.add_option("--lock", dest="lock", action="store_true", default=False)
87 return op
88
89 def parse(self, args):
90 ud = self.handler.SshPwData()
91 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
92 self._setToObj(self.op, opts, ud)
93 ud.lineno = self.lineno
94
95 if len(extra) != 1:
96 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "sshpw")
97 ud.password = extra[0]
98
99 if ud in self.dataList():
100 warnings.warn(_("An ssh user with the name %s has already been defined.") % ud.name)
101
102 return ud
103
104 def dataList(self):
105 return self.sshUserList
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/timezone.py b/scripts/lib/mic/3rdparty/pykickstart/commands/timezone.py
new file mode 100644
index 0000000000..f5441de593
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/timezone.py
@@ -0,0 +1,86 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Timezone(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.isUtc = kwargs.get("isUtc", False)
36 self.timezone = kwargs.get("timezone", "")
37
38 def __str__(self):
39 retval = KickstartCommand.__str__(self)
40
41 if self.timezone != "":
42 if self.isUtc:
43 utc = "--utc"
44 else:
45 utc = ""
46
47 retval += "# System timezone\ntimezone %s %s\n" %(utc, self.timezone)
48
49 return retval
50
51 def _getParser(self):
52 op = KSOptionParser()
53 op.add_option("--utc", dest="isUtc", action="store_true", default=False)
54 return op
55
56 def parse(self, args):
57 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
58 self._setToSelf(self.op, opts)
59
60 if len(extra) != 1:
61 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("A single argument is expected for the %s command") % "timezone")
62
63 self.timezone = extra[0]
64 return self
65
66class FC6_Timezone(FC3_Timezone):
67 removedKeywords = FC3_Timezone.removedKeywords
68 removedAttrs = FC3_Timezone.removedAttrs
69
70 def __str__(self):
71 retval = KickstartCommand.__str__(self)
72
73 if self.timezone != "":
74 if self.isUtc:
75 utc = "--isUtc"
76 else:
77 utc = ""
78
79 retval += "# System timezone\ntimezone %s %s\n" %(utc, self.timezone)
80
81 return retval
82
83 def _getParser(self):
84 op = FC3_Timezone._getParser(self)
85 op.add_option("--utc", "--isUtc", dest="isUtc", action="store_true", default=False)
86 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/updates.py b/scripts/lib/mic/3rdparty/pykickstart/commands/updates.py
new file mode 100644
index 0000000000..53ec49f7b8
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/updates.py
@@ -0,0 +1,60 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class F7_Updates(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34 self.url = kwargs.get("url", "")
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.url == "floppy":
40 retval += "updates\n"
41 elif self.url != "":
42 retval += "updates %s\n" % self.url
43
44 return retval
45
46 def _getParser(self):
47 op = KSOptionParser()
48 return op
49
50 def parse(self, args):
51 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
52
53 if len(extra) > 1:
54 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s only takes one argument") % "updates")
55 elif len(extra) == 0:
56 self.url = "floppy"
57 else:
58 self.url = extra[0]
59
60 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/upgrade.py b/scripts/lib/mic/3rdparty/pykickstart/commands/upgrade.py
new file mode 100644
index 0000000000..a68a82d378
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/upgrade.py
@@ -0,0 +1,106 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_Upgrade(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.upgrade = kwargs.get("upgrade", None)
34 self.op = self._getParser()
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if self.upgrade is None:
40 return retval
41
42 if self.upgrade:
43 retval += "# Upgrade existing installation\nupgrade\n"
44 else:
45 retval += "# Install OS instead of upgrade\ninstall\n"
46
47 return retval
48
49 def _getParser(self):
50 op = KSOptionParser()
51 return op
52
53 def parse(self, args):
54 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
55
56 if len(extra) > 0:
57 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "upgrade")
58
59 if self.currentCmd == "upgrade":
60 self.upgrade = True
61 else:
62 self.upgrade = False
63
64 return self
65
66class F11_Upgrade(FC3_Upgrade):
67 removedKeywords = FC3_Upgrade.removedKeywords
68 removedAttrs = FC3_Upgrade.removedAttrs
69
70 def __init__(self, writePriority=0, *args, **kwargs):
71 FC3_Upgrade.__init__(self, writePriority, *args, **kwargs)
72
73 self.op = self._getParser()
74 self.root_device = kwargs.get("root_device", None)
75
76 def __str__(self):
77 if self.upgrade and (self.root_device is not None):
78 retval = KickstartCommand.__str__(self)
79 retval += "# Upgrade existing installation\nupgrade --root-device=%s\n" % self.root_device
80 else:
81 retval = FC3_Upgrade.__str__(self)
82
83 return retval
84
85 def _getParser(self):
86 op = KSOptionParser()
87 op.add_option("--root-device", dest="root_device")
88 return op
89
90 def parse(self, args):
91 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
92
93 if len(extra) > 0:
94 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "upgrade")
95
96 if (opts.root_device is not None) and (opts.root_device == ""):
97 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not accept empty parameter %s") % ("upgrade", "--root-device"))
98 else:
99 self.root_device = opts.root_device
100
101 if self.currentCmd == "upgrade":
102 self.upgrade = True
103 else:
104 self.upgrade = False
105
106 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/user.py b/scripts/lib/mic/3rdparty/pykickstart/commands/user.py
new file mode 100644
index 0000000000..189dc7585f
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/user.py
@@ -0,0 +1,173 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.constants import *
22from pykickstart.errors import *
23from pykickstart.options import *
24
25import gettext
26import warnings
27_ = lambda x: gettext.ldgettext("pykickstart", x)
28
29class FC6_UserData(BaseData):
30 removedKeywords = BaseData.removedKeywords
31 removedAttrs = BaseData.removedAttrs
32
33 def __init__(self, *args, **kwargs):
34 BaseData.__init__(self, *args, **kwargs)
35 self.groups = kwargs.get("groups", [])
36 self.homedir = kwargs.get("homedir", "")
37 self.isCrypted = kwargs.get("isCrypted", False)
38 self.name = kwargs.get("name", "")
39 self.password = kwargs.get("password", "")
40 self.shell = kwargs.get("shell", "")
41 self.uid = kwargs.get("uid", None)
42
43 def __eq__(self, y):
44 return self.name == y.name
45
46 def __str__(self):
47 retval = BaseData.__str__(self)
48
49 if self.uid != "":
50 retval += "user"
51 retval += self._getArgsAsStr() + "\n"
52
53 return retval
54
55 def _getArgsAsStr(self):
56 retval = ""
57
58 if len(self.groups) > 0:
59 retval += " --groups=%s" % ",".join(self.groups)
60 if self.homedir:
61 retval += " --homedir=%s" % self.homedir
62 if self.name:
63 retval += " --name=%s" % self.name
64 if self.password:
65 retval += " --password=%s" % self.password
66 if self.isCrypted:
67 retval += " --iscrypted"
68 if self.shell:
69 retval += " --shell=%s" % self.shell
70 if self.uid:
71 retval += " --uid=%s" % self.uid
72
73 return retval
74
75class F8_UserData(FC6_UserData):
76 removedKeywords = FC6_UserData.removedKeywords
77 removedAttrs = FC6_UserData.removedAttrs
78
79 def __init__(self, *args, **kwargs):
80 FC6_UserData.__init__(self, *args, **kwargs)
81 self.lock = kwargs.get("lock", False)
82
83 def _getArgsAsStr(self):
84 retval = FC6_UserData._getArgsAsStr(self)
85
86 if self.lock:
87 retval += " --lock"
88
89 return retval
90
91class F12_UserData(F8_UserData):
92 removedKeywords = F8_UserData.removedKeywords
93 removedAttrs = F8_UserData.removedAttrs
94
95 def __init__(self, *args, **kwargs):
96 F8_UserData.__init__(self, *args, **kwargs)
97 self.gecos = kwargs.get("gecos", "")
98
99 def _getArgsAsStr(self):
100 retval = F8_UserData._getArgsAsStr(self)
101
102 if self.gecos:
103 retval += " --gecos=\"%s\"" % (self.gecos,)
104
105 return retval
106
107class FC6_User(KickstartCommand):
108 removedKeywords = KickstartCommand.removedKeywords
109 removedAttrs = KickstartCommand.removedAttrs
110
111 def __init__(self, writePriority=0, *args, **kwargs):
112 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
113 self.op = self._getParser()
114
115 self.userList = kwargs.get("userList", [])
116
117 def __str__(self):
118 retval = ""
119 for user in self.userList:
120 retval += user.__str__()
121
122 return retval
123
124 def _getParser(self):
125 def groups_cb (option, opt_str, value, parser):
126 for d in value.split(','):
127 parser.values.ensure_value(option.dest, []).append(d)
128
129 op = KSOptionParser()
130 op.add_option("--groups", dest="groups", action="callback",
131 callback=groups_cb, nargs=1, type="string")
132 op.add_option("--homedir")
133 op.add_option("--iscrypted", dest="isCrypted", action="store_true",
134 default=False)
135 op.add_option("--name", required=1)
136 op.add_option("--password")
137 op.add_option("--shell")
138 op.add_option("--uid", type="int")
139 return op
140
141 def parse(self, args):
142 ud = self.handler.UserData()
143 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
144 self._setToObj(self.op, opts, ud)
145 ud.lineno = self.lineno
146
147 # Check for duplicates in the data list.
148 if ud in self.dataList():
149 warnings.warn(_("A user with the name %s has already been defined.") % ud.name)
150
151 return ud
152
153 def dataList(self):
154 return self.userList
155
156class F8_User(FC6_User):
157 removedKeywords = FC6_User.removedKeywords
158 removedAttrs = FC6_User.removedAttrs
159
160 def _getParser(self):
161 op = FC6_User._getParser(self)
162 op.add_option("--lock", action="store_true", default=False)
163 op.add_option("--plaintext", dest="isCrypted", action="store_false")
164 return op
165
166class F12_User(F8_User):
167 removedKeywords = F8_User.removedKeywords
168 removedAttrs = F8_User.removedAttrs
169
170 def _getParser(self):
171 op = F8_User._getParser(self)
172 op.add_option("--gecos", type="string")
173 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/vnc.py b/scripts/lib/mic/3rdparty/pykickstart/commands/vnc.py
new file mode 100644
index 0000000000..200ccfba2e
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/vnc.py
@@ -0,0 +1,114 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24class FC3_Vnc(KickstartCommand):
25 removedKeywords = KickstartCommand.removedKeywords
26 removedAttrs = KickstartCommand.removedAttrs
27
28 def __init__(self, writePriority=0, *args, **kwargs):
29 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
30 self.op = self._getParser()
31
32 self.enabled = kwargs.get("enabled", False)
33 self.password = kwargs.get("password", "")
34 self.connect = kwargs.get("connect", "")
35
36 def __str__(self):
37 retval = KickstartCommand.__str__(self)
38
39 if not self.enabled:
40 return retval
41
42 retval += "vnc"
43
44 if self.connect != "":
45 retval += " --connect=%s" % self.connect
46 if self.password != "":
47 retval += " --password=%s" % self.password
48
49 return retval + "\n"
50
51 def _getParser(self):
52 op = KSOptionParser()
53 op.add_option("--connect")
54 op.add_option("--password", dest="password")
55 return op
56
57 def parse(self, args):
58 self.enabled = True
59 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
60 self._setToSelf(self.op, opts)
61 return self
62
63class FC6_Vnc(FC3_Vnc):
64 removedKeywords = FC3_Vnc.removedKeywords + ["connect"]
65 removedAttrs = FC3_Vnc.removedAttrs + ["connect"]
66
67 def __init__(self, writePriority=0, host="", port="", *args, **kwargs):
68 FC3_Vnc.__init__(self, writePriority, *args, **kwargs)
69 self.deleteRemovedAttrs()
70
71 self.host = kwargs.get("host", "")
72 self.port = kwargs.get("port", "")
73
74 def __str__(self):
75 retval = KickstartCommand.__str__(self)
76
77 if not self.enabled:
78 return retval
79
80 retval += "vnc"
81
82 if self.host != "":
83 retval += " --host=%s" % self.host
84
85 if self.port != "":
86 retval += " --port=%s" % self.port
87 if self.password != "":
88 retval += " --password=%s" % self.password
89
90 return retval + "\n"
91
92 def _getParser(self):
93 def connect_cb (option, opt_str, value, parser):
94 cargs = value.split(":")
95 parser.values.ensure_value("host", cargs[0])
96
97 if len(cargs) > 1:
98 parser.values.ensure_value("port", cargs[1])
99
100 op = FC3_Vnc._getParser(self)
101 op.add_option("--connect", action="callback", callback=connect_cb,
102 nargs=1, type="string")
103 op.add_option("--host", dest="host")
104 op.add_option("--port", dest="port")
105 return op
106
107class F9_Vnc(FC6_Vnc):
108 removedKeywords = FC6_Vnc.removedKeywords
109 removedAttrs = FC6_Vnc.removedAttrs
110
111 def _getParser(self):
112 op = FC6_Vnc._getParser(self)
113 op.remove_option("--connect")
114 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/volgroup.py b/scripts/lib/mic/3rdparty/pykickstart/commands/volgroup.py
new file mode 100644
index 0000000000..255c47f0ae
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/volgroup.py
@@ -0,0 +1,102 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24import warnings
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_VolGroupData(BaseData):
28 removedKeywords = BaseData.removedKeywords
29 removedAttrs = BaseData.removedAttrs
30
31 def __init__(self, *args, **kwargs):
32 BaseData.__init__(self, *args, **kwargs)
33 self.format = kwargs.get("format", True)
34 self.pesize = kwargs.get("pesize", 32768)
35 self.preexist = kwargs.get("preexist", False)
36 self.vgname = kwargs.get("vgname", "")
37 self.physvols = kwargs.get("physvols", [])
38
39 def __eq__(self, y):
40 return self.vgname == y.vgname
41
42 def __str__(self):
43 retval = BaseData.__str__(self)
44 retval += "volgroup %s" % self.vgname
45
46 if not self.format:
47 retval += " --noformat"
48 if self.pesize != 0:
49 retval += " --pesize=%d" % self.pesize
50 if self.preexist:
51 retval += " --useexisting"
52
53 return retval + " " + " ".join(self.physvols) + "\n"
54
55class FC3_VolGroup(KickstartCommand):
56 removedKeywords = KickstartCommand.removedKeywords
57 removedAttrs = KickstartCommand.removedAttrs
58
59 def __init__(self, writePriority=132, *args, **kwargs):
60 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
61 self.op = self._getParser()
62
63 self.vgList = kwargs.get("vgList", [])
64
65 def __str__(self):
66 retval = ""
67 for vg in self.vgList:
68 retval += vg.__str__()
69
70 return retval
71
72 def _getParser(self):
73 # Have to be a little more complicated to set two values.
74 def vg_cb (option, opt_str, value, parser):
75 parser.values.format = False
76 parser.values.preexist = True
77
78 op = KSOptionParser()
79 op.add_option("--noformat", action="callback", callback=vg_cb,
80 dest="format", default=True, nargs=0)
81 op.add_option("--pesize", dest="pesize", type="int", nargs=1,
82 default=32768)
83 op.add_option("--useexisting", dest="preexist", action="store_true",
84 default=False)
85 return op
86
87 def parse(self, args):
88 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
89 vg = self.handler.VolGroupData()
90 self._setToObj(self.op, opts, vg)
91 vg.lineno = self.lineno
92 vg.vgname = extra[0]
93 vg.physvols = extra[1:]
94
95 # Check for duplicates in the data list.
96 if vg in self.dataList():
97 warnings.warn(_("A volgroup with the name %s has already been defined.") % vg.vgname)
98
99 return vg
100
101 def dataList(self):
102 return self.vgList
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/xconfig.py b/scripts/lib/mic/3rdparty/pykickstart/commands/xconfig.py
new file mode 100644
index 0000000000..644ee86743
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/xconfig.py
@@ -0,0 +1,184 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24import gettext
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_XConfig(KickstartCommand):
28 removedKeywords = KickstartCommand.removedKeywords
29 removedAttrs = KickstartCommand.removedAttrs
30
31 def __init__(self, writePriority=0, *args, **kwargs):
32 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
33 self.op = self._getParser()
34
35 self.card = kwargs.get("card", "")
36 self.defaultdesktop = kwargs.get("defaultdesktop", "")
37 self.depth = kwargs.get("depth", 0)
38 self.hsync = kwargs.get("hsync", "")
39 self.monitor = kwargs.get("monitor", "")
40 self.noProbe = kwargs.get("noProbe", False)
41 self.resolution = kwargs.get("resolution", "")
42 self.server = kwargs.get("server", "")
43 self.startX = kwargs.get("startX", False)
44 self.videoRam = kwargs.get("videoRam", "")
45 self.vsync = kwargs.get("vsync", "")
46
47 def __str__(self):
48 retval = KickstartCommand.__str__(self)
49
50 if self.card != "":
51 retval += " --card=%s" % self.card
52 if self.defaultdesktop != "":
53 retval += " --defaultdesktop=%s" % self.defaultdesktop
54 if self.depth != 0:
55 retval += " --depth=%d" % self.depth
56 if self.hsync != "":
57 retval += " --hsync=%s" % self.hsync
58 if self.monitor != "":
59 retval += " --monitor=%s" % self.monitor
60 if self.noProbe:
61 retval += " --noprobe"
62 if self.resolution != "":
63 retval += " --resolution=%s" % self.resolution
64 if self.server != "":
65 retval += " --server=%s" % self.server
66 if self.startX:
67 retval += " --startxonboot"
68 if self.videoRam != "":
69 retval += " --videoram=%s" % self.videoRam
70 if self.vsync != "":
71 retval += " --vsync=%s" % self.vsync
72
73 if retval != "":
74 retval = "# X Window System configuration information\nxconfig %s\n" % retval
75
76 return retval
77
78 def _getParser(self):
79 op = KSOptionParser()
80 op.add_option("--card")
81 op.add_option("--defaultdesktop")
82 op.add_option("--depth", action="store", type="int", nargs=1)
83 op.add_option("--hsync")
84 op.add_option("--monitor")
85 op.add_option("--noprobe", dest="noProbe", action="store_true",
86 default=False)
87 op.add_option("--resolution")
88 op.add_option("--server")
89 op.add_option("--startxonboot", dest="startX", action="store_true",
90 default=False)
91 op.add_option("--videoram", dest="videoRam")
92 op.add_option("--vsync")
93 return op
94
95 def parse(self, args):
96 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
97 if extra:
98 mapping = {"command": "xconfig", "options": extra}
99 raise KickstartValueError, formatErrorMsg(self.lineno, msg=_("Unexpected arguments to %(command)s command: %(options)s") % mapping)
100
101 self._setToSelf(self.op, opts)
102 return self
103
104class FC6_XConfig(FC3_XConfig):
105 removedKeywords = FC3_XConfig.removedKeywords + ["card", "hsync", "monitor", "noProbe", "vsync"]
106 removedAttrs = FC3_XConfig.removedAttrs + ["card", "hsync", "monitor", "noProbe", "vsync"]
107
108 def __init__(self, writePriority=0, *args, **kwargs):
109 FC3_XConfig.__init__(self, writePriority, *args, **kwargs)
110 self.deleteRemovedAttrs()
111
112 self.driver = kwargs.get("driver", "")
113
114 def __str__(self):
115 retval = KickstartCommand.__str__(self)
116
117 if hasattr(self, "driver") and self.driver != "":
118 retval += " --driver=%s" % self.driver
119 if self.defaultdesktop != "":
120 retval += " --defaultdesktop=%s" % self.defaultdesktop
121 if self.depth != 0:
122 retval += " --depth=%d" % self.depth
123 if hasattr(self, "resolution") and self.resolution != "":
124 retval += " --resolution=%s" % self.resolution
125 if self.startX:
126 retval += " --startxonboot"
127 if hasattr(self, "videoRam") and self.videoRam != "":
128 retval += " --videoram=%s" % self.videoRam
129
130 if retval != "":
131 retval = "# X Window System configuration information\nxconfig %s\n" % retval
132
133 return retval
134
135 def _getParser(self):
136 op = FC3_XConfig._getParser(self)
137 op.add_option("--card", deprecated=1)
138 op.add_option("--driver", dest="driver")
139 op.add_option("--hsync", deprecated=1)
140 op.add_option("--monitor", deprecated=1)
141 op.add_option("--noprobe", deprecated=1)
142 op.add_option("--vsync", deprecated=1)
143 return op
144
145class F9_XConfig(FC6_XConfig):
146 removedKeywords = FC6_XConfig.removedKeywords
147 removedAttrs = FC6_XConfig.removedAttrs
148
149 def _getParser(self):
150 op = FC6_XConfig._getParser(self)
151 op.remove_option("--card")
152 op.remove_option("--hsync")
153 op.remove_option("--monitor")
154 op.remove_option("--noprobe")
155 op.remove_option("--vsync")
156 return op
157
158class F10_XConfig(F9_XConfig):
159 removedKeywords = F9_XConfig.removedKeywords + ["driver", "resolution", "videoRam"]
160 removedAttrs = F9_XConfig.removedAttrs + ["driver", "resolution", "videoRam"]
161
162 def __init__(self, writePriority=0, *args, **kwargs):
163 F9_XConfig.__init__(self, writePriority, *args, **kwargs)
164 self.deleteRemovedAttrs()
165
166 def _getParser(self):
167 op = F9_XConfig._getParser(self)
168 op.add_option("--driver", deprecated=1)
169 op.add_option("--depth", deprecated=1)
170 op.add_option("--resolution", deprecated=1)
171 op.add_option("--videoram", deprecated=1)
172 return op
173
174class F14_XConfig(F10_XConfig):
175 removedKeywords = F10_XConfig.removedKeywords
176 removedAttrs = F10_XConfig.removedAttrs
177
178 def _getParser(self):
179 op = F10_XConfig._getParser(self)
180 op.remove_option("--driver")
181 op.remove_option("--depth")
182 op.remove_option("--resolution")
183 op.remove_option("--videoram")
184 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/zerombr.py b/scripts/lib/mic/3rdparty/pykickstart/commands/zerombr.py
new file mode 100644
index 0000000000..79555a9b27
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/zerombr.py
@@ -0,0 +1,69 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20import warnings
21
22from pykickstart.base import *
23from pykickstart.options import *
24
25import gettext
26_ = lambda x: gettext.ldgettext("pykickstart", x)
27
28class FC3_ZeroMbr(KickstartCommand):
29 removedKeywords = KickstartCommand.removedKeywords
30 removedAttrs = KickstartCommand.removedAttrs
31
32 def __init__(self, writePriority=110, *args, **kwargs):
33 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
34 self.op = self._getParser()
35 self.zerombr = kwargs.get("zerombr", False)
36
37 def __str__(self):
38 retval = KickstartCommand.__str__(self)
39
40 if self.zerombr:
41 retval += "# Clear the Master Boot Record\nzerombr\n"
42
43 return retval
44
45 def _getParser(self):
46 op = KSOptionParser()
47 return op
48
49 def parse(self, args):
50 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
51
52 if len(extra) > 0:
53 warnings.warn(_("Ignoring deprecated option on line %s: The zerombr command no longer takes any options. In future releases, this will result in a fatal error from kickstart. Please modify your kickstart file to remove any options.") % self.lineno, DeprecationWarning)
54
55 self.zerombr = True
56 return self
57
58class F9_ZeroMbr(FC3_ZeroMbr):
59 removedKeywords = FC3_ZeroMbr.removedKeywords
60 removedAttrs = FC3_ZeroMbr.removedAttrs
61
62 def parse(self, args):
63 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
64
65 if len(extra) > 0:
66 raise KickstartParseError, formatErrorMsg(self.lineno, msg=_("Kickstart command %s does not take any arguments") % "zerombr")
67
68 self.zerombr = True
69 return self
diff --git a/scripts/lib/mic/3rdparty/pykickstart/commands/zfcp.py b/scripts/lib/mic/3rdparty/pykickstart/commands/zfcp.py
new file mode 100644
index 0000000000..1ed2694c89
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/commands/zfcp.py
@@ -0,0 +1,134 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.options import *
22
23import gettext
24import warnings
25_ = lambda x: gettext.ldgettext("pykickstart", x)
26
27class FC3_ZFCPData(BaseData):
28 removedKeywords = BaseData.removedKeywords
29 removedAttrs = BaseData.removedAttrs
30
31 def __init__(self, *args, **kwargs):
32 BaseData.__init__(self, *args, **kwargs)
33 self.devnum = kwargs.get("devnum", "")
34 self.wwpn = kwargs.get("wwpn", "")
35 self.fcplun = kwargs.get("fcplun", "")
36 self.scsiid = kwargs.get("scsiid", "")
37 self.scsilun = kwargs.get("scsilun", "")
38
39 def __eq__(self, y):
40 return self.devnum == y.devnum and self.wwpn == y.wwpn and \
41 self.fcplun == y.fcplun and self.scsiid == y.scsiid and \
42 self.scsilun == y.scsilun
43
44 def __str__(self):
45 retval = BaseData.__str__(self)
46 retval += "zfcp"
47
48 if self.devnum != "":
49 retval += " --devnum=%s" % self.devnum
50 if self.wwpn != "":
51 retval += " --wwpn=%s" % self.wwpn
52 if self.fcplun != "":
53 retval += " --fcplun=%s" % self.fcplun
54 if hasattr(self, "scsiid") and self.scsiid != "":
55 retval += " --scsiid=%s" % self.scsiid
56 if hasattr(self, "scsilun") and self.scsilun != "":
57 retval += " --scsilun=%s" % self.scsilun
58
59 return retval + "\n"
60
61class F12_ZFCPData(FC3_ZFCPData):
62 removedKeywords = FC3_ZFCPData.removedKeywords + ["scsiid", "scsilun"]
63 removedAttrs = FC3_ZFCPData.removedAttrs + ["scsiid", "scsilun"]
64
65 def __init__(self, *args, **kwargs):
66 FC3_ZFCPData.__init__(self, *args, **kwargs)
67 self.deleteRemovedAttrs()
68
69F14_ZFCPData = F12_ZFCPData
70
71class FC3_ZFCP(KickstartCommand):
72 removedKeywords = KickstartCommand.removedKeywords
73 removedAttrs = KickstartCommand.removedAttrs
74
75 def __init__(self, writePriority=71, *args, **kwargs):
76 KickstartCommand.__init__(self, writePriority, *args, **kwargs)
77 self.op = self._getParser()
78
79 self.zfcp = kwargs.get("zfcp", [])
80
81 def __str__(self):
82 retval = ""
83 for zfcp in self.zfcp:
84 retval += zfcp.__str__()
85
86 return retval
87
88 def _getParser(self):
89 op = KSOptionParser()
90 op.add_option("--devnum", dest="devnum", required=1)
91 op.add_option("--fcplun", dest="fcplun", required=1)
92 op.add_option("--scsiid", dest="scsiid", required=1)
93 op.add_option("--scsilun", dest="scsilun", required=1)
94 op.add_option("--wwpn", dest="wwpn", required=1)
95 return op
96
97 def parse(self, args):
98 zd = self.handler.ZFCPData()
99 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
100 self._setToObj(self.op, opts, zd)
101 zd.lineno = self.lineno
102
103 # Check for duplicates in the data list.
104 if zd in self.dataList():
105 warnings.warn(_("A zfcp with this information has already been defined."))
106
107 return zd
108
109 def dataList(self):
110 return self.zfcp
111
112class F12_ZFCP(FC3_ZFCP):
113 removedKeywords = FC3_ZFCP.removedKeywords
114 removedAttrs = FC3_ZFCP.removedAttrs + ["scsiid", "scsilun"]
115
116 def __init__(self, *args, **kwargs):
117 FC3_ZFCP.__init__(self, *args, **kwargs)
118 self.deleteRemovedAttrs()
119
120 def _getParser(self):
121 op = FC3_ZFCP._getParser(self)
122 op.add_option("--scsiid", deprecated=1)
123 op.add_option("--scsilun", deprecated=1)
124 return op
125
126class F14_ZFCP(F12_ZFCP):
127 removedKeywords = F12_ZFCP.removedKeywords
128 removedAttrs = F12_ZFCP.removedAttrs
129
130 def _getParser(self):
131 op = F12_ZFCP._getParser(self)
132 op.remove_option("--scsiid")
133 op.remove_option("--scsilun")
134 return op
diff --git a/scripts/lib/mic/3rdparty/pykickstart/constants.py b/scripts/lib/mic/3rdparty/pykickstart/constants.py
new file mode 100644
index 0000000000..5e12fc80ec
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/constants.py
@@ -0,0 +1,57 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005-2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20CLEARPART_TYPE_LINUX = 0
21CLEARPART_TYPE_ALL = 1
22CLEARPART_TYPE_NONE = 2
23
24DISPLAY_MODE_CMDLINE = 0
25DISPLAY_MODE_GRAPHICAL = 1
26DISPLAY_MODE_TEXT = 2
27
28FIRSTBOOT_DEFAULT = 0
29FIRSTBOOT_SKIP = 1
30FIRSTBOOT_RECONFIG = 2
31
32KS_MISSING_PROMPT = 0
33KS_MISSING_IGNORE = 1
34
35SELINUX_DISABLED = 0
36SELINUX_ENFORCING = 1
37SELINUX_PERMISSIVE = 2
38
39KS_SCRIPT_PRE = 0
40KS_SCRIPT_POST = 1
41KS_SCRIPT_TRACEBACK = 2
42
43KS_WAIT = 0
44KS_REBOOT = 1
45KS_SHUTDOWN = 2
46
47KS_INSTKEY_SKIP = -99
48
49BOOTPROTO_DHCP = "dhcp"
50BOOTPROTO_BOOTP = "bootp"
51BOOTPROTO_STATIC = "static"
52BOOTPROTO_QUERY = "query"
53BOOTPROTO_IBFT = "ibft"
54
55GROUP_REQUIRED = 0
56GROUP_DEFAULT = 1
57GROUP_ALL = 2
diff --git a/scripts/lib/mic/3rdparty/pykickstart/errors.py b/scripts/lib/mic/3rdparty/pykickstart/errors.py
new file mode 100644
index 0000000000..a234d99d43
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/errors.py
@@ -0,0 +1,103 @@
1#
2# errors.py: Kickstart error handling.
3#
4# Chris Lumens <clumens@redhat.com>
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20"""
21Error handling classes and functions.
22
23This module exports a single function:
24
25 formatErrorMsg - Properly formats an error message.
26
27It also exports several exception classes:
28
29 KickstartError - A generic exception class.
30
31 KickstartParseError - An exception for errors relating to parsing.
32
33 KickstartValueError - An exception for errors relating to option
34 processing.
35
36 KickstartVersionError - An exception for errors relating to unsupported
37 syntax versions.
38"""
39import gettext
40_ = lambda x: gettext.ldgettext("pykickstart", x)
41
42def formatErrorMsg(lineno, msg=""):
43 """Properly format the error message msg for inclusion in an exception."""
44 if msg != "":
45 mapping = {"lineno": lineno, "msg": msg}
46 return _("The following problem occurred on line %(lineno)s of the kickstart file:\n\n%(msg)s\n") % mapping
47 else:
48 return _("There was a problem reading from line %s of the kickstart file") % lineno
49
50class KickstartError(Exception):
51 """A generic exception class for unspecific error conditions."""
52 def __init__(self, val = ""):
53 """Create a new KickstartError exception instance with the descriptive
54 message val. val should be the return value of formatErrorMsg.
55 """
56 Exception.__init__(self)
57 self.value = val
58
59 def __str__ (self):
60 return self.value
61
62class KickstartParseError(KickstartError):
63 """An exception class for errors when processing the input file, such as
64 unknown options, commands, or sections.
65 """
66 def __init__(self, msg):
67 """Create a new KickstartParseError exception instance with the
68 descriptive message val. val should be the return value of
69 formatErrorMsg.
70 """
71 KickstartError.__init__(self, msg)
72
73 def __str__(self):
74 return self.value
75
76class KickstartValueError(KickstartError):
77 """An exception class for errors when processing arguments to commands,
78 such as too many arguments, too few arguments, or missing required
79 arguments.
80 """
81 def __init__(self, msg):
82 """Create a new KickstartValueError exception instance with the
83 descriptive message val. val should be the return value of
84 formatErrorMsg.
85 """
86 KickstartError.__init__(self, msg)
87
88 def __str__ (self):
89 return self.value
90
91class KickstartVersionError(KickstartError):
92 """An exception class for errors related to using an incorrect version of
93 kickstart syntax.
94 """
95 def __init__(self, msg):
96 """Create a new KickstartVersionError exception instance with the
97 descriptive message val. val should be the return value of
98 formatErrorMsg.
99 """
100 KickstartError.__init__(self, msg)
101
102 def __str__ (self):
103 return self.value
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/__init__.py
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py
new file mode 100644
index 0000000000..d8c8f2b899
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/control.py
@@ -0,0 +1,1307 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.version import *
21from pykickstart.commands import *
22
23# This map is keyed on kickstart syntax version as provided by
24# pykickstart.version. Within each sub-dict is a mapping from command name
25# to the class that handles it. This is an onto mapping - that is, multiple
26# command names can map to the same class. However, the Handler will ensure
27# that only one instance of each class ever exists.
28commandMap = {
29 FC3: {
30 "auth": authconfig.FC3_Authconfig,
31 "authconfig": authconfig.FC3_Authconfig,
32 "autopart": autopart.FC3_AutoPart,
33 "autostep": autostep.FC3_AutoStep,
34 "bootloader": bootloader.FC3_Bootloader,
35 "cdrom": method.FC3_Method,
36 "clearpart": clearpart.FC3_ClearPart,
37 "cmdline": displaymode.FC3_DisplayMode,
38 "device": device.FC3_Device,
39 "deviceprobe": deviceprobe.FC3_DeviceProbe,
40 "driverdisk": driverdisk.FC3_DriverDisk,
41 "firewall": firewall.FC3_Firewall,
42 "firstboot": firstboot.FC3_Firstboot,
43 "graphical": displaymode.FC3_DisplayMode,
44 "halt": reboot.FC3_Reboot,
45 "harddrive": method.FC3_Method,
46 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
47 "install": upgrade.FC3_Upgrade,
48 "interactive": interactive.FC3_Interactive,
49 "keyboard": keyboard.FC3_Keyboard,
50 "lang": lang.FC3_Lang,
51 "langsupport": langsupport.FC3_LangSupport,
52 "lilo": bootloader.FC3_Bootloader,
53 "lilocheck": lilocheck.FC3_LiloCheck,
54 "logvol": logvol.FC3_LogVol,
55 "monitor": monitor.FC3_Monitor,
56 "mouse": mouse.FC3_Mouse,
57 "network": network.FC3_Network,
58 "nfs": method.FC3_Method,
59 "part": partition.FC3_Partition,
60 "partition": partition.FC3_Partition,
61 "poweroff": reboot.FC3_Reboot,
62 "raid": raid.FC3_Raid,
63 "reboot": reboot.FC3_Reboot,
64 "rootpw": rootpw.FC3_RootPw,
65 "selinux": selinux.FC3_SELinux,
66 "shutdown": reboot.FC3_Reboot,
67 "skipx": skipx.FC3_SkipX,
68 "text": displaymode.FC3_DisplayMode,
69 "timezone": timezone.FC3_Timezone,
70 "upgrade": upgrade.FC3_Upgrade,
71 "url": method.FC3_Method,
72 "vnc": vnc.FC3_Vnc,
73 "volgroup": volgroup.FC3_VolGroup,
74 "xconfig": xconfig.FC3_XConfig,
75 "zerombr": zerombr.FC3_ZeroMbr,
76 "zfcp": zfcp.FC3_ZFCP,
77 },
78
79 # based on fc3
80 FC4: {
81 "auth": authconfig.FC3_Authconfig,
82 "authconfig": authconfig.FC3_Authconfig,
83 "autopart": autopart.FC3_AutoPart,
84 "autostep": autostep.FC3_AutoStep,
85 "bootloader": bootloader.FC4_Bootloader,
86 "cdrom": method.FC3_Method,
87 "clearpart": clearpart.FC3_ClearPart,
88 "cmdline": displaymode.FC3_DisplayMode,
89 "device": device.FC3_Device,
90 "deviceprobe": deviceprobe.FC3_DeviceProbe,
91 "driverdisk": driverdisk.FC4_DriverDisk,
92 "firewall": firewall.FC3_Firewall,
93 "firstboot": firstboot.FC3_Firstboot,
94 "graphical": displaymode.FC3_DisplayMode,
95 "halt": reboot.FC3_Reboot,
96 "harddrive": method.FC3_Method,
97 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
98 "install": upgrade.FC3_Upgrade,
99 "interactive": interactive.FC3_Interactive,
100 "keyboard": keyboard.FC3_Keyboard,
101 "lang": lang.FC3_Lang,
102 "langsupport": langsupport.FC3_LangSupport,
103 "logvol": logvol.FC4_LogVol,
104 "mediacheck": mediacheck.FC4_MediaCheck,
105 "monitor": monitor.FC3_Monitor,
106 "mouse": mouse.FC3_Mouse,
107 "network": network.FC4_Network,
108 "nfs": method.FC3_Method,
109 "part": partition.FC4_Partition,
110 "partition": partition.FC4_Partition,
111 "poweroff": reboot.FC3_Reboot,
112 "raid": raid.FC4_Raid,
113 "reboot": reboot.FC3_Reboot,
114 "rootpw": rootpw.FC3_RootPw,
115 "selinux": selinux.FC3_SELinux,
116 "shutdown": reboot.FC3_Reboot,
117 "skipx": skipx.FC3_SkipX,
118 "text": displaymode.FC3_DisplayMode,
119 "timezone": timezone.FC3_Timezone,
120 "upgrade": upgrade.FC3_Upgrade,
121 "url": method.FC3_Method,
122 "vnc": vnc.FC3_Vnc,
123 "volgroup": volgroup.FC3_VolGroup,
124 "xconfig": xconfig.FC3_XConfig,
125 "zerombr": zerombr.FC3_ZeroMbr,
126 "zfcp": zfcp.FC3_ZFCP,
127 },
128
129 # based on fc4
130 FC5: {
131 "auth": authconfig.FC3_Authconfig,
132 "authconfig": authconfig.FC3_Authconfig,
133 "autopart": autopart.FC3_AutoPart,
134 "autostep": autostep.FC3_AutoStep,
135 "bootloader": bootloader.FC4_Bootloader,
136 "cdrom": method.FC3_Method,
137 "clearpart": clearpart.FC3_ClearPart,
138 "cmdline": displaymode.FC3_DisplayMode,
139 "device": device.FC3_Device,
140 "deviceprobe": deviceprobe.FC3_DeviceProbe,
141 "driverdisk": driverdisk.FC4_DriverDisk,
142 "firewall": firewall.FC3_Firewall,
143 "firstboot": firstboot.FC3_Firstboot,
144 "graphical": displaymode.FC3_DisplayMode,
145 "halt": reboot.FC3_Reboot,
146 "harddrive": method.FC3_Method,
147 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
148 "install": upgrade.FC3_Upgrade,
149 "interactive": interactive.FC3_Interactive,
150 "keyboard": keyboard.FC3_Keyboard,
151 "lang": lang.FC3_Lang,
152 "langsupport": langsupport.FC5_LangSupport,
153 "logvol": logvol.FC4_LogVol,
154 "mediacheck": mediacheck.FC4_MediaCheck,
155 "monitor": monitor.FC3_Monitor,
156 "mouse": mouse.FC3_Mouse,
157 "network": network.FC4_Network,
158 "nfs": method.FC3_Method,
159 "part": partition.FC4_Partition,
160 "partition": partition.FC4_Partition,
161 "poweroff": reboot.FC3_Reboot,
162 "raid": raid.FC5_Raid,
163 "reboot": reboot.FC3_Reboot,
164 "rootpw": rootpw.FC3_RootPw,
165 "selinux": selinux.FC3_SELinux,
166 "shutdown": reboot.FC3_Reboot,
167 "skipx": skipx.FC3_SkipX,
168 "text": displaymode.FC3_DisplayMode,
169 "timezone": timezone.FC3_Timezone,
170 "upgrade": upgrade.FC3_Upgrade,
171 "url": method.FC3_Method,
172 "vnc": vnc.FC3_Vnc,
173 "volgroup": volgroup.FC3_VolGroup,
174 "xconfig": xconfig.FC3_XConfig,
175 "zerombr": zerombr.FC3_ZeroMbr,
176 "zfcp": zfcp.FC3_ZFCP,
177 },
178
179 # based on fc5
180 FC6: {
181 "auth": authconfig.FC3_Authconfig,
182 "authconfig": authconfig.FC3_Authconfig,
183 "autopart": autopart.FC3_AutoPart,
184 "autostep": autostep.FC3_AutoStep,
185 "bootloader": bootloader.FC4_Bootloader,
186 "cdrom": method.FC6_Method,
187 "clearpart": clearpart.FC3_ClearPart,
188 "cmdline": displaymode.FC3_DisplayMode,
189 "device": device.FC3_Device,
190 "deviceprobe": deviceprobe.FC3_DeviceProbe,
191 "dmraid": dmraid.FC6_DmRaid,
192 "driverdisk": driverdisk.FC4_DriverDisk,
193 "firewall": firewall.FC3_Firewall,
194 "firstboot": firstboot.FC3_Firstboot,
195 "graphical": displaymode.FC3_DisplayMode,
196 "halt": reboot.FC6_Reboot,
197 "harddrive": method.FC6_Method,
198 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
199 "install": upgrade.FC3_Upgrade,
200 "interactive": interactive.FC3_Interactive,
201 "iscsi": iscsi.FC6_Iscsi,
202 "iscsiname": iscsiname.FC6_IscsiName,
203 "keyboard": keyboard.FC3_Keyboard,
204 "lang": lang.FC3_Lang,
205 "langsupport": langsupport.FC5_LangSupport,
206 "logging": logging.FC6_Logging,
207 "logvol": logvol.FC4_LogVol,
208 "mediacheck": mediacheck.FC4_MediaCheck,
209 "monitor": monitor.FC6_Monitor,
210 "mouse": mouse.FC3_Mouse,
211 "multipath": multipath.FC6_MultiPath,
212 "network": network.FC6_Network,
213 "nfs": method.FC6_Method,
214 "part": partition.FC4_Partition,
215 "partition": partition.FC4_Partition,
216 "poweroff": reboot.FC6_Reboot,
217 "raid": raid.FC5_Raid,
218 "reboot": reboot.FC6_Reboot,
219 "repo": repo.FC6_Repo,
220 "rootpw": rootpw.FC3_RootPw,
221 "selinux": selinux.FC3_SELinux,
222 "services": services.FC6_Services,
223 "shutdown": reboot.FC6_Reboot,
224 "skipx": skipx.FC3_SkipX,
225 "text": displaymode.FC3_DisplayMode,
226 "timezone": timezone.FC6_Timezone,
227 "upgrade": upgrade.FC3_Upgrade,
228 "user": user.FC6_User,
229 "url": method.FC6_Method,
230 "vnc": vnc.FC6_Vnc,
231 "volgroup": volgroup.FC3_VolGroup,
232 "xconfig": xconfig.FC6_XConfig,
233 "zerombr": zerombr.FC3_ZeroMbr,
234 "zfcp": zfcp.FC3_ZFCP,
235 },
236
237 # based on fc6
238 F7: {
239 "auth": authconfig.FC3_Authconfig,
240 "authconfig": authconfig.FC3_Authconfig,
241 "autopart": autopart.FC3_AutoPart,
242 "autostep": autostep.FC3_AutoStep,
243 "bootloader": bootloader.FC4_Bootloader,
244 "cdrom": method.FC6_Method,
245 "clearpart": clearpart.FC3_ClearPart,
246 "cmdline": displaymode.FC3_DisplayMode,
247 "device": device.FC3_Device,
248 "deviceprobe": deviceprobe.FC3_DeviceProbe,
249 "dmraid": dmraid.FC6_DmRaid,
250 "driverdisk": driverdisk.FC4_DriverDisk,
251 "firewall": firewall.FC3_Firewall,
252 "firstboot": firstboot.FC3_Firstboot,
253 "graphical": displaymode.FC3_DisplayMode,
254 "halt": reboot.FC6_Reboot,
255 "harddrive": method.FC6_Method,
256 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
257 "install": upgrade.FC3_Upgrade,
258 "interactive": interactive.FC3_Interactive,
259 "iscsi": iscsi.FC6_Iscsi,
260 "iscsiname": iscsiname.FC6_IscsiName,
261 "keyboard": keyboard.FC3_Keyboard,
262 "lang": lang.FC3_Lang,
263 "logging": logging.FC6_Logging,
264 "logvol": logvol.FC4_LogVol,
265 "mediacheck": mediacheck.FC4_MediaCheck,
266 "monitor": monitor.FC6_Monitor,
267 "multipath": multipath.FC6_MultiPath,
268 "network": network.FC6_Network,
269 "nfs": method.FC6_Method,
270 "part": partition.FC4_Partition,
271 "partition": partition.FC4_Partition,
272 "poweroff": reboot.FC6_Reboot,
273 "raid": raid.F7_Raid,
274 "reboot": reboot.FC6_Reboot,
275 "repo": repo.FC6_Repo,
276 "rootpw": rootpw.FC3_RootPw,
277 "selinux": selinux.FC3_SELinux,
278 "services": services.FC6_Services,
279 "shutdown": reboot.FC6_Reboot,
280 "skipx": skipx.FC3_SkipX,
281 "text": displaymode.FC3_DisplayMode,
282 "timezone": timezone.FC6_Timezone,
283 "updates": updates.F7_Updates,
284 "upgrade": upgrade.FC3_Upgrade,
285 "url": method.FC6_Method,
286 "user": user.FC6_User,
287 "vnc": vnc.FC6_Vnc,
288 "volgroup": volgroup.FC3_VolGroup,
289 "xconfig": xconfig.FC6_XConfig,
290 "zerombr": zerombr.FC3_ZeroMbr,
291 "zfcp": zfcp.FC3_ZFCP,
292 },
293
294 # based on f7
295 F8: {
296 "auth": authconfig.FC3_Authconfig,
297 "authconfig": authconfig.FC3_Authconfig,
298 "autopart": autopart.FC3_AutoPart,
299 "autostep": autostep.FC3_AutoStep,
300 "bootloader": bootloader.F8_Bootloader,
301 "cdrom": method.FC6_Method,
302 "clearpart": clearpart.FC3_ClearPart,
303 "cmdline": displaymode.FC3_DisplayMode,
304 "device": device.F8_Device,
305 "deviceprobe": deviceprobe.FC3_DeviceProbe,
306 "dmraid": dmraid.FC6_DmRaid,
307 "driverdisk": driverdisk.FC4_DriverDisk,
308 "firewall": firewall.FC3_Firewall,
309 "firstboot": firstboot.FC3_Firstboot,
310 "graphical": displaymode.FC3_DisplayMode,
311 "halt": reboot.FC6_Reboot,
312 "harddrive": method.FC6_Method,
313 "ignoredisk": ignoredisk.F8_IgnoreDisk,
314 "install": upgrade.FC3_Upgrade,
315 "interactive": interactive.FC3_Interactive,
316 "iscsi": iscsi.FC6_Iscsi,
317 "iscsiname": iscsiname.FC6_IscsiName,
318 "keyboard": keyboard.FC3_Keyboard,
319 "lang": lang.FC3_Lang,
320 "logging": logging.FC6_Logging,
321 "logvol": logvol.FC4_LogVol,
322 "mediacheck": mediacheck.FC4_MediaCheck,
323 "monitor": monitor.FC6_Monitor,
324 "multipath": multipath.FC6_MultiPath,
325 "network": network.F8_Network,
326 "nfs": method.FC6_Method,
327 "part": partition.FC4_Partition,
328 "partition": partition.FC4_Partition,
329 "poweroff": reboot.FC6_Reboot,
330 "raid": raid.F7_Raid,
331 "reboot": reboot.FC6_Reboot,
332 "repo": repo.F8_Repo,
333 "rootpw": rootpw.F8_RootPw,
334 "selinux": selinux.FC3_SELinux,
335 "services": services.FC6_Services,
336 "shutdown": reboot.FC6_Reboot,
337 "skipx": skipx.FC3_SkipX,
338 "text": displaymode.FC3_DisplayMode,
339 "timezone": timezone.FC6_Timezone,
340 "updates": updates.F7_Updates,
341 "upgrade": upgrade.FC3_Upgrade,
342 "url": method.FC6_Method,
343 "user": user.F8_User,
344 "vnc": vnc.FC6_Vnc,
345 "volgroup": volgroup.FC3_VolGroup,
346 "xconfig": xconfig.FC6_XConfig,
347 "zerombr": zerombr.FC3_ZeroMbr,
348 "zfcp": zfcp.FC3_ZFCP,
349 },
350
351 # based on f8
352 F9: {
353 "auth": authconfig.FC3_Authconfig,
354 "authconfig": authconfig.FC3_Authconfig,
355 "autopart": autopart.F9_AutoPart,
356 "autostep": autostep.FC3_AutoStep,
357 "bootloader": bootloader.F8_Bootloader,
358 "cdrom": method.FC6_Method,
359 "clearpart": clearpart.FC3_ClearPart,
360 "cmdline": displaymode.FC3_DisplayMode,
361 "device": device.F8_Device,
362 "deviceprobe": deviceprobe.FC3_DeviceProbe,
363 "dmraid": dmraid.FC6_DmRaid,
364 "driverdisk": driverdisk.FC4_DriverDisk,
365 "firewall": firewall.F9_Firewall,
366 "firstboot": firstboot.FC3_Firstboot,
367 "graphical": displaymode.FC3_DisplayMode,
368 "halt": reboot.FC6_Reboot,
369 "harddrive": method.FC6_Method,
370 "ignoredisk": ignoredisk.F8_IgnoreDisk,
371 "install": upgrade.FC3_Upgrade,
372 "interactive": interactive.FC3_Interactive,
373 "iscsi": iscsi.FC6_Iscsi,
374 "iscsiname": iscsiname.FC6_IscsiName,
375 "keyboard": keyboard.FC3_Keyboard,
376 "lang": lang.FC3_Lang,
377 "logging": logging.FC6_Logging,
378 "logvol": logvol.F9_LogVol,
379 "mediacheck": mediacheck.FC4_MediaCheck,
380 "monitor": monitor.FC6_Monitor,
381 "multipath": multipath.FC6_MultiPath,
382 "network": network.F9_Network,
383 "nfs": method.FC6_Method,
384 "part": partition.F9_Partition,
385 "partition": partition.F9_Partition,
386 "poweroff": reboot.FC6_Reboot,
387 "raid": raid.F9_Raid,
388 "reboot": reboot.FC6_Reboot,
389 "repo": repo.F8_Repo,
390 "rootpw": rootpw.F8_RootPw,
391 "selinux": selinux.FC3_SELinux,
392 "services": services.FC6_Services,
393 "shutdown": reboot.FC6_Reboot,
394 "skipx": skipx.FC3_SkipX,
395 "text": displaymode.FC3_DisplayMode,
396 "timezone": timezone.FC6_Timezone,
397 "updates": updates.F7_Updates,
398 "upgrade": upgrade.FC3_Upgrade,
399 "url": method.FC6_Method,
400 "user": user.F8_User,
401 "vnc": vnc.F9_Vnc,
402 "volgroup": volgroup.FC3_VolGroup,
403 "xconfig": xconfig.F9_XConfig,
404 "zerombr": zerombr.F9_ZeroMbr,
405 "zfcp": zfcp.FC3_ZFCP,
406 },
407
408 # based on f9
409 F10: {
410 "auth": authconfig.FC3_Authconfig,
411 "authconfig": authconfig.FC3_Authconfig,
412 "autopart": autopart.F9_AutoPart,
413 "autostep": autostep.FC3_AutoStep,
414 "bootloader": bootloader.F8_Bootloader,
415 "cdrom": method.FC6_Method,
416 "clearpart": clearpart.FC3_ClearPart,
417 "cmdline": displaymode.FC3_DisplayMode,
418 "device": device.F8_Device,
419 "deviceprobe": deviceprobe.FC3_DeviceProbe,
420 "dmraid": dmraid.FC6_DmRaid,
421 "driverdisk": driverdisk.FC4_DriverDisk,
422 "firewall": firewall.F10_Firewall,
423 "firstboot": firstboot.FC3_Firstboot,
424 "graphical": displaymode.FC3_DisplayMode,
425 "halt": reboot.FC6_Reboot,
426 "harddrive": method.FC6_Method,
427 "ignoredisk": ignoredisk.F8_IgnoreDisk,
428 "install": upgrade.FC3_Upgrade,
429 "interactive": interactive.FC3_Interactive,
430 "iscsi": iscsi.F10_Iscsi,
431 "iscsiname": iscsiname.FC6_IscsiName,
432 "keyboard": keyboard.FC3_Keyboard,
433 "lang": lang.FC3_Lang,
434 "logging": logging.FC6_Logging,
435 "logvol": logvol.F9_LogVol,
436 "mediacheck": mediacheck.FC4_MediaCheck,
437 "monitor": monitor.F10_Monitor,
438 "multipath": multipath.FC6_MultiPath,
439 "network": network.F9_Network,
440 "nfs": method.FC6_Method,
441 "part": partition.F9_Partition,
442 "partition": partition.F9_Partition,
443 "poweroff": reboot.FC6_Reboot,
444 "raid": raid.F9_Raid,
445 "reboot": reboot.FC6_Reboot,
446 "repo": repo.F8_Repo,
447 "rescue": rescue.F10_Rescue,
448 "rootpw": rootpw.F8_RootPw,
449 "selinux": selinux.FC3_SELinux,
450 "services": services.FC6_Services,
451 "shutdown": reboot.FC6_Reboot,
452 "skipx": skipx.FC3_SkipX,
453 "text": displaymode.FC3_DisplayMode,
454 "timezone": timezone.FC6_Timezone,
455 "updates": updates.F7_Updates,
456 "upgrade": upgrade.FC3_Upgrade,
457 "url": method.FC6_Method,
458 "user": user.F8_User,
459 "vnc": vnc.F9_Vnc,
460 "volgroup": volgroup.FC3_VolGroup,
461 "xconfig": xconfig.F10_XConfig,
462 "zerombr": zerombr.F9_ZeroMbr,
463 "zfcp": zfcp.FC3_ZFCP,
464 },
465
466 # based on f10
467 F11: {
468 "auth": authconfig.FC3_Authconfig,
469 "authconfig": authconfig.FC3_Authconfig,
470 "autopart": autopart.F9_AutoPart,
471 "autostep": autostep.FC3_AutoStep,
472 "bootloader": bootloader.F8_Bootloader,
473 "cdrom": method.FC6_Method,
474 "clearpart": clearpart.FC3_ClearPart,
475 "cmdline": displaymode.FC3_DisplayMode,
476 "device": device.F8_Device,
477 "deviceprobe": deviceprobe.FC3_DeviceProbe,
478 "dmraid": dmraid.FC6_DmRaid,
479 "driverdisk": driverdisk.FC4_DriverDisk,
480 "firewall": firewall.F10_Firewall,
481 "firstboot": firstboot.FC3_Firstboot,
482 "graphical": displaymode.FC3_DisplayMode,
483 "halt": reboot.FC6_Reboot,
484 "harddrive": method.FC6_Method,
485 "ignoredisk": ignoredisk.F8_IgnoreDisk,
486 "install": upgrade.F11_Upgrade,
487 "interactive": interactive.FC3_Interactive,
488 "iscsi": iscsi.F10_Iscsi,
489 "iscsiname": iscsiname.FC6_IscsiName,
490 "keyboard": keyboard.FC3_Keyboard,
491 "lang": lang.FC3_Lang,
492 "logging": logging.FC6_Logging,
493 "logvol": logvol.F9_LogVol,
494 "mediacheck": mediacheck.FC4_MediaCheck,
495 "monitor": monitor.F10_Monitor,
496 "multipath": multipath.FC6_MultiPath,
497 "network": network.F9_Network,
498 "nfs": method.FC6_Method,
499 "part": partition.F11_Partition,
500 "partition": partition.F11_Partition,
501 "poweroff": reboot.FC6_Reboot,
502 "raid": raid.F9_Raid,
503 "reboot": reboot.FC6_Reboot,
504 "repo": repo.F11_Repo,
505 "rescue": rescue.F10_Rescue,
506 "rootpw": rootpw.F8_RootPw,
507 "selinux": selinux.FC3_SELinux,
508 "services": services.FC6_Services,
509 "shutdown": reboot.FC6_Reboot,
510 "skipx": skipx.FC3_SkipX,
511 "text": displaymode.FC3_DisplayMode,
512 "timezone": timezone.FC6_Timezone,
513 "updates": updates.F7_Updates,
514 "upgrade": upgrade.F11_Upgrade,
515 "url": method.FC6_Method,
516 "user": user.F8_User,
517 "vnc": vnc.F9_Vnc,
518 "volgroup": volgroup.FC3_VolGroup,
519 "xconfig": xconfig.F10_XConfig,
520 "zerombr": zerombr.F9_ZeroMbr,
521 "zfcp": zfcp.FC3_ZFCP,
522 },
523
524 # based on f11
525 F12: {
526 "auth": authconfig.FC3_Authconfig,
527 "authconfig": authconfig.FC3_Authconfig,
528 "autopart": autopart.F12_AutoPart,
529 "autostep": autostep.FC3_AutoStep,
530 "bootloader": bootloader.F12_Bootloader,
531 "cdrom": method.FC6_Method,
532 "clearpart": clearpart.FC3_ClearPart,
533 "cmdline": displaymode.FC3_DisplayMode,
534 "device": device.F8_Device,
535 "deviceprobe": deviceprobe.FC3_DeviceProbe,
536 "dmraid": dmraid.FC6_DmRaid,
537 "driverdisk": driverdisk.F12_DriverDisk,
538 "fcoe": fcoe.F12_Fcoe,
539 "firewall": firewall.F10_Firewall,
540 "firstboot": firstboot.FC3_Firstboot,
541 "graphical": displaymode.FC3_DisplayMode,
542 "group": group.F12_Group,
543 "halt": reboot.FC6_Reboot,
544 "harddrive": method.FC6_Method,
545 "ignoredisk": ignoredisk.F8_IgnoreDisk,
546 "install": upgrade.F11_Upgrade,
547 "interactive": interactive.FC3_Interactive,
548 "iscsi": iscsi.F10_Iscsi,
549 "iscsiname": iscsiname.FC6_IscsiName,
550 "keyboard": keyboard.FC3_Keyboard,
551 "lang": lang.FC3_Lang,
552 "logging": logging.FC6_Logging,
553 "logvol": logvol.F12_LogVol,
554 "mediacheck": mediacheck.FC4_MediaCheck,
555 "monitor": monitor.F10_Monitor,
556 "multipath": multipath.FC6_MultiPath,
557 "network": network.F9_Network,
558 "nfs": method.FC6_Method,
559 "part": partition.F12_Partition,
560 "partition": partition.F12_Partition,
561 "poweroff": reboot.FC6_Reboot,
562 "raid": raid.F12_Raid,
563 "reboot": reboot.FC6_Reboot,
564 "repo": repo.F11_Repo,
565 "rescue": rescue.F10_Rescue,
566 "rootpw": rootpw.F8_RootPw,
567 "selinux": selinux.FC3_SELinux,
568 "services": services.FC6_Services,
569 "shutdown": reboot.FC6_Reboot,
570 "skipx": skipx.FC3_SkipX,
571 "text": displaymode.FC3_DisplayMode,
572 "timezone": timezone.FC6_Timezone,
573 "updates": updates.F7_Updates,
574 "upgrade": upgrade.F11_Upgrade,
575 "url": method.FC6_Method,
576 "user": user.F12_User,
577 "vnc": vnc.F9_Vnc,
578 "volgroup": volgroup.FC3_VolGroup,
579 "xconfig": xconfig.F10_XConfig,
580 "zerombr": zerombr.F9_ZeroMbr,
581 "zfcp": zfcp.F12_ZFCP,
582 },
583
584 # based on f12
585 F13: {
586 "auth": authconfig.FC3_Authconfig,
587 "authconfig": authconfig.FC3_Authconfig,
588 "autopart": autopart.F12_AutoPart,
589 "autostep": autostep.FC3_AutoStep,
590 "bootloader": bootloader.F12_Bootloader,
591 "cdrom": method.F13_Method,
592 "clearpart": clearpart.FC3_ClearPart,
593 "cmdline": displaymode.FC3_DisplayMode,
594 "device": device.F8_Device,
595 "deviceprobe": deviceprobe.FC3_DeviceProbe,
596 "dmraid": dmraid.FC6_DmRaid,
597 "driverdisk": driverdisk.F12_DriverDisk,
598 "fcoe": fcoe.F13_Fcoe,
599 "firewall": firewall.F10_Firewall,
600 "firstboot": firstboot.FC3_Firstboot,
601 "graphical": displaymode.FC3_DisplayMode,
602 "group": group.F12_Group,
603 "halt": reboot.FC6_Reboot,
604 "harddrive": method.F13_Method,
605 "ignoredisk": ignoredisk.F8_IgnoreDisk,
606 "install": upgrade.F11_Upgrade,
607 "interactive": interactive.FC3_Interactive,
608 "iscsi": iscsi.F10_Iscsi,
609 "iscsiname": iscsiname.FC6_IscsiName,
610 "keyboard": keyboard.FC3_Keyboard,
611 "lang": lang.FC3_Lang,
612 "logging": logging.FC6_Logging,
613 "logvol": logvol.F12_LogVol,
614 "mediacheck": mediacheck.FC4_MediaCheck,
615 "monitor": monitor.F10_Monitor,
616 "multipath": multipath.FC6_MultiPath,
617 "network": network.F9_Network,
618 "nfs": method.F13_Method,
619 "part": partition.F12_Partition,
620 "partition": partition.F12_Partition,
621 "poweroff": reboot.FC6_Reboot,
622 "raid": raid.F13_Raid,
623 "reboot": reboot.FC6_Reboot,
624 "repo": repo.F13_Repo,
625 "rescue": rescue.F10_Rescue,
626 "rootpw": rootpw.F8_RootPw,
627 "selinux": selinux.FC3_SELinux,
628 "services": services.FC6_Services,
629 "shutdown": reboot.FC6_Reboot,
630 "skipx": skipx.FC3_SkipX,
631 "sshpw": sshpw.F13_SshPw,
632 "text": displaymode.FC3_DisplayMode,
633 "timezone": timezone.FC6_Timezone,
634 "updates": updates.F7_Updates,
635 "upgrade": upgrade.F11_Upgrade,
636 "url": method.F13_Method,
637 "user": user.F12_User,
638 "vnc": vnc.F9_Vnc,
639 "volgroup": volgroup.FC3_VolGroup,
640 "xconfig": xconfig.F10_XConfig,
641 "zerombr": zerombr.F9_ZeroMbr,
642 "zfcp": zfcp.F12_ZFCP,
643 },
644
645 # based on f13
646 F14: {
647 "auth": authconfig.FC3_Authconfig,
648 "authconfig": authconfig.FC3_Authconfig,
649 "autopart": autopart.F12_AutoPart,
650 "autostep": autostep.FC3_AutoStep,
651 "bootloader": bootloader.F14_Bootloader,
652 "cdrom": method.F14_Method,
653 "clearpart": clearpart.FC3_ClearPart,
654 "cmdline": displaymode.FC3_DisplayMode,
655 "device": device.F8_Device,
656 "deviceprobe": deviceprobe.FC3_DeviceProbe,
657 "dmraid": dmraid.FC6_DmRaid,
658 "driverdisk": driverdisk.F14_DriverDisk,
659 "fcoe": fcoe.F13_Fcoe,
660 "firewall": firewall.F14_Firewall,
661 "firstboot": firstboot.FC3_Firstboot,
662 "graphical": displaymode.FC3_DisplayMode,
663 "group": group.F12_Group,
664 "halt": reboot.FC6_Reboot,
665 "harddrive": method.F14_Method,
666 "ignoredisk": ignoredisk.F14_IgnoreDisk,
667 "install": upgrade.F11_Upgrade,
668 "interactive": interactive.F14_Interactive,
669 "iscsi": iscsi.F10_Iscsi,
670 "iscsiname": iscsiname.FC6_IscsiName,
671 "keyboard": keyboard.FC3_Keyboard,
672 "lang": lang.FC3_Lang,
673 "logging": logging.FC6_Logging,
674 "logvol": logvol.F14_LogVol,
675 "mediacheck": mediacheck.FC4_MediaCheck,
676 "monitor": monitor.F10_Monitor,
677 "multipath": multipath.FC6_MultiPath,
678 "network": network.F9_Network,
679 "nfs": method.F14_Method,
680 "part": partition.F14_Partition,
681 "partition": partition.F14_Partition,
682 "poweroff": reboot.FC6_Reboot,
683 "raid": raid.F14_Raid,
684 "reboot": reboot.FC6_Reboot,
685 "repo": repo.F14_Repo,
686 "rescue": rescue.F10_Rescue,
687 "rootpw": rootpw.F8_RootPw,
688 "selinux": selinux.FC3_SELinux,
689 "services": services.FC6_Services,
690 "shutdown": reboot.FC6_Reboot,
691 "skipx": skipx.FC3_SkipX,
692 "sshpw": sshpw.F13_SshPw,
693 "text": displaymode.FC3_DisplayMode,
694 "timezone": timezone.FC6_Timezone,
695 "updates": updates.F7_Updates,
696 "upgrade": upgrade.F11_Upgrade,
697 "url": method.F14_Method,
698 "user": user.F12_User,
699 "vnc": vnc.F9_Vnc,
700 "volgroup": volgroup.FC3_VolGroup,
701 "xconfig": xconfig.F14_XConfig,
702 "zerombr": zerombr.F9_ZeroMbr,
703 "zfcp": zfcp.F14_ZFCP,
704 },
705
706 # based on f14
707 F15: {
708 "auth": authconfig.FC3_Authconfig,
709 "authconfig": authconfig.FC3_Authconfig,
710 "autopart": autopart.F12_AutoPart,
711 "autostep": autostep.FC3_AutoStep,
712 "bootloader": bootloader.F15_Bootloader,
713 "cdrom": method.F14_Method,
714 "clearpart": clearpart.FC3_ClearPart,
715 "cmdline": displaymode.FC3_DisplayMode,
716 "device": device.F8_Device,
717 "deviceprobe": deviceprobe.FC3_DeviceProbe,
718 "dmraid": dmraid.FC6_DmRaid,
719 "driverdisk": driverdisk.F14_DriverDisk,
720 "fcoe": fcoe.F13_Fcoe,
721 "firewall": firewall.F14_Firewall,
722 "firstboot": firstboot.FC3_Firstboot,
723 "graphical": displaymode.FC3_DisplayMode,
724 "group": group.F12_Group,
725 "halt": reboot.FC6_Reboot,
726 "harddrive": method.F14_Method,
727 "ignoredisk": ignoredisk.F14_IgnoreDisk,
728 "install": upgrade.F11_Upgrade,
729 "iscsi": iscsi.F10_Iscsi,
730 "iscsiname": iscsiname.FC6_IscsiName,
731 "keyboard": keyboard.FC3_Keyboard,
732 "lang": lang.FC3_Lang,
733 "logging": logging.FC6_Logging,
734 "logvol": logvol.F15_LogVol,
735 "mediacheck": mediacheck.FC4_MediaCheck,
736 "monitor": monitor.F10_Monitor,
737 "multipath": multipath.FC6_MultiPath,
738 "network": network.F9_Network,
739 "nfs": method.F14_Method,
740 "part": partition.F14_Partition,
741 "partition": partition.F14_Partition,
742 "poweroff": reboot.FC6_Reboot,
743 "raid": raid.F15_Raid,
744 "reboot": reboot.FC6_Reboot,
745 "repo": repo.F15_Repo,
746 "rescue": rescue.F10_Rescue,
747 "rootpw": rootpw.F8_RootPw,
748 "selinux": selinux.FC3_SELinux,
749 "services": services.FC6_Services,
750 "shutdown": reboot.FC6_Reboot,
751 "skipx": skipx.FC3_SkipX,
752 "sshpw": sshpw.F13_SshPw,
753 "text": displaymode.FC3_DisplayMode,
754 "timezone": timezone.FC6_Timezone,
755 "updates": updates.F7_Updates,
756 "upgrade": upgrade.F11_Upgrade,
757 "url": method.F14_Method,
758 "user": user.F12_User,
759 "vnc": vnc.F9_Vnc,
760 "volgroup": volgroup.FC3_VolGroup,
761 "xconfig": xconfig.F14_XConfig,
762 "zerombr": zerombr.F9_ZeroMbr,
763 "zfcp": zfcp.F14_ZFCP,
764 },
765
766 # based on f15
767 F16: {
768 "auth": authconfig.FC3_Authconfig,
769 "authconfig": authconfig.FC3_Authconfig,
770 "autopart": autopart.F12_AutoPart,
771 "autostep": autostep.FC3_AutoStep,
772 "bootloader": bootloader.F15_Bootloader,
773 "cdrom": method.F14_Method,
774 "clearpart": clearpart.FC3_ClearPart,
775 "cmdline": displaymode.FC3_DisplayMode,
776 "device": device.F8_Device,
777 "deviceprobe": deviceprobe.FC3_DeviceProbe,
778 "dmraid": dmraid.FC6_DmRaid,
779 "driverdisk": driverdisk.F14_DriverDisk,
780 "fcoe": fcoe.F13_Fcoe,
781 "firewall": firewall.F14_Firewall,
782 "firstboot": firstboot.FC3_Firstboot,
783 "graphical": displaymode.FC3_DisplayMode,
784 "group": group.F12_Group,
785 "halt": reboot.FC6_Reboot,
786 "harddrive": method.F14_Method,
787 "ignoredisk": ignoredisk.F14_IgnoreDisk,
788 "install": upgrade.F11_Upgrade,
789 "iscsi": iscsi.F10_Iscsi,
790 "iscsiname": iscsiname.FC6_IscsiName,
791 "keyboard": keyboard.FC3_Keyboard,
792 "lang": lang.FC3_Lang,
793 "logging": logging.FC6_Logging,
794 "logvol": logvol.F15_LogVol,
795 "mediacheck": mediacheck.FC4_MediaCheck,
796 "monitor": monitor.F10_Monitor,
797 "multipath": multipath.FC6_MultiPath,
798 "network": network.F16_Network,
799 "nfs": method.F14_Method,
800 "part": partition.F14_Partition,
801 "partition": partition.F14_Partition,
802 "poweroff": reboot.FC6_Reboot,
803 "raid": raid.F15_Raid,
804 "reboot": reboot.FC6_Reboot,
805 "repo": repo.F15_Repo,
806 "rescue": rescue.F10_Rescue,
807 "rootpw": rootpw.F8_RootPw,
808 "selinux": selinux.FC3_SELinux,
809 "services": services.FC6_Services,
810 "shutdown": reboot.FC6_Reboot,
811 "skipx": skipx.FC3_SkipX,
812 "sshpw": sshpw.F13_SshPw,
813 "text": displaymode.FC3_DisplayMode,
814 "timezone": timezone.FC6_Timezone,
815 "updates": updates.F7_Updates,
816 "upgrade": upgrade.F11_Upgrade,
817 "url": method.F14_Method,
818 "user": user.F12_User,
819 "vnc": vnc.F9_Vnc,
820 "volgroup": volgroup.FC3_VolGroup,
821 "xconfig": xconfig.F14_XConfig,
822 "zerombr": zerombr.F9_ZeroMbr,
823 "zfcp": zfcp.F14_ZFCP,
824 },
825
826 # based on fc1
827 RHEL3: {
828 "auth": authconfig.FC3_Authconfig,
829 "authconfig": authconfig.FC3_Authconfig,
830 "autopart": autopart.FC3_AutoPart,
831 "autostep": autostep.FC3_AutoStep,
832 "bootloader": bootloader.FC3_Bootloader,
833 "cdrom": method.FC3_Method,
834 "clearpart": clearpart.FC3_ClearPart,
835 "cmdline": displaymode.FC3_DisplayMode,
836 "device": device.FC3_Device,
837 "deviceprobe": deviceprobe.FC3_DeviceProbe,
838 "driverdisk": driverdisk.FC3_DriverDisk,
839 "firewall": firewall.FC3_Firewall,
840 "firstboot": firstboot.FC3_Firstboot,
841 "graphical": displaymode.FC3_DisplayMode,
842 "halt": reboot.FC3_Reboot,
843 "harddrive": method.FC3_Method,
844 "ignoredisk": ignoredisk.FC3_IgnoreDisk,
845 "install": upgrade.FC3_Upgrade,
846 "interactive": interactive.FC3_Interactive,
847 "keyboard": keyboard.FC3_Keyboard,
848 "lang": lang.FC3_Lang,
849 "langsupport": langsupport.FC3_LangSupport,
850 "lilo": bootloader.FC3_Bootloader,
851 "lilocheck": lilocheck.FC3_LiloCheck,
852 "logvol": logvol.FC3_LogVol,
853 "monitor": monitor.FC3_Monitor,
854 "mouse": mouse.RHEL3_Mouse,
855 "network": network.FC3_Network,
856 "nfs": method.FC3_Method,
857 "part": partition.FC3_Partition,
858 "partition": partition.FC3_Partition,
859 "poweroff": reboot.FC3_Reboot,
860 "raid": raid.FC3_Raid,
861 "reboot": reboot.FC3_Reboot,
862 "rootpw": rootpw.FC3_RootPw,
863 "shutdown": reboot.FC3_Reboot,
864 "skipx": skipx.FC3_SkipX,
865 "text": displaymode.FC3_DisplayMode,
866 "timezone": timezone.FC3_Timezone,
867 "upgrade": upgrade.FC3_Upgrade,
868 "url": method.FC3_Method,
869 "vnc": vnc.FC3_Vnc,
870 "volgroup": volgroup.FC3_VolGroup,
871 "xconfig": xconfig.FC3_XConfig,
872 "zerombr": zerombr.FC3_ZeroMbr,
873 },
874
875 # based on fc3
876 RHEL4: {
877 "auth": authconfig.FC3_Authconfig,
878 "authconfig": authconfig.FC3_Authconfig,
879 "autopart": autopart.FC3_AutoPart,
880 "autostep": autostep.FC3_AutoStep,
881 "bootloader": bootloader.FC3_Bootloader,
882 "cdrom": method.FC3_Method,
883 "clearpart": clearpart.FC3_ClearPart,
884 "cmdline": displaymode.FC3_DisplayMode,
885 "device": device.FC3_Device,
886 "deviceprobe": deviceprobe.FC3_DeviceProbe,
887 "driverdisk": driverdisk.FC4_DriverDisk,
888 "firewall": firewall.FC3_Firewall,
889 "firstboot": firstboot.FC3_Firstboot,
890 "graphical": displaymode.FC3_DisplayMode,
891 "halt": reboot.FC3_Reboot,
892 "harddrive": method.FC3_Method,
893 "ignoredisk": ignoredisk.F8_IgnoreDisk,
894 "install": upgrade.FC3_Upgrade,
895 "interactive": interactive.FC3_Interactive,
896 "keyboard": keyboard.FC3_Keyboard,
897 "lang": lang.FC3_Lang,
898 "langsupport": langsupport.FC3_LangSupport,
899 "lilo": bootloader.FC3_Bootloader,
900 "lilocheck": lilocheck.FC3_LiloCheck,
901 "logvol": logvol.FC3_LogVol,
902 "monitor": monitor.FC3_Monitor,
903 "mouse": mouse.FC3_Mouse,
904 "network": network.RHEL4_Network,
905 "nfs": method.FC3_Method,
906 "part": partition.FC3_Partition,
907 "partition": partition.FC3_Partition,
908 "poweroff": reboot.FC3_Reboot,
909 "raid": raid.FC3_Raid,
910 "reboot": reboot.FC3_Reboot,
911 "rootpw": rootpw.FC3_RootPw,
912 "selinux": selinux.FC3_SELinux,
913 "shutdown": reboot.FC3_Reboot,
914 "skipx": skipx.FC3_SkipX,
915 "text": displaymode.FC3_DisplayMode,
916 "timezone": timezone.FC3_Timezone,
917 "upgrade": upgrade.FC3_Upgrade,
918 "url": method.FC3_Method,
919 "vnc": vnc.FC3_Vnc,
920 "volgroup": volgroup.FC3_VolGroup,
921 "xconfig": xconfig.FC3_XConfig,
922 "zerombr": zerombr.FC3_ZeroMbr,
923 "zfcp": zfcp.FC3_ZFCP,
924 },
925
926 # based on fc6
927 RHEL5: {
928 "auth": authconfig.FC3_Authconfig,
929 "authconfig": authconfig.FC3_Authconfig,
930 "autopart": autopart.F9_AutoPart,
931 "autostep": autostep.FC3_AutoStep,
932 "bootloader": bootloader.RHEL5_Bootloader,
933 "cdrom": method.FC6_Method,
934 "clearpart": clearpart.FC3_ClearPart,
935 "cmdline": displaymode.FC3_DisplayMode,
936 "device": device.FC3_Device,
937 "deviceprobe": deviceprobe.FC3_DeviceProbe,
938 "dmraid": dmraid.FC6_DmRaid,
939 "driverdisk": driverdisk.F12_DriverDisk,
940 "firewall": firewall.FC3_Firewall,
941 "firstboot": firstboot.FC3_Firstboot,
942 "graphical": displaymode.FC3_DisplayMode,
943 "halt": reboot.FC6_Reboot,
944 "harddrive": method.FC6_Method,
945 "ignoredisk": ignoredisk.F8_IgnoreDisk,
946 "install": upgrade.FC3_Upgrade,
947 "interactive": interactive.FC3_Interactive,
948 "iscsi": iscsi.FC6_Iscsi,
949 "iscsiname": iscsiname.FC6_IscsiName,
950 "key": key.RHEL5_Key,
951 "keyboard": keyboard.FC3_Keyboard,
952 "lang": lang.FC3_Lang,
953 "langsupport": langsupport.FC5_LangSupport,
954 "logging": logging.FC6_Logging,
955 "logvol": logvol.RHEL5_LogVol,
956 "mediacheck": mediacheck.FC4_MediaCheck,
957 "monitor": monitor.FC6_Monitor,
958 "mouse": mouse.FC3_Mouse,
959 "multipath": multipath.FC6_MultiPath,
960 "network": network.RHEL5_Network,
961 "nfs": method.FC6_Method,
962 "part": partition.RHEL5_Partition,
963 "partition": partition.RHEL5_Partition,
964 "poweroff": reboot.FC6_Reboot,
965 "raid": raid.RHEL5_Raid,
966 "reboot": reboot.FC6_Reboot,
967 "repo": repo.FC6_Repo,
968 "rootpw": rootpw.FC3_RootPw,
969 "services": services.FC6_Services,
970 "selinux": selinux.FC3_SELinux,
971 "shutdown": reboot.FC6_Reboot,
972 "skipx": skipx.FC3_SkipX,
973 "text": displaymode.FC3_DisplayMode,
974 "timezone": timezone.FC6_Timezone,
975 "upgrade": upgrade.FC3_Upgrade,
976 "user": user.FC6_User,
977 "url": method.FC6_Method,
978 "vnc": vnc.FC6_Vnc,
979 "volgroup": volgroup.FC3_VolGroup,
980 "xconfig": xconfig.FC6_XConfig,
981 "zerombr": zerombr.FC3_ZeroMbr,
982 "zfcp": zfcp.FC3_ZFCP,
983 },
984
985 # based on f13ish
986 RHEL6: {
987 "auth": authconfig.FC3_Authconfig,
988 "authconfig": authconfig.FC3_Authconfig,
989 "autopart": autopart.F12_AutoPart,
990 "autostep": autostep.FC3_AutoStep,
991 "bootloader": bootloader.RHEL6_Bootloader,
992 "cdrom": method.RHEL6_Method,
993 "clearpart": clearpart.FC3_ClearPart,
994 "cmdline": displaymode.FC3_DisplayMode,
995 "device": device.F8_Device,
996 "deviceprobe": deviceprobe.FC3_DeviceProbe,
997 "dmraid": dmraid.FC6_DmRaid,
998 "driverdisk": driverdisk.F12_DriverDisk,
999 "fcoe": fcoe.F13_Fcoe,
1000 "firewall": firewall.F10_Firewall,
1001 "firstboot": firstboot.FC3_Firstboot,
1002 "graphical": displaymode.FC3_DisplayMode,
1003 "group": group.F12_Group,
1004 "halt": reboot.FC6_Reboot,
1005 "harddrive": method.RHEL6_Method,
1006 "ignoredisk": ignoredisk.RHEL6_IgnoreDisk,
1007 "install": upgrade.F11_Upgrade,
1008 "interactive": interactive.FC3_Interactive,
1009 "iscsi": iscsi.F10_Iscsi,
1010 "iscsiname": iscsiname.FC6_IscsiName,
1011 "keyboard": keyboard.FC3_Keyboard,
1012 "lang": lang.FC3_Lang,
1013 "logging": logging.FC6_Logging,
1014 "logvol": logvol.F12_LogVol,
1015 "mediacheck": mediacheck.FC4_MediaCheck,
1016 "monitor": monitor.F10_Monitor,
1017 "multipath": multipath.FC6_MultiPath,
1018 "network": network.RHEL6_Network,
1019 "nfs": method.RHEL6_Method,
1020 "part": partition.F12_Partition,
1021 "partition": partition.F12_Partition,
1022 "poweroff": reboot.FC6_Reboot,
1023 "raid": raid.F13_Raid,
1024 "reboot": reboot.FC6_Reboot,
1025 "repo": repo.RHEL6_Repo,
1026 "rescue": rescue.F10_Rescue,
1027 "rootpw": rootpw.F8_RootPw,
1028 "selinux": selinux.FC3_SELinux,
1029 "services": services.FC6_Services,
1030 "shutdown": reboot.FC6_Reboot,
1031 "skipx": skipx.FC3_SkipX,
1032 "sshpw": sshpw.F13_SshPw,
1033 "text": displaymode.FC3_DisplayMode,
1034 "timezone": timezone.FC6_Timezone,
1035 "updates": updates.F7_Updates,
1036 "upgrade": upgrade.F11_Upgrade,
1037 "url": method.RHEL6_Method,
1038 "user": user.F12_User,
1039 "vnc": vnc.F9_Vnc,
1040 "volgroup": volgroup.FC3_VolGroup,
1041 "xconfig": xconfig.F10_XConfig,
1042 "zerombr": zerombr.F9_ZeroMbr,
1043 "zfcp": zfcp.F12_ZFCP,
1044 }
1045}
1046
1047# This map is keyed on kickstart syntax version as provided by
1048# pykickstart.version. Within each sub-dict is a mapping from a data object
1049# name to the class that provides it. This is a bijective mapping - that is,
1050# each name maps to exactly one data class and all data classes have a name.
1051# More than one instance of each class is allowed to exist, however.
1052dataMap = {
1053 FC3: {
1054 "DriverDiskData": driverdisk.FC3_DriverDiskData,
1055 "LogVolData": logvol.FC3_LogVolData,
1056 "NetworkData": network.FC3_NetworkData,
1057 "PartData": partition.FC3_PartData,
1058 "RaidData": raid.FC3_RaidData,
1059 "VolGroupData": volgroup.FC3_VolGroupData,
1060 "ZFCPData": zfcp.FC3_ZFCPData,
1061 },
1062 FC4: {
1063 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1064 "LogVolData": logvol.FC4_LogVolData,
1065 "NetworkData": network.FC4_NetworkData,
1066 "PartData": partition.FC4_PartData,
1067 "RaidData": raid.FC4_RaidData,
1068 "VolGroupData": volgroup.FC3_VolGroupData,
1069 "ZFCPData": zfcp.FC3_ZFCPData,
1070 },
1071 FC5: {
1072 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1073 "LogVolData": logvol.FC4_LogVolData,
1074 "NetworkData": network.FC4_NetworkData,
1075 "PartData": partition.FC4_PartData,
1076 "RaidData": raid.FC5_RaidData,
1077 "VolGroupData": volgroup.FC3_VolGroupData,
1078 "ZFCPData": zfcp.FC3_ZFCPData,
1079 },
1080 FC6: {
1081 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1082 "DmRaidData": dmraid.FC6_DmRaidData,
1083 "IscsiData": iscsi.FC6_IscsiData,
1084 "LogVolData": logvol.FC4_LogVolData,
1085 "MultiPathData": multipath.FC6_MultiPathData,
1086 "NetworkData": network.FC6_NetworkData,
1087 "PartData": partition.FC4_PartData,
1088 "RaidData": raid.FC5_RaidData,
1089 "RepoData": repo.FC6_RepoData,
1090 "UserData": user.FC6_UserData,
1091 "VolGroupData": volgroup.FC3_VolGroupData,
1092 "ZFCPData": zfcp.FC3_ZFCPData,
1093 },
1094 F7: {
1095 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1096 "DmRaidData": dmraid.FC6_DmRaidData,
1097 "IscsiData": iscsi.FC6_IscsiData,
1098 "LogVolData": logvol.FC4_LogVolData,
1099 "MultiPathData": multipath.FC6_MultiPathData,
1100 "NetworkData": network.FC6_NetworkData,
1101 "PartData": partition.FC4_PartData,
1102 "RaidData": raid.F7_RaidData,
1103 "RepoData": repo.FC6_RepoData,
1104 "UserData": user.FC6_UserData,
1105 "VolGroupData": volgroup.FC3_VolGroupData,
1106 "ZFCPData": zfcp.FC3_ZFCPData,
1107 },
1108 F8: {
1109 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1110 "DeviceData": device.F8_DeviceData,
1111 "DmRaidData": dmraid.FC6_DmRaidData,
1112 "IscsiData": iscsi.FC6_IscsiData,
1113 "LogVolData": logvol.FC4_LogVolData,
1114 "MultiPathData": multipath.FC6_MultiPathData,
1115 "NetworkData": network.F8_NetworkData,
1116 "PartData": partition.FC4_PartData,
1117 "RaidData": raid.F7_RaidData,
1118 "RepoData": repo.F8_RepoData,
1119 "UserData": user.F8_UserData,
1120 "VolGroupData": volgroup.FC3_VolGroupData,
1121 "ZFCPData": zfcp.FC3_ZFCPData,
1122 },
1123 F9: {
1124 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1125 "DeviceData": device.F8_DeviceData,
1126 "DmRaidData": dmraid.FC6_DmRaidData,
1127 "IscsiData": iscsi.FC6_IscsiData,
1128 "LogVolData": logvol.F9_LogVolData,
1129 "MultiPathData": multipath.FC6_MultiPathData,
1130 "NetworkData": network.F8_NetworkData,
1131 "PartData": partition.F9_PartData,
1132 "RaidData": raid.F9_RaidData,
1133 "RepoData": repo.F8_RepoData,
1134 "UserData": user.F8_UserData,
1135 "VolGroupData": volgroup.FC3_VolGroupData,
1136 "ZFCPData": zfcp.FC3_ZFCPData,
1137 },
1138 F10: {
1139 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1140 "DeviceData": device.F8_DeviceData,
1141 "DmRaidData": dmraid.FC6_DmRaidData,
1142 "IscsiData": iscsi.F10_IscsiData,
1143 "LogVolData": logvol.F9_LogVolData,
1144 "MultiPathData": multipath.FC6_MultiPathData,
1145 "NetworkData": network.F8_NetworkData,
1146 "PartData": partition.F9_PartData,
1147 "RaidData": raid.F9_RaidData,
1148 "RepoData": repo.F8_RepoData,
1149 "UserData": user.F8_UserData,
1150 "VolGroupData": volgroup.FC3_VolGroupData,
1151 "ZFCPData": zfcp.FC3_ZFCPData,
1152 },
1153 F11: {
1154 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1155 "DeviceData": device.F8_DeviceData,
1156 "DmRaidData": dmraid.FC6_DmRaidData,
1157 "IscsiData": iscsi.F10_IscsiData,
1158 "LogVolData": logvol.F9_LogVolData,
1159 "MultiPathData": multipath.FC6_MultiPathData,
1160 "NetworkData": network.F8_NetworkData,
1161 "PartData": partition.F11_PartData,
1162 "RaidData": raid.F9_RaidData,
1163 "RepoData": repo.F11_RepoData,
1164 "UserData": user.F8_UserData,
1165 "VolGroupData": volgroup.FC3_VolGroupData,
1166 "ZFCPData": zfcp.FC3_ZFCPData,
1167 },
1168 F12: {
1169 "DriverDiskData": driverdisk.F12_DriverDiskData,
1170 "DeviceData": device.F8_DeviceData,
1171 "DmRaidData": dmraid.FC6_DmRaidData,
1172 "FcoeData": fcoe.F12_FcoeData,
1173 "GroupData": group.F12_GroupData,
1174 "IscsiData": iscsi.F10_IscsiData,
1175 "LogVolData": logvol.F12_LogVolData,
1176 "MultiPathData": multipath.FC6_MultiPathData,
1177 "NetworkData": network.F8_NetworkData,
1178 "PartData": partition.F12_PartData,
1179 "RaidData": raid.F12_RaidData,
1180 "RepoData": repo.F11_RepoData,
1181 "UserData": user.F12_UserData,
1182 "VolGroupData": volgroup.FC3_VolGroupData,
1183 "ZFCPData": zfcp.F12_ZFCPData,
1184 },
1185 F13: {
1186 "DriverDiskData": driverdisk.F12_DriverDiskData,
1187 "DeviceData": device.F8_DeviceData,
1188 "DmRaidData": dmraid.FC6_DmRaidData,
1189 "FcoeData": fcoe.F13_FcoeData,
1190 "GroupData": group.F12_GroupData,
1191 "IscsiData": iscsi.F10_IscsiData,
1192 "LogVolData": logvol.F12_LogVolData,
1193 "MultiPathData": multipath.FC6_MultiPathData,
1194 "NetworkData": network.F8_NetworkData,
1195 "PartData": partition.F12_PartData,
1196 "RaidData": raid.F13_RaidData,
1197 "RepoData": repo.F13_RepoData,
1198 "SshPwData": sshpw.F13_SshPwData,
1199 "UserData": user.F12_UserData,
1200 "VolGroupData": volgroup.FC3_VolGroupData,
1201 "ZFCPData": zfcp.F12_ZFCPData,
1202 },
1203 F14: {
1204 "DriverDiskData": driverdisk.F14_DriverDiskData,
1205 "DeviceData": device.F8_DeviceData,
1206 "DmRaidData": dmraid.FC6_DmRaidData,
1207 "FcoeData": fcoe.F13_FcoeData,
1208 "GroupData": group.F12_GroupData,
1209 "IscsiData": iscsi.F10_IscsiData,
1210 "LogVolData": logvol.F14_LogVolData,
1211 "MultiPathData": multipath.FC6_MultiPathData,
1212 "NetworkData": network.F8_NetworkData,
1213 "PartData": partition.F14_PartData,
1214 "RaidData": raid.F14_RaidData,
1215 "RepoData": repo.F14_RepoData,
1216 "SshPwData": sshpw.F13_SshPwData,
1217 "UserData": user.F12_UserData,
1218 "VolGroupData": volgroup.FC3_VolGroupData,
1219 "ZFCPData": zfcp.F14_ZFCPData,
1220 },
1221 F15: {
1222 "DriverDiskData": driverdisk.F14_DriverDiskData,
1223 "DeviceData": device.F8_DeviceData,
1224 "DmRaidData": dmraid.FC6_DmRaidData,
1225 "FcoeData": fcoe.F13_FcoeData,
1226 "GroupData": group.F12_GroupData,
1227 "IscsiData": iscsi.F10_IscsiData,
1228 "LogVolData": logvol.F15_LogVolData,
1229 "MultiPathData": multipath.FC6_MultiPathData,
1230 "NetworkData": network.F8_NetworkData,
1231 "PartData": partition.F14_PartData,
1232 "RaidData": raid.F15_RaidData,
1233 "RepoData": repo.F15_RepoData,
1234 "SshPwData": sshpw.F13_SshPwData,
1235 "UserData": user.F12_UserData,
1236 "VolGroupData": volgroup.FC3_VolGroupData,
1237 "ZFCPData": zfcp.F14_ZFCPData,
1238 },
1239 F16: {
1240 "DriverDiskData": driverdisk.F14_DriverDiskData,
1241 "DeviceData": device.F8_DeviceData,
1242 "DmRaidData": dmraid.FC6_DmRaidData,
1243 "FcoeData": fcoe.F13_FcoeData,
1244 "GroupData": group.F12_GroupData,
1245 "IscsiData": iscsi.F10_IscsiData,
1246 "LogVolData": logvol.F15_LogVolData,
1247 "MultiPathData": multipath.FC6_MultiPathData,
1248 "NetworkData": network.F16_NetworkData,
1249 "PartData": partition.F14_PartData,
1250 "RaidData": raid.F15_RaidData,
1251 "RepoData": repo.F15_RepoData,
1252 "SshPwData": sshpw.F13_SshPwData,
1253 "UserData": user.F12_UserData,
1254 "VolGroupData": volgroup.FC3_VolGroupData,
1255 "ZFCPData": zfcp.F14_ZFCPData,
1256 },
1257 RHEL3: {
1258 "DriverDiskData": driverdisk.FC3_DriverDiskData,
1259 "LogVolData": logvol.FC3_LogVolData,
1260 "NetworkData": network.RHEL4_NetworkData,
1261 "PartData": partition.FC3_PartData,
1262 "RaidData": raid.FC3_RaidData,
1263 "VolGroupData": volgroup.FC3_VolGroupData,
1264 "ZFCPData": zfcp.FC3_ZFCPData,
1265 },
1266 RHEL4: {
1267 "DriverDiskData": driverdisk.FC4_DriverDiskData,
1268 "LogVolData": logvol.FC3_LogVolData,
1269 "NetworkData": network.RHEL4_NetworkData,
1270 "PartData": partition.FC3_PartData,
1271 "RaidData": raid.FC3_RaidData,
1272 "VolGroupData": volgroup.FC3_VolGroupData,
1273 "ZFCPData": zfcp.FC3_ZFCPData,
1274 },
1275 RHEL5: {
1276 "DriverDiskData": driverdisk.F12_DriverDiskData,
1277 "DmRaidData": dmraid.FC6_DmRaidData,
1278 "IscsiData": iscsi.FC6_IscsiData,
1279 "LogVolData": logvol.RHEL5_LogVolData,
1280 "MultiPathData": multipath.FC6_MultiPathData,
1281 "NetworkData": network.FC6_NetworkData,
1282 "PartData": partition.RHEL5_PartData,
1283 "RaidData": raid.RHEL5_RaidData,
1284 "RepoData": repo.FC6_RepoData,
1285 "UserData": user.FC6_UserData,
1286 "VolGroupData": volgroup.FC3_VolGroupData,
1287 "ZFCPData": zfcp.FC3_ZFCPData,
1288 },
1289 RHEL6: {
1290 "DriverDiskData": driverdisk.F12_DriverDiskData,
1291 "DeviceData": device.F8_DeviceData,
1292 "DmRaidData": dmraid.FC6_DmRaidData,
1293 "FcoeData": fcoe.F13_FcoeData,
1294 "GroupData": group.F12_GroupData,
1295 "IscsiData": iscsi.F10_IscsiData,
1296 "LogVolData": logvol.F12_LogVolData,
1297 "MultiPathData": multipath.FC6_MultiPathData,
1298 "NetworkData": network.RHEL6_NetworkData,
1299 "PartData": partition.F12_PartData,
1300 "RaidData": raid.F13_RaidData,
1301 "RepoData": repo.RHEL6_RepoData,
1302 "SshPwData": sshpw.F13_SshPwData,
1303 "UserData": user.F12_UserData,
1304 "VolGroupData": volgroup.FC3_VolGroupData,
1305 "ZFCPData": zfcp.F12_ZFCPData,
1306 }
1307}
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f10.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f10.py
new file mode 100644
index 0000000000..17c8211bbf
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f10.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F10Handler(BaseHandler):
24 version = F10
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f11.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f11.py
new file mode 100644
index 0000000000..d21aee3e8b
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f11.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2008 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F11Handler(BaseHandler):
24 version = F11
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f12.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f12.py
new file mode 100644
index 0000000000..cea3ecef6b
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f12.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F12Handler(BaseHandler):
24 version = F12
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f13.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f13.py
new file mode 100644
index 0000000000..b94c738f79
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f13.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F13Handler(BaseHandler):
24 version = F13
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f14.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f14.py
new file mode 100644
index 0000000000..478f75d15e
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f14.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2010 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F14Handler(BaseHandler):
24 version = F14
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f15.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f15.py
new file mode 100644
index 0000000000..12aecb4c1a
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f15.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2010 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F15Handler(BaseHandler):
24 version = F15
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py
new file mode 100644
index 0000000000..3c52f8d754
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f16.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2011 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F16Handler(BaseHandler):
24 version = F16
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f7.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f7.py
new file mode 100644
index 0000000000..5e856ea983
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f7.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F7Handler(BaseHandler):
24 version = F7
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f8.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f8.py
new file mode 100644
index 0000000000..1a978810f4
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f8.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F8Handler(BaseHandler):
24 version = F8
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/f9.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/f9.py
new file mode 100644
index 0000000000..116f1b57c9
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/f9.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class F9Handler(BaseHandler):
24 version = F9
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/fc3.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc3.py
new file mode 100644
index 0000000000..a115dc2646
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc3.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class FC3Handler(BaseHandler):
24 version = FC3
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/fc4.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc4.py
new file mode 100644
index 0000000000..fd47b732ef
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc4.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class FC4Handler(BaseHandler):
24 version = FC4
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/fc5.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc5.py
new file mode 100644
index 0000000000..bcdc29d23a
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc5.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class FC5Handler(BaseHandler):
24 version = FC5
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/fc6.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc6.py
new file mode 100644
index 0000000000..c83a929f84
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/fc6.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class FC6Handler(BaseHandler):
24 version = FC6
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel3.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel3.py
new file mode 100644
index 0000000000..131763c2a8
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel3.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class RHEL3Handler(BaseHandler):
24 version = RHEL3
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel4.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel4.py
new file mode 100644
index 0000000000..3496c43ea5
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel4.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class RHEL4Handler(BaseHandler):
24 version = RHEL4
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel5.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel5.py
new file mode 100644
index 0000000000..abb7a8d36c
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel5.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class RHEL5Handler(BaseHandler):
24 version = RHEL5
diff --git a/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel6.py b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel6.py
new file mode 100644
index 0000000000..7202419780
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/handlers/rhel6.py
@@ -0,0 +1,24 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2010 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20from pykickstart.base import *
21from pykickstart.version import *
22
23class RHEL6Handler(BaseHandler):
24 version = RHEL6
diff --git a/scripts/lib/mic/3rdparty/pykickstart/ko.py b/scripts/lib/mic/3rdparty/pykickstart/ko.py
new file mode 100644
index 0000000000..1350d19c70
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/ko.py
@@ -0,0 +1,37 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2009 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20"""
21Base classes for internal pykickstart use.
22
23The module exports the following important classes:
24
25 KickstartObject - The base class for all classes in pykickstart
26"""
27
28class KickstartObject(object):
29 """The base class for all other classes in pykickstart."""
30 def __init__(self, *args, **kwargs):
31 """Create a new KickstartObject instance. All other classes in
32 pykickstart should be derived from this one. Instance attributes:
33 """
34 pass
35
36 def __str__(self):
37 return ""
diff --git a/scripts/lib/mic/3rdparty/pykickstart/options.py b/scripts/lib/mic/3rdparty/pykickstart/options.py
new file mode 100644
index 0000000000..341c5d7298
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/options.py
@@ -0,0 +1,204 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2005, 2006, 2007 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20"""
21Specialized option handling.
22
23This module exports two classes:
24
25 KSOptionParser - A specialized subclass of OptionParser to be used
26 in BaseHandler subclasses.
27
28 KSOption - A specialized subclass of Option.
29"""
30import warnings
31from copy import copy
32from optparse import *
33
34from constants import *
35from errors import *
36from version import *
37
38import gettext
39_ = lambda x: gettext.ldgettext("pykickstart", x)
40
41class KSOptionParser(OptionParser):
42 """A specialized subclass of optparse.OptionParser to handle extra option
43 attribute checking, work error reporting into the KickstartParseError
44 framework, and to turn off the default help.
45 """
46 def exit(self, status=0, msg=None):
47 pass
48
49 def error(self, msg):
50 if self.lineno != None:
51 raise KickstartParseError, formatErrorMsg(self.lineno, msg=msg)
52 else:
53 raise KickstartParseError, msg
54
55 def keys(self):
56 retval = []
57
58 for opt in self.option_list:
59 if opt not in retval:
60 retval.append(opt.dest)
61
62 return retval
63
64 def _init_parsing_state (self):
65 OptionParser._init_parsing_state(self)
66 self.option_seen = {}
67
68 def check_values (self, values, args):
69 def seen(self, option):
70 return self.option_seen.has_key(option)
71
72 def usedTooNew(self, option):
73 return option.introduced and option.introduced > self.version
74
75 def usedDeprecated(self, option):
76 return option.deprecated
77
78 def usedRemoved(self, option):
79 return option.removed and option.removed <= self.version
80
81 for option in filter(lambda o: isinstance(o, Option), self.option_list):
82 if option.required and not seen(self, option):
83 raise KickstartValueError, formatErrorMsg(self.lineno, _("Option %s is required") % option)
84 elif seen(self, option) and usedTooNew(self, option):
85 mapping = {"option": option, "intro": versionToString(option.introduced),
86 "version": versionToString(self.version)}
87 self.error(_("The %(option)s option was introduced in version %(intro)s, but you are using kickstart syntax version %(version)s.") % mapping)
88 elif seen(self, option) and usedRemoved(self, option):
89 mapping = {"option": option, "removed": versionToString(option.removed),
90 "version": versionToString(self.version)}
91
92 if option.removed == self.version:
93 self.error(_("The %(option)s option is no longer supported.") % mapping)
94 else:
95 self.error(_("The %(option)s option was removed in version %(removed)s, but you are using kickstart syntax version %(version)s.") % mapping)
96 elif seen(self, option) and usedDeprecated(self, option):
97 mapping = {"lineno": self.lineno, "option": option}
98 warnings.warn(_("Ignoring deprecated option on line %(lineno)s: The %(option)s option has been deprecated and no longer has any effect. It may be removed from future releases, which will result in a fatal error from kickstart. Please modify your kickstart file to remove this option.") % mapping, DeprecationWarning)
99
100 return (values, args)
101
102 def parse_args(self, *args, **kwargs):
103 if kwargs.has_key("lineno"):
104 self.lineno = kwargs.pop("lineno")
105
106 return OptionParser.parse_args(self, **kwargs)
107
108 def __init__(self, mapping=None, version=None):
109 """Create a new KSOptionParser instance. Each KickstartCommand
110 subclass should create one instance of KSOptionParser, providing
111 at least the lineno attribute. mapping and version are not required.
112 Instance attributes:
113
114 mapping -- A mapping from option strings to different values.
115 version -- The version of the kickstart syntax we are checking
116 against.
117 """
118 OptionParser.__init__(self, option_class=KSOption,
119 add_help_option=False,
120 conflict_handler="resolve")
121 if mapping is None:
122 self.map = {}
123 else:
124 self.map = mapping
125
126 self.lineno = None
127 self.option_seen = {}
128 self.version = version
129
130def _check_ksboolean(option, opt, value):
131 if value.lower() in ("on", "yes", "true", "1"):
132 return True
133 elif value.lower() in ("off", "no", "false", "0"):
134 return False
135 else:
136 mapping = {"opt": opt, "value": value}
137 raise OptionValueError(_("Option %(opt)s: invalid boolean value: %(value)r") % mapping)
138
139def _check_string(option, opt, value):
140 if len(value) > 2 and value.startswith("--"):
141 mapping = {"opt": opt, "value": value}
142 raise OptionValueError(_("Option %(opt)s: invalid string value: %(value)r") % mapping)
143 else:
144 return value
145
146# Creates a new Option class that supports several new attributes:
147# - required: any option with this attribute must be supplied or an exception
148# is thrown
149# - introduced: the kickstart syntax version that this option first appeared
150# in - an exception will be raised if the option is used and
151# the specified syntax version is less than the value of this
152# attribute
153# - deprecated: the kickstart syntax version that this option was deprecated
154# in - a DeprecationWarning will be thrown if the option is
155# used and the specified syntax version is greater than the
156# value of this attribute
157# - removed: the kickstart syntax version that this option was removed in - an
158# exception will be raised if the option is used and the specified
159# syntax version is greated than the value of this attribute
160# Also creates a new type:
161# - ksboolean: support various kinds of boolean values on an option
162# And two new actions:
163# - map : allows you to define an opt -> val mapping such that dest gets val
164# when opt is seen
165# - map_extend: allows you to define an opt -> [val1, ... valn] mapping such
166# that dest gets a list of vals built up when opt is seen
167class KSOption (Option):
168 ATTRS = Option.ATTRS + ['introduced', 'deprecated', 'removed', 'required']
169 ACTIONS = Option.ACTIONS + ("map", "map_extend",)
170 STORE_ACTIONS = Option.STORE_ACTIONS + ("map", "map_extend",)
171
172 TYPES = Option.TYPES + ("ksboolean", "string")
173 TYPE_CHECKER = copy(Option.TYPE_CHECKER)
174 TYPE_CHECKER["ksboolean"] = _check_ksboolean
175 TYPE_CHECKER["string"] = _check_string
176
177 def _check_required(self):
178 if self.required and not self.takes_value():
179 raise OptionError(_("Required flag set for option that doesn't take a value"), self)
180
181 # Make sure _check_required() is called from the constructor!
182 CHECK_METHODS = Option.CHECK_METHODS + [_check_required]
183
184 def process (self, opt, value, values, parser):
185 Option.process(self, opt, value, values, parser)
186 parser.option_seen[self] = 1
187
188 # Override default take_action method to handle our custom actions.
189 def take_action(self, action, dest, opt, value, values, parser):
190 if action == "map":
191 values.ensure_value(dest, parser.map[opt.lstrip('-')])
192 elif action == "map_extend":
193 values.ensure_value(dest, []).extend(parser.map[opt.lstrip('-')])
194 else:
195 Option.take_action(self, action, dest, opt, value, values, parser)
196
197 def takes_value(self):
198 # Deprecated options don't take a value.
199 return Option.takes_value(self) and not self.deprecated
200
201 def __init__(self, *args, **kwargs):
202 self.deprecated = False
203 self.required = False
204 Option.__init__(self, *args, **kwargs)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/parser.py b/scripts/lib/mic/3rdparty/pykickstart/parser.py
new file mode 100644
index 0000000000..840a448673
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/parser.py
@@ -0,0 +1,702 @@
1#
2# parser.py: Kickstart file parser.
3#
4# Chris Lumens <clumens@redhat.com>
5#
6# Copyright 2005, 2006, 2007, 2008, 2011 Red Hat, Inc.
7#
8# This copyrighted material is made available to anyone wishing to use, modify,
9# copy, or redistribute it subject to the terms and conditions of the GNU
10# General Public License v.2. This program is distributed in the hope that it
11# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
12# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13# See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program; if not, write to the Free Software Foundation, Inc., 51
17# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
18# trademarks that are incorporated in the source code or documentation are not
19# subject to the GNU General Public License and may only be used or replicated
20# with the express permission of Red Hat, Inc.
21#
22"""
23Main kickstart file processing module.
24
25This module exports several important classes:
26
27 Script - Representation of a single %pre, %post, or %traceback script.
28
29 Packages - Representation of the %packages section.
30
31 KickstartParser - The kickstart file parser state machine.
32"""
33
34from collections import Iterator
35import os
36import shlex
37import sys
38import tempfile
39from copy import copy
40from optparse import *
41from urlgrabber import urlread
42import urlgrabber.grabber as grabber
43
44import constants
45from errors import KickstartError, KickstartParseError, KickstartValueError, formatErrorMsg
46from ko import KickstartObject
47from sections import *
48import version
49
50import gettext
51_ = lambda x: gettext.ldgettext("pykickstart", x)
52
53STATE_END = "end"
54STATE_COMMANDS = "commands"
55
56ver = version.DEVEL
57
58def _preprocessStateMachine (lineIter):
59 l = None
60 lineno = 0
61
62 # Now open an output kickstart file that we are going to write to one
63 # line at a time.
64 (outF, outName) = tempfile.mkstemp("-ks.cfg", "", "/tmp")
65
66 while True:
67 try:
68 l = lineIter.next()
69 except StopIteration:
70 break
71
72 # At the end of the file?
73 if l == "":
74 break
75
76 lineno += 1
77 url = None
78
79 ll = l.strip()
80 if not ll.startswith("%ksappend"):
81 os.write(outF, l)
82 continue
83
84 # Try to pull down the remote file.
85 try:
86 ksurl = ll.split(' ')[1]
87 except:
88 raise KickstartParseError, formatErrorMsg(lineno, msg=_("Illegal url for %%ksappend: %s") % ll)
89
90 try:
91 url = grabber.urlopen(ksurl)
92 except grabber.URLGrabError, e:
93 raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file: %s") % e.strerror)
94 else:
95 # Sanity check result. Sometimes FTP doesn't catch a file
96 # is missing.
97 try:
98 if url.size < 1:
99 raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file"))
100 except:
101 raise KickstartError, formatErrorMsg(lineno, msg=_("Unable to open %%ksappend file"))
102
103 # If that worked, write the remote file to the output kickstart
104 # file in one burst. Then close everything up to get ready to
105 # read ahead in the input file. This allows multiple %ksappend
106 # lines to exist.
107 if url is not None:
108 os.write(outF, url.read())
109 url.close()
110
111 # All done - close the temp file and return its location.
112 os.close(outF)
113 return outName
114
115def preprocessFromString (s):
116 """Preprocess the kickstart file, provided as the string str. This
117 method is currently only useful for handling %ksappend lines,
118 which need to be fetched before the real kickstart parser can be
119 run. Returns the location of the complete kickstart file.
120 """
121 i = iter(s.splitlines(True) + [""])
122 rc = _preprocessStateMachine (i.next)
123 return rc
124
125def preprocessKickstart (f):
126 """Preprocess the kickstart file, given by the filename file. This
127 method is currently only useful for handling %ksappend lines,
128 which need to be fetched before the real kickstart parser can be
129 run. Returns the location of the complete kickstart file.
130 """
131 try:
132 fh = urlopen(f)
133 except grabber.URLGrabError, e:
134 raise KickstartError, formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % e.strerror)
135
136 rc = _preprocessStateMachine (iter(fh.readlines()))
137 fh.close()
138 return rc
139
140class PutBackIterator(Iterator):
141 def __init__(self, iterable):
142 self._iterable = iter(iterable)
143 self._buf = None
144
145 def __iter__(self):
146 return self
147
148 def put(self, s):
149 self._buf = s
150
151 def next(self):
152 if self._buf:
153 retval = self._buf
154 self._buf = None
155 return retval
156 else:
157 return self._iterable.next()
158
159###
160### SCRIPT HANDLING
161###
162class Script(KickstartObject):
163 """A class representing a single kickstart script. If functionality beyond
164 just a data representation is needed (for example, a run method in
165 anaconda), Script may be subclassed. Although a run method is not
166 provided, most of the attributes of Script have to do with running the
167 script. Instances of Script are held in a list by the Version object.
168 """
169 def __init__(self, script, *args , **kwargs):
170 """Create a new Script instance. Instance attributes:
171
172 errorOnFail -- If execution of the script fails, should anaconda
173 stop, display an error, and then reboot without
174 running any other scripts?
175 inChroot -- Does the script execute in anaconda's chroot
176 environment or not?
177 interp -- The program that should be used to interpret this
178 script.
179 lineno -- The line number this script starts on.
180 logfile -- Where all messages from the script should be logged.
181 script -- A string containing all the lines of the script.
182 type -- The type of the script, which can be KS_SCRIPT_* from
183 pykickstart.constants.
184 """
185 KickstartObject.__init__(self, *args, **kwargs)
186 self.script = "".join(script)
187
188 self.interp = kwargs.get("interp", "/bin/sh")
189 self.inChroot = kwargs.get("inChroot", False)
190 self.lineno = kwargs.get("lineno", None)
191 self.logfile = kwargs.get("logfile", None)
192 self.errorOnFail = kwargs.get("errorOnFail", False)
193 self.type = kwargs.get("type", constants.KS_SCRIPT_PRE)
194
195 def __str__(self):
196 """Return a string formatted for output to a kickstart file."""
197 retval = ""
198
199 if self.type == constants.KS_SCRIPT_PRE:
200 retval += '\n%pre'
201 elif self.type == constants.KS_SCRIPT_POST:
202 retval += '\n%post'
203 elif self.type == constants.KS_SCRIPT_TRACEBACK:
204 retval += '\n%traceback'
205
206 if self.interp != "/bin/sh" and self.interp != "":
207 retval += " --interpreter=%s" % self.interp
208 if self.type == constants.KS_SCRIPT_POST and not self.inChroot:
209 retval += " --nochroot"
210 if self.logfile != None:
211 retval += " --logfile %s" % self.logfile
212 if self.errorOnFail:
213 retval += " --erroronfail"
214
215 if self.script.endswith("\n"):
216 if ver >= version.F8:
217 return retval + "\n%s%%end\n" % self.script
218 else:
219 return retval + "\n%s\n" % self.script
220 else:
221 if ver >= version.F8:
222 return retval + "\n%s\n%%end\n" % self.script
223 else:
224 return retval + "\n%s\n" % self.script
225
226
227##
228## PACKAGE HANDLING
229##
230class Group:
231 """A class representing a single group in the %packages section."""
232 def __init__(self, name="", include=constants.GROUP_DEFAULT):
233 """Create a new Group instance. Instance attributes:
234
235 name -- The group's identifier
236 include -- The level of how much of the group should be included.
237 Values can be GROUP_* from pykickstart.constants.
238 """
239 self.name = name
240 self.include = include
241
242 def __str__(self):
243 """Return a string formatted for output to a kickstart file."""
244 if self.include == constants.GROUP_REQUIRED:
245 return "@%s --nodefaults" % self.name
246 elif self.include == constants.GROUP_ALL:
247 return "@%s --optional" % self.name
248 else:
249 return "@%s" % self.name
250
251 def __cmp__(self, other):
252 if self.name < other.name:
253 return -1
254 elif self.name > other.name:
255 return 1
256 return 0
257
258class Packages(KickstartObject):
259 """A class representing the %packages section of the kickstart file."""
260 def __init__(self, *args, **kwargs):
261 """Create a new Packages instance. Instance attributes:
262
263 addBase -- Should the Base group be installed even if it is
264 not specified?
265 default -- Should the default package set be selected?
266 excludedList -- A list of all the packages marked for exclusion in
267 the %packages section, without the leading minus
268 symbol.
269 excludeDocs -- Should documentation in each package be excluded?
270 groupList -- A list of Group objects representing all the groups
271 specified in the %packages section. Names will be
272 stripped of the leading @ symbol.
273 excludedGroupList -- A list of Group objects representing all the
274 groups specified for removal in the %packages
275 section. Names will be stripped of the leading
276 -@ symbols.
277 handleMissing -- If unknown packages are specified in the %packages
278 section, should it be ignored or not? Values can
279 be KS_MISSING_* from pykickstart.constants.
280 packageList -- A list of all the packages specified in the
281 %packages section.
282 instLangs -- A list of languages to install.
283 """
284 KickstartObject.__init__(self, *args, **kwargs)
285
286 self.addBase = True
287 self.default = False
288 self.excludedList = []
289 self.excludedGroupList = []
290 self.excludeDocs = False
291 self.groupList = []
292 self.handleMissing = constants.KS_MISSING_PROMPT
293 self.packageList = []
294 self.instLangs = None
295
296 def __str__(self):
297 """Return a string formatted for output to a kickstart file."""
298 pkgs = ""
299
300 if not self.default:
301 grps = self.groupList
302 grps.sort()
303 for grp in grps:
304 pkgs += "%s\n" % grp.__str__()
305
306 p = self.packageList
307 p.sort()
308 for pkg in p:
309 pkgs += "%s\n" % pkg
310
311 grps = self.excludedGroupList
312 grps.sort()
313 for grp in grps:
314 pkgs += "-%s\n" % grp.__str__()
315
316 p = self.excludedList
317 p.sort()
318 for pkg in p:
319 pkgs += "-%s\n" % pkg
320
321 if pkgs == "":
322 return ""
323
324 retval = "\n%packages"
325
326 if self.default:
327 retval += " --default"
328 if self.excludeDocs:
329 retval += " --excludedocs"
330 if not self.addBase:
331 retval += " --nobase"
332 if self.handleMissing == constants.KS_MISSING_IGNORE:
333 retval += " --ignoremissing"
334 if self.instLangs:
335 retval += " --instLangs=%s" % self.instLangs
336
337 if ver >= version.F8:
338 return retval + "\n" + pkgs + "\n%end\n"
339 else:
340 return retval + "\n" + pkgs + "\n"
341
342 def _processGroup (self, line):
343 op = OptionParser()
344 op.add_option("--nodefaults", action="store_true", default=False)
345 op.add_option("--optional", action="store_true", default=False)
346
347 (opts, extra) = op.parse_args(args=line.split())
348
349 if opts.nodefaults and opts.optional:
350 raise KickstartValueError, _("Group cannot specify both --nodefaults and --optional")
351
352 # If the group name has spaces in it, we have to put it back together
353 # now.
354 grp = " ".join(extra)
355
356 if opts.nodefaults:
357 self.groupList.append(Group(name=grp, include=constants.GROUP_REQUIRED))
358 elif opts.optional:
359 self.groupList.append(Group(name=grp, include=constants.GROUP_ALL))
360 else:
361 self.groupList.append(Group(name=grp, include=constants.GROUP_DEFAULT))
362
363 def add (self, pkgList):
364 """Given a list of lines from the input file, strip off any leading
365 symbols and add the result to the appropriate list.
366 """
367 existingExcludedSet = set(self.excludedList)
368 existingPackageSet = set(self.packageList)
369 newExcludedSet = set()
370 newPackageSet = set()
371
372 excludedGroupList = []
373
374 for pkg in pkgList:
375 stripped = pkg.strip()
376
377 if stripped[0] == "@":
378 self._processGroup(stripped[1:])
379 elif stripped[0] == "-":
380 if stripped[1] == "@":
381 excludedGroupList.append(Group(name=stripped[2:]))
382 else:
383 newExcludedSet.add(stripped[1:])
384 else:
385 newPackageSet.add(stripped)
386
387 # Groups have to be excluded in two different ways (note: can't use
388 # sets here because we have to store objects):
389 excludedGroupNames = map(lambda g: g.name, excludedGroupList)
390
391 # First, an excluded group may be cancelling out a previously given
392 # one. This is often the case when using %include. So there we should
393 # just remove the group from the list.
394 self.groupList = filter(lambda g: g.name not in excludedGroupNames, self.groupList)
395
396 # Second, the package list could have included globs which are not
397 # processed by pykickstart. In that case we need to preserve a list of
398 # excluded groups so whatever tool doing package/group installation can
399 # take appropriate action.
400 self.excludedGroupList.extend(excludedGroupList)
401
402 existingPackageSet = (existingPackageSet - newExcludedSet) | newPackageSet
403 existingExcludedSet = (existingExcludedSet - existingPackageSet) | newExcludedSet
404
405 self.packageList = list(existingPackageSet)
406 self.excludedList = list(existingExcludedSet)
407
408
409###
410### PARSER
411###
412class KickstartParser:
413 """The kickstart file parser class as represented by a basic state
414 machine. To create a specialized parser, make a subclass and override
415 any of the methods you care about. Methods that don't need to do
416 anything may just pass. However, _stateMachine should never be
417 overridden.
418 """
419 def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
420 missingIncludeIsFatal=True):
421 """Create a new KickstartParser instance. Instance attributes:
422
423 errorsAreFatal -- Should errors cause processing to halt, or
424 just print a message to the screen? This
425 is most useful for writing syntax checkers
426 that may want to continue after an error is
427 encountered.
428 followIncludes -- If %include is seen, should the included
429 file be checked as well or skipped?
430 handler -- An instance of a BaseHandler subclass. If
431 None, the input file will still be parsed
432 but no data will be saved and no commands
433 will be executed.
434 missingIncludeIsFatal -- Should missing include files be fatal, even
435 if errorsAreFatal is False?
436 """
437 self.errorsAreFatal = errorsAreFatal
438 self.followIncludes = followIncludes
439 self.handler = handler
440 self.currentdir = {}
441 self.missingIncludeIsFatal = missingIncludeIsFatal
442
443 self._state = STATE_COMMANDS
444 self._includeDepth = 0
445 self._line = ""
446
447 self.version = self.handler.version
448
449 global ver
450 ver = self.version
451
452 self._sections = {}
453 self.setupSections()
454
455 def _reset(self):
456 """Reset the internal variables of the state machine for a new kickstart file."""
457 self._state = STATE_COMMANDS
458 self._includeDepth = 0
459
460 def getSection(self, s):
461 """Return a reference to the requested section (s must start with '%'s),
462 or raise KeyError if not found.
463 """
464 return self._sections[s]
465
466 def handleCommand (self, lineno, args):
467 """Given the list of command and arguments, call the Version's
468 dispatcher method to handle the command. Returns the command or
469 data object returned by the dispatcher. This method may be
470 overridden in a subclass if necessary.
471 """
472 if self.handler:
473 self.handler.currentCmd = args[0]
474 self.handler.currentLine = self._line
475 retval = self.handler.dispatcher(args, lineno)
476
477 return retval
478
479 def registerSection(self, obj):
480 """Given an instance of a Section subclass, register the new section
481 with the parser. Calling this method means the parser will
482 recognize your new section and dispatch into the given object to
483 handle it.
484 """
485 if not obj.sectionOpen:
486 raise TypeError, "no sectionOpen given for section %s" % obj
487
488 if not obj.sectionOpen.startswith("%"):
489 raise TypeError, "section %s tag does not start with a %%" % obj.sectionOpen
490
491 self._sections[obj.sectionOpen] = obj
492
493 def _finalize(self, obj):
494 """Called at the close of a kickstart section to take any required
495 actions. Internally, this is used to add scripts once we have the
496 whole body read.
497 """
498 obj.finalize()
499 self._state = STATE_COMMANDS
500
501 def _handleSpecialComments(self, line):
502 """Kickstart recognizes a couple special comments."""
503 if self._state != STATE_COMMANDS:
504 return
505
506 # Save the platform for s-c-kickstart.
507 if line[:10] == "#platform=":
508 self.handler.platform = self._line[11:]
509
510 def _readSection(self, lineIter, lineno):
511 obj = self._sections[self._state]
512
513 while True:
514 try:
515 line = lineIter.next()
516 if line == "":
517 # This section ends at the end of the file.
518 if self.version >= version.F8:
519 raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
520
521 self._finalize(obj)
522 except StopIteration:
523 break
524
525 lineno += 1
526
527 # Throw away blank lines and comments, unless the section wants all
528 # lines.
529 if self._isBlankOrComment(line) and not obj.allLines:
530 continue
531
532 if line.startswith("%"):
533 args = shlex.split(line)
534
535 if args and args[0] == "%end":
536 # This is a properly terminated section.
537 self._finalize(obj)
538 break
539 elif args and args[0] == "%ksappend":
540 continue
541 elif args and (self._validState(args[0]) or args[0] in ["%include", "%ksappend"]):
542 # This is an unterminated section.
543 if self.version >= version.F8:
544 raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
545
546 # Finish up. We do not process the header here because
547 # kicking back out to STATE_COMMANDS will ensure that happens.
548 lineIter.put(line)
549 lineno -= 1
550 self._finalize(obj)
551 break
552 else:
553 # This is just a line within a section. Pass it off to whatever
554 # section handles it.
555 obj.handleLine(line)
556
557 return lineno
558
559 def _validState(self, st):
560 """Is the given section tag one that has been registered with the parser?"""
561 return st in self._sections.keys()
562
563 def _tryFunc(self, fn):
564 """Call the provided function (which doesn't take any arguments) and
565 do the appropriate error handling. If errorsAreFatal is False, this
566 function will just print the exception and keep going.
567 """
568 try:
569 fn()
570 except Exception, msg:
571 if self.errorsAreFatal:
572 raise
573 else:
574 print msg
575
576 def _isBlankOrComment(self, line):
577 return line.isspace() or line == "" or line.lstrip()[0] == '#'
578
579 def _stateMachine(self, lineIter):
580 # For error reporting.
581 lineno = 0
582
583 while True:
584 # Get the next line out of the file, quitting if this is the last line.
585 try:
586 self._line = lineIter.next()
587 if self._line == "":
588 break
589 except StopIteration:
590 break
591
592 lineno += 1
593
594 # Eliminate blank lines, whitespace-only lines, and comments.
595 if self._isBlankOrComment(self._line):
596 self._handleSpecialComments(self._line)
597 continue
598
599 # Remove any end-of-line comments.
600 sanitized = self._line.split("#")[0]
601
602 # Then split the line.
603 args = shlex.split(sanitized.rstrip())
604
605 if args[0] == "%include":
606 # This case comes up primarily in ksvalidator.
607 if not self.followIncludes:
608 continue
609
610 if len(args) == 1 or not args[1]:
611 raise KickstartParseError, formatErrorMsg(lineno)
612
613 self._includeDepth += 1
614
615 try:
616 self.readKickstart(args[1], reset=False)
617 except KickstartError:
618 # Handle the include file being provided over the
619 # network in a %pre script. This case comes up in the
620 # early parsing in anaconda.
621 if self.missingIncludeIsFatal:
622 raise
623
624 self._includeDepth -= 1
625 continue
626
627 # Now on to the main event.
628 if self._state == STATE_COMMANDS:
629 if args[0] == "%ksappend":
630 # This is handled by the preprocess* functions, so continue.
631 continue
632 elif args[0][0] == '%':
633 # This is the beginning of a new section. Handle its header
634 # here.
635 newSection = args[0]
636 if not self._validState(newSection):
637 raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown kickstart section: %s" % newSection))
638
639 self._state = newSection
640 obj = self._sections[self._state]
641 self._tryFunc(lambda: obj.handleHeader(lineno, args))
642
643 # This will handle all section processing, kicking us back
644 # out to STATE_COMMANDS at the end with the current line
645 # being the next section header, etc.
646 lineno = self._readSection(lineIter, lineno)
647 else:
648 # This is a command in the command section. Dispatch to it.
649 self._tryFunc(lambda: self.handleCommand(lineno, args))
650 elif self._state == STATE_END:
651 break
652
653 def readKickstartFromString (self, s, reset=True):
654 """Process a kickstart file, provided as the string str."""
655 if reset:
656 self._reset()
657
658 # Add a "" to the end of the list so the string reader acts like the
659 # file reader and we only get StopIteration when we're after the final
660 # line of input.
661 i = PutBackIterator(s.splitlines(True) + [""])
662 self._stateMachine (i)
663
664 def readKickstart(self, f, reset=True):
665 """Process a kickstart file, given by the filename f."""
666 if reset:
667 self._reset()
668
669 # an %include might not specify a full path. if we don't try to figure
670 # out what the path should have been, then we're unable to find it
671 # requiring full path specification, though, sucks. so let's make
672 # the reading "smart" by keeping track of what the path is at each
673 # include depth.
674 if not os.path.exists(f):
675 if self.currentdir.has_key(self._includeDepth - 1):
676 if os.path.exists(os.path.join(self.currentdir[self._includeDepth - 1], f)):
677 f = os.path.join(self.currentdir[self._includeDepth - 1], f)
678
679 cd = os.path.dirname(f)
680 if not cd.startswith("/"):
681 cd = os.path.abspath(cd)
682 self.currentdir[self._includeDepth] = cd
683
684 try:
685 s = urlread(f)
686 except grabber.URLGrabError, e:
687 raise KickstartError, formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % e.strerror)
688
689 self.readKickstartFromString(s, reset=False)
690
691 def setupSections(self):
692 """Install the sections all kickstart files support. You may override
693 this method in a subclass, but should avoid doing so unless you know
694 what you're doing.
695 """
696 self._sections = {}
697
698 # Install the sections all kickstart files support.
699 self.registerSection(PreScriptSection(self.handler, dataObj=Script))
700 self.registerSection(PostScriptSection(self.handler, dataObj=Script))
701 self.registerSection(TracebackScriptSection(self.handler, dataObj=Script))
702 self.registerSection(PackageSection(self.handler))
diff --git a/scripts/lib/mic/3rdparty/pykickstart/sections.py b/scripts/lib/mic/3rdparty/pykickstart/sections.py
new file mode 100644
index 0000000000..44df856b8d
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/sections.py
@@ -0,0 +1,244 @@
1#
2# sections.py: Kickstart file sections.
3#
4# Chris Lumens <clumens@redhat.com>
5#
6# Copyright 2011 Red Hat, Inc.
7#
8# This copyrighted material is made available to anyone wishing to use, modify,
9# copy, or redistribute it subject to the terms and conditions of the GNU
10# General Public License v.2. This program is distributed in the hope that it
11# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
12# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13# See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program; if not, write to the Free Software Foundation, Inc., 51
17# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
18# trademarks that are incorporated in the source code or documentation are not
19# subject to the GNU General Public License and may only be used or replicated
20# with the express permission of Red Hat, Inc.
21#
22"""
23This module exports the classes that define a section of a kickstart file. A
24section is a chunk of the file starting with a %tag and ending with a %end.
25Examples of sections include %packages, %pre, and %post.
26
27You may use this module to define your own custom sections which will be
28treated just the same as a predefined one by the kickstart parser. All that
29is necessary is to create a new subclass of Section and call
30parser.registerSection with an instance of your new class.
31"""
32from constants import *
33from options import KSOptionParser
34from version import *
35
36class Section(object):
37 """The base class for defining kickstart sections. You are free to
38 subclass this as appropriate.
39
40 Class attributes:
41
42 allLines -- Does this section require the parser to call handleLine
43 for every line in the section, even blanks and comments?
44 sectionOpen -- The string that denotes the start of this section. You
45 must start your tag with a percent sign.
46 timesSeen -- This attribute is for informational purposes only. It is
47 incremented every time handleHeader is called to keep
48 track of the number of times a section of this type is
49 seen.
50 """
51 allLines = False
52 sectionOpen = ""
53 timesSeen = 0
54
55 def __init__(self, handler, **kwargs):
56 """Create a new Script instance. At the least, you must pass in an
57 instance of a baseHandler subclass.
58
59 Valid kwargs:
60
61 dataObj --
62 """
63 self.handler = handler
64
65 self.version = self.handler.version
66
67 self.dataObj = kwargs.get("dataObj", None)
68
69 def finalize(self):
70 """This method is called when the %end tag for a section is seen. It
71 is not required to be provided.
72 """
73 pass
74
75 def handleLine(self, line):
76 """This method is called for every line of a section. Take whatever
77 action is appropriate. While this method is not required to be
78 provided, not providing it does not make a whole lot of sense.
79
80 Arguments:
81
82 line -- The complete line, with any trailing newline.
83 """
84 pass
85
86 def handleHeader(self, lineno, args):
87 """This method is called when the opening tag for a section is seen.
88 Not all sections will need this method, though all provided with
89 kickstart include one.
90
91 Arguments:
92
93 args -- A list of all strings passed as arguments to the section
94 opening tag.
95 """
96 self.timesSeen += 1
97
98class NullSection(Section):
99 """This defines a section that pykickstart will recognize but do nothing
100 with. If the parser runs across a %section that has no object registered,
101 it will raise an error. Sometimes, you may want to simply ignore those
102 sections instead. This class is useful for that purpose.
103 """
104 def __init__(self, *args, **kwargs):
105 """Create a new NullSection instance. You must pass a sectionOpen
106 parameter (including a leading '%') for the section you wish to
107 ignore.
108 """
109 Section.__init__(self, *args, **kwargs)
110 self.sectionOpen = kwargs.get("sectionOpen")
111
112class ScriptSection(Section):
113 allLines = True
114
115 def __init__(self, *args, **kwargs):
116 Section.__init__(self, *args, **kwargs)
117 self._script = {}
118 self._resetScript()
119
120 def _getParser(self):
121 op = KSOptionParser(self.version)
122 op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
123 default=False)
124 op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
125 op.add_option("--log", "--logfile", dest="log")
126 return op
127
128 def _resetScript(self):
129 self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
130 "lineno": None, "chroot": False, "body": []}
131
132 def handleLine(self, line):
133 self._script["body"].append(line)
134
135 def finalize(self):
136 if " ".join(self._script["body"]).strip() == "":
137 return
138
139 kwargs = {"interp": self._script["interp"],
140 "inChroot": self._script["chroot"],
141 "lineno": self._script["lineno"],
142 "logfile": self._script["log"],
143 "errorOnFail": self._script["errorOnFail"],
144 "type": self._script["type"]}
145
146 s = self.dataObj (self._script["body"], **kwargs)
147 self._resetScript()
148
149 if self.handler:
150 self.handler.scripts.append(s)
151
152 def handleHeader(self, lineno, args):
153 """Process the arguments to a %pre/%post/%traceback header for later
154 setting on a Script instance once the end of the script is found.
155 This method may be overridden in a subclass if necessary.
156 """
157 Section.handleHeader(self, lineno, args)
158 op = self._getParser()
159
160 (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
161
162 self._script["interp"] = opts.interpreter
163 self._script["lineno"] = lineno
164 self._script["log"] = opts.log
165 self._script["errorOnFail"] = opts.errorOnFail
166 if hasattr(opts, "nochroot"):
167 self._script["chroot"] = not opts.nochroot
168
169class PreScriptSection(ScriptSection):
170 sectionOpen = "%pre"
171
172 def _resetScript(self):
173 ScriptSection._resetScript(self)
174 self._script["type"] = KS_SCRIPT_PRE
175
176class PostScriptSection(ScriptSection):
177 sectionOpen = "%post"
178
179 def _getParser(self):
180 op = ScriptSection._getParser(self)
181 op.add_option("--nochroot", dest="nochroot", action="store_true",
182 default=False)
183 return op
184
185 def _resetScript(self):
186 ScriptSection._resetScript(self)
187 self._script["chroot"] = True
188 self._script["type"] = KS_SCRIPT_POST
189
190class TracebackScriptSection(ScriptSection):
191 sectionOpen = "%traceback"
192
193 def _resetScript(self):
194 ScriptSection._resetScript(self)
195 self._script["type"] = KS_SCRIPT_TRACEBACK
196
197class PackageSection(Section):
198 sectionOpen = "%packages"
199
200 def handleLine(self, line):
201 if not self.handler:
202 return
203
204 (h, s, t) = line.partition('#')
205 line = h.rstrip()
206
207 self.handler.packages.add([line])
208
209 def handleHeader(self, lineno, args):
210 """Process the arguments to the %packages header and set attributes
211 on the Version's Packages instance appropriate. This method may be
212 overridden in a subclass if necessary.
213 """
214 Section.handleHeader(self, lineno, args)
215 op = KSOptionParser(version=self.version)
216 op.add_option("--excludedocs", dest="excludedocs", action="store_true",
217 default=False)
218 op.add_option("--ignoremissing", dest="ignoremissing",
219 action="store_true", default=False)
220 op.add_option("--nobase", dest="nobase", action="store_true",
221 default=False)
222 op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
223 deprecated=FC4, removed=F9)
224 op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
225 deprecated=FC4, removed=F9)
226 op.add_option("--default", dest="defaultPackages", action="store_true",
227 default=False, introduced=F7)
228 op.add_option("--instLangs", dest="instLangs", type="string",
229 default="", introduced=F9)
230
231 (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
232
233 self.handler.packages.excludeDocs = opts.excludedocs
234 self.handler.packages.addBase = not opts.nobase
235 if opts.ignoremissing:
236 self.handler.packages.handleMissing = KS_MISSING_IGNORE
237 else:
238 self.handler.packages.handleMissing = KS_MISSING_PROMPT
239
240 if opts.defaultPackages:
241 self.handler.packages.default = True
242
243 if opts.instLangs:
244 self.handler.packages.instLangs = opts.instLangs
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/__init__.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/__init__.py
new file mode 100644
index 0000000000..7bcd9d5541
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/__init__.py
@@ -0,0 +1,53 @@
1# This program is free software; you can redistribute it and/or modify
2# it under the terms of the GNU General Public License as published by
3# the Free Software Foundation; either version 2 of the License, or
4# (at your option) any later version.
5#
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU Library General Public License for more details.
10#
11# You should have received a copy of the GNU General Public License
12# along with this program; if not, write to the Free Software
13# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
15# Copyright 2002-2006 Michael D. Stenner, Ryan Tomayko
16
17# $Id: __init__.py,v 1.20 2006/09/22 00:58:55 mstenner Exp $
18
19"""A high-level cross-protocol url-grabber.
20
21Using urlgrabber, data can be fetched in three basic ways:
22
23 urlgrab(url) copy the file to the local filesystem
24 urlopen(url) open the remote file and return a file object
25 (like urllib2.urlopen)
26 urlread(url) return the contents of the file as a string
27
28When using these functions (or methods), urlgrabber supports the
29following features:
30
31 * identical behavior for http://, ftp://, and file:// urls
32 * http keepalive - faster downloads of many files by using
33 only a single connection
34 * byte ranges - fetch only a portion of the file
35 * reget - for a urlgrab, resume a partial download
36 * progress meters - the ability to report download progress
37 automatically, even when using urlopen!
38 * throttling - restrict bandwidth usage
39 * retries - automatically retry a download if it fails. The
40 number of retries and failure types are configurable.
41 * authenticated server access for http and ftp
42 * proxy support - support for authenticated http and ftp proxies
43 * mirror groups - treat a list of mirrors as a single source,
44 automatically switching mirrors if there is a failure.
45"""
46
47__version__ = '3.1.0'
48__date__ = '2006/09/21'
49__author__ = 'Michael D. Stenner <mstenner@linux.duke.edu>, ' \
50 'Ryan Tomayko <rtomayko@naeblis.cx>'
51__url__ = 'http://linux.duke.edu/projects/urlgrabber/'
52
53from grabber import urlgrab, urlopen, urlread
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/byterange.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/byterange.py
new file mode 100644
index 0000000000..001b4e32d6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/byterange.py
@@ -0,0 +1,463 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
19
20# $Id: byterange.py,v 1.12 2006/07/20 20:15:58 mstenner Exp $
21
22import os
23import stat
24import urllib
25import urllib2
26import rfc822
27
28DEBUG = None
29
30try:
31 from cStringIO import StringIO
32except ImportError, msg:
33 from StringIO import StringIO
34
35class RangeError(IOError):
36 """Error raised when an unsatisfiable range is requested."""
37 pass
38
39class HTTPRangeHandler(urllib2.BaseHandler):
40 """Handler that enables HTTP Range headers.
41
42 This was extremely simple. The Range header is a HTTP feature to
43 begin with so all this class does is tell urllib2 that the
44 "206 Partial Content" reponse from the HTTP server is what we
45 expected.
46
47 Example:
48 import urllib2
49 import byterange
50
51 range_handler = range.HTTPRangeHandler()
52 opener = urllib2.build_opener(range_handler)
53
54 # install it
55 urllib2.install_opener(opener)
56
57 # create Request and set Range header
58 req = urllib2.Request('http://www.python.org/')
59 req.header['Range'] = 'bytes=30-50'
60 f = urllib2.urlopen(req)
61 """
62
63 def http_error_206(self, req, fp, code, msg, hdrs):
64 # 206 Partial Content Response
65 r = urllib.addinfourl(fp, hdrs, req.get_full_url())
66 r.code = code
67 r.msg = msg
68 return r
69
70 def http_error_416(self, req, fp, code, msg, hdrs):
71 # HTTP's Range Not Satisfiable error
72 raise RangeError('Requested Range Not Satisfiable')
73
74class HTTPSRangeHandler(HTTPRangeHandler):
75 """ Range Header support for HTTPS. """
76
77 def https_error_206(self, req, fp, code, msg, hdrs):
78 return self.http_error_206(req, fp, code, msg, hdrs)
79
80 def https_error_416(self, req, fp, code, msg, hdrs):
81 self.https_error_416(req, fp, code, msg, hdrs)
82
83class RangeableFileObject:
84 """File object wrapper to enable raw range handling.
85 This was implemented primarilary for handling range
86 specifications for file:// urls. This object effectively makes
87 a file object look like it consists only of a range of bytes in
88 the stream.
89
90 Examples:
91 # expose 10 bytes, starting at byte position 20, from
92 # /etc/aliases.
93 >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30))
94 # seek seeks within the range (to position 23 in this case)
95 >>> fo.seek(3)
96 # tell tells where your at _within the range_ (position 3 in
97 # this case)
98 >>> fo.tell()
99 # read EOFs if an attempt is made to read past the last
100 # byte in the range. the following will return only 7 bytes.
101 >>> fo.read(30)
102 """
103
104 def __init__(self, fo, rangetup):
105 """Create a RangeableFileObject.
106 fo -- a file like object. only the read() method need be
107 supported but supporting an optimized seek() is
108 preferable.
109 rangetup -- a (firstbyte,lastbyte) tuple specifying the range
110 to work over.
111 The file object provided is assumed to be at byte offset 0.
112 """
113 self.fo = fo
114 (self.firstbyte, self.lastbyte) = range_tuple_normalize(rangetup)
115 self.realpos = 0
116 self._do_seek(self.firstbyte)
117
118 def __getattr__(self, name):
119 """This effectively allows us to wrap at the instance level.
120 Any attribute not found in _this_ object will be searched for
121 in self.fo. This includes methods."""
122 if hasattr(self.fo, name):
123 return getattr(self.fo, name)
124 raise AttributeError, name
125
126 def tell(self):
127 """Return the position within the range.
128 This is different from fo.seek in that position 0 is the
129 first byte position of the range tuple. For example, if
130 this object was created with a range tuple of (500,899),
131 tell() will return 0 when at byte position 500 of the file.
132 """
133 return (self.realpos - self.firstbyte)
134
135 def seek(self,offset,whence=0):
136 """Seek within the byte range.
137 Positioning is identical to that described under tell().
138 """
139 assert whence in (0, 1, 2)
140 if whence == 0: # absolute seek
141 realoffset = self.firstbyte + offset
142 elif whence == 1: # relative seek
143 realoffset = self.realpos + offset
144 elif whence == 2: # absolute from end of file
145 # XXX: are we raising the right Error here?
146 raise IOError('seek from end of file not supported.')
147
148 # do not allow seek past lastbyte in range
149 if self.lastbyte and (realoffset >= self.lastbyte):
150 realoffset = self.lastbyte
151
152 self._do_seek(realoffset - self.realpos)
153
154 def read(self, size=-1):
155 """Read within the range.
156 This method will limit the size read based on the range.
157 """
158 size = self._calc_read_size(size)
159 rslt = self.fo.read(size)
160 self.realpos += len(rslt)
161 return rslt
162
163 def readline(self, size=-1):
164 """Read lines within the range.
165 This method will limit the size read based on the range.
166 """
167 size = self._calc_read_size(size)
168 rslt = self.fo.readline(size)
169 self.realpos += len(rslt)
170 return rslt
171
172 def _calc_read_size(self, size):
173 """Handles calculating the amount of data to read based on
174 the range.
175 """
176 if self.lastbyte:
177 if size > -1:
178 if ((self.realpos + size) >= self.lastbyte):
179 size = (self.lastbyte - self.realpos)
180 else:
181 size = (self.lastbyte - self.realpos)
182 return size
183
184 def _do_seek(self,offset):
185 """Seek based on whether wrapped object supports seek().
186 offset is relative to the current position (self.realpos).
187 """
188 assert offset >= 0
189 if not hasattr(self.fo, 'seek'):
190 self._poor_mans_seek(offset)
191 else:
192 self.fo.seek(self.realpos + offset)
193 self.realpos+= offset
194
195 def _poor_mans_seek(self,offset):
196 """Seek by calling the wrapped file objects read() method.
197 This is used for file like objects that do not have native
198 seek support. The wrapped objects read() method is called
199 to manually seek to the desired position.
200 offset -- read this number of bytes from the wrapped
201 file object.
202 raise RangeError if we encounter EOF before reaching the
203 specified offset.
204 """
205 pos = 0
206 bufsize = 1024
207 while pos < offset:
208 if (pos + bufsize) > offset:
209 bufsize = offset - pos
210 buf = self.fo.read(bufsize)
211 if len(buf) != bufsize:
212 raise RangeError('Requested Range Not Satisfiable')
213 pos+= bufsize
214
215class FileRangeHandler(urllib2.FileHandler):
216 """FileHandler subclass that adds Range support.
217 This class handles Range headers exactly like an HTTP
218 server would.
219 """
220 def open_local_file(self, req):
221 import mimetypes
222 import mimetools
223 host = req.get_host()
224 file = req.get_selector()
225 localfile = urllib.url2pathname(file)
226 stats = os.stat(localfile)
227 size = stats[stat.ST_SIZE]
228 modified = rfc822.formatdate(stats[stat.ST_MTIME])
229 mtype = mimetypes.guess_type(file)[0]
230 if host:
231 host, port = urllib.splitport(host)
232 if port or socket.gethostbyname(host) not in self.get_names():
233 raise urllib2.URLError('file not on local host')
234 fo = open(localfile,'rb')
235 brange = req.headers.get('Range',None)
236 brange = range_header_to_tuple(brange)
237 assert brange != ()
238 if brange:
239 (fb,lb) = brange
240 if lb == '': lb = size
241 if fb < 0 or fb > size or lb > size:
242 raise RangeError('Requested Range Not Satisfiable')
243 size = (lb - fb)
244 fo = RangeableFileObject(fo, (fb,lb))
245 headers = mimetools.Message(StringIO(
246 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' %
247 (mtype or 'text/plain', size, modified)))
248 return urllib.addinfourl(fo, headers, 'file:'+file)
249
250
251# FTP Range Support
252# Unfortunately, a large amount of base FTP code had to be copied
253# from urllib and urllib2 in order to insert the FTP REST command.
254# Code modifications for range support have been commented as
255# follows:
256# -- range support modifications start/end here
257
258from urllib import splitport, splituser, splitpasswd, splitattr, \
259 unquote, addclosehook, addinfourl
260import ftplib
261import socket
262import sys
263import ftplib
264import mimetypes
265import mimetools
266
267class FTPRangeHandler(urllib2.FTPHandler):
268 def ftp_open(self, req):
269 host = req.get_host()
270 if not host:
271 raise IOError, ('ftp error', 'no host given')
272 host, port = splitport(host)
273 if port is None:
274 port = ftplib.FTP_PORT
275
276 # username/password handling
277 user, host = splituser(host)
278 if user:
279 user, passwd = splitpasswd(user)
280 else:
281 passwd = None
282 host = unquote(host)
283 user = unquote(user or '')
284 passwd = unquote(passwd or '')
285
286 try:
287 host = socket.gethostbyname(host)
288 except socket.error, msg:
289 raise urllib2.URLError(msg)
290 path, attrs = splitattr(req.get_selector())
291 dirs = path.split('/')
292 dirs = map(unquote, dirs)
293 dirs, file = dirs[:-1], dirs[-1]
294 if dirs and not dirs[0]:
295 dirs = dirs[1:]
296 try:
297 fw = self.connect_ftp(user, passwd, host, port, dirs)
298 type = file and 'I' or 'D'
299 for attr in attrs:
300 attr, value = splitattr(attr)
301 if attr.lower() == 'type' and \
302 value in ('a', 'A', 'i', 'I', 'd', 'D'):
303 type = value.upper()
304
305 # -- range support modifications start here
306 rest = None
307 range_tup = range_header_to_tuple(req.headers.get('Range',None))
308 assert range_tup != ()
309 if range_tup:
310 (fb,lb) = range_tup
311 if fb > 0: rest = fb
312 # -- range support modifications end here
313
314 fp, retrlen = fw.retrfile(file, type, rest)
315
316 # -- range support modifications start here
317 if range_tup:
318 (fb,lb) = range_tup
319 if lb == '':
320 if retrlen is None or retrlen == 0:
321 raise RangeError('Requested Range Not Satisfiable due to unobtainable file length.')
322 lb = retrlen
323 retrlen = lb - fb
324 if retrlen < 0:
325 # beginning of range is larger than file
326 raise RangeError('Requested Range Not Satisfiable')
327 else:
328 retrlen = lb - fb
329 fp = RangeableFileObject(fp, (0,retrlen))
330 # -- range support modifications end here
331
332 headers = ""
333 mtype = mimetypes.guess_type(req.get_full_url())[0]
334 if mtype:
335 headers += "Content-Type: %s\n" % mtype
336 if retrlen is not None and retrlen >= 0:
337 headers += "Content-Length: %d\n" % retrlen
338 sf = StringIO(headers)
339 headers = mimetools.Message(sf)
340 return addinfourl(fp, headers, req.get_full_url())
341 except ftplib.all_errors, msg:
342 raise IOError, ('ftp error', msg), sys.exc_info()[2]
343
344 def connect_ftp(self, user, passwd, host, port, dirs):
345 fw = ftpwrapper(user, passwd, host, port, dirs)
346 return fw
347
348class ftpwrapper(urllib.ftpwrapper):
349 # range support note:
350 # this ftpwrapper code is copied directly from
351 # urllib. The only enhancement is to add the rest
352 # argument and pass it on to ftp.ntransfercmd
353 def retrfile(self, file, type, rest=None):
354 self.endtransfer()
355 if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1
356 else: cmd = 'TYPE ' + type; isdir = 0
357 try:
358 self.ftp.voidcmd(cmd)
359 except ftplib.all_errors:
360 self.init()
361 self.ftp.voidcmd(cmd)
362 conn = None
363 if file and not isdir:
364 # Use nlst to see if the file exists at all
365 try:
366 self.ftp.nlst(file)
367 except ftplib.error_perm, reason:
368 raise IOError, ('ftp error', reason), sys.exc_info()[2]
369 # Restore the transfer mode!
370 self.ftp.voidcmd(cmd)
371 # Try to retrieve as a file
372 try:
373 cmd = 'RETR ' + file
374 conn = self.ftp.ntransfercmd(cmd, rest)
375 except ftplib.error_perm, reason:
376 if str(reason)[:3] == '501':
377 # workaround for REST not supported error
378 fp, retrlen = self.retrfile(file, type)
379 fp = RangeableFileObject(fp, (rest,''))
380 return (fp, retrlen)
381 elif str(reason)[:3] != '550':
382 raise IOError, ('ftp error', reason), sys.exc_info()[2]
383 if not conn:
384 # Set transfer mode to ASCII!
385 self.ftp.voidcmd('TYPE A')
386 # Try a directory listing
387 if file: cmd = 'LIST ' + file
388 else: cmd = 'LIST'
389 conn = self.ftp.ntransfercmd(cmd)
390 self.busy = 1
391 # Pass back both a suitably decorated object and a retrieval length
392 return (addclosehook(conn[0].makefile('rb'),
393 self.endtransfer), conn[1])
394
395
396####################################################################
397# Range Tuple Functions
398# XXX: These range tuple functions might go better in a class.
399
400_rangere = None
401def range_header_to_tuple(range_header):
402 """Get a (firstbyte,lastbyte) tuple from a Range header value.
403
404 Range headers have the form "bytes=<firstbyte>-<lastbyte>". This
405 function pulls the firstbyte and lastbyte values and returns
406 a (firstbyte,lastbyte) tuple. If lastbyte is not specified in
407 the header value, it is returned as an empty string in the
408 tuple.
409
410 Return None if range_header is None
411 Return () if range_header does not conform to the range spec
412 pattern.
413
414 """
415 global _rangere
416 if range_header is None: return None
417 if _rangere is None:
418 import re
419 _rangere = re.compile(r'^bytes=(\d{1,})-(\d*)')
420 match = _rangere.match(range_header)
421 if match:
422 tup = range_tuple_normalize(match.group(1,2))
423 if tup and tup[1]:
424 tup = (tup[0],tup[1]+1)
425 return tup
426 return ()
427
428def range_tuple_to_header(range_tup):
429 """Convert a range tuple to a Range header value.
430 Return a string of the form "bytes=<firstbyte>-<lastbyte>" or None
431 if no range is needed.
432 """
433 if range_tup is None: return None
434 range_tup = range_tuple_normalize(range_tup)
435 if range_tup:
436 if range_tup[1]:
437 range_tup = (range_tup[0],range_tup[1] - 1)
438 return 'bytes=%s-%s' % range_tup
439
440def range_tuple_normalize(range_tup):
441 """Normalize a (first_byte,last_byte) range tuple.
442 Return a tuple whose first element is guaranteed to be an int
443 and whose second element will be '' (meaning: the last byte) or
444 an int. Finally, return None if the normalized tuple == (0,'')
445 as that is equivelant to retrieving the entire file.
446 """
447 if range_tup is None: return None
448 # handle first byte
449 fb = range_tup[0]
450 if fb in (None,''): fb = 0
451 else: fb = int(fb)
452 # handle last byte
453 try: lb = range_tup[1]
454 except IndexError: lb = ''
455 else:
456 if lb is None: lb = ''
457 elif lb != '': lb = int(lb)
458 # check if range is over the entire file
459 if (fb,lb) == (0,''): return None
460 # check that the range is valid
461 if lb < fb: raise RangeError('Invalid byte range: %s-%s' % (fb,lb))
462 return (fb,lb)
463
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/grabber.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/grabber.py
new file mode 100644
index 0000000000..fefdab36f6
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/grabber.py
@@ -0,0 +1,1477 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
19
20"""A high-level cross-protocol url-grabber.
21
22GENERAL ARGUMENTS (kwargs)
23
24 Where possible, the module-level default is indicated, and legal
25 values are provided.
26
27 copy_local = 0 [0|1]
28
29 ignored except for file:// urls, in which case it specifies
30 whether urlgrab should still make a copy of the file, or simply
31 point to the existing copy. The module level default for this
32 option is 0.
33
34 close_connection = 0 [0|1]
35
36 tells URLGrabber to close the connection after a file has been
37 transfered. This is ignored unless the download happens with the
38 http keepalive handler (keepalive=1). Otherwise, the connection
39 is left open for further use. The module level default for this
40 option is 0 (keepalive connections will not be closed).
41
42 keepalive = 1 [0|1]
43
44 specifies whether keepalive should be used for HTTP/1.1 servers
45 that support it. The module level default for this option is 1
46 (keepalive is enabled).
47
48 progress_obj = None
49
50 a class instance that supports the following methods:
51 po.start(filename, url, basename, length, text)
52 # length will be None if unknown
53 po.update(read) # read == bytes read so far
54 po.end()
55
56 text = None
57
58 specifies an alternativ text item in the beginning of the progress
59 bar line. If not given, the basename of the file is used.
60
61 throttle = 1.0
62
63 a number - if it's an int, it's the bytes/second throttle limit.
64 If it's a float, it is first multiplied by bandwidth. If throttle
65 == 0, throttling is disabled. If None, the module-level default
66 (which can be set on default_grabber.throttle) is used. See
67 BANDWIDTH THROTTLING for more information.
68
69 timeout = None
70
71 a positive float expressing the number of seconds to wait for socket
72 operations. If the value is None or 0.0, socket operations will block
73 forever. Setting this option causes urlgrabber to call the settimeout
74 method on the Socket object used for the request. See the Python
75 documentation on settimeout for more information.
76 http://www.python.org/doc/current/lib/socket-objects.html
77
78 bandwidth = 0
79
80 the nominal max bandwidth in bytes/second. If throttle is a float
81 and bandwidth == 0, throttling is disabled. If None, the
82 module-level default (which can be set on
83 default_grabber.bandwidth) is used. See BANDWIDTH THROTTLING for
84 more information.
85
86 range = None
87
88 a tuple of the form (first_byte, last_byte) describing a byte
89 range to retrieve. Either or both of the values may set to
90 None. If first_byte is None, byte offset 0 is assumed. If
91 last_byte is None, the last byte available is assumed. Note that
92 the range specification is python-like in that (0,10) will yeild
93 the first 10 bytes of the file.
94
95 If set to None, no range will be used.
96
97 reget = None [None|'simple'|'check_timestamp']
98
99 whether to attempt to reget a partially-downloaded file. Reget
100 only applies to .urlgrab and (obviously) only if there is a
101 partially downloaded file. Reget has two modes:
102
103 'simple' -- the local file will always be trusted. If there
104 are 100 bytes in the local file, then the download will always
105 begin 100 bytes into the requested file.
106
107 'check_timestamp' -- the timestamp of the server file will be
108 compared to the timestamp of the local file. ONLY if the
109 local file is newer than or the same age as the server file
110 will reget be used. If the server file is newer, or the
111 timestamp is not returned, the entire file will be fetched.
112
113 NOTE: urlgrabber can do very little to verify that the partial
114 file on disk is identical to the beginning of the remote file.
115 You may want to either employ a custom "checkfunc" or simply avoid
116 using reget in situations where corruption is a concern.
117
118 user_agent = 'urlgrabber/VERSION'
119
120 a string, usually of the form 'AGENT/VERSION' that is provided to
121 HTTP servers in the User-agent header. The module level default
122 for this option is "urlgrabber/VERSION".
123
124 http_headers = None
125
126 a tuple of 2-tuples, each containing a header and value. These
127 will be used for http and https requests only. For example, you
128 can do
129 http_headers = (('Pragma', 'no-cache'),)
130
131 ftp_headers = None
132
133 this is just like http_headers, but will be used for ftp requests.
134
135 proxies = None
136
137 a dictionary that maps protocol schemes to proxy hosts. For
138 example, to use a proxy server on host "foo" port 3128 for http
139 and https URLs:
140 proxies={ 'http' : 'http://foo:3128', 'https' : 'http://foo:3128' }
141 note that proxy authentication information may be provided using
142 normal URL constructs:
143 proxies={ 'http' : 'http://user:host@foo:3128' }
144 Lastly, if proxies is None, the default environment settings will
145 be used.
146
147 prefix = None
148
149 a url prefix that will be prepended to all requested urls. For
150 example:
151 g = URLGrabber(prefix='http://foo.com/mirror/')
152 g.urlgrab('some/file.txt')
153 ## this will fetch 'http://foo.com/mirror/some/file.txt'
154 This option exists primarily to allow identical behavior to
155 MirrorGroup (and derived) instances. Note: a '/' will be inserted
156 if necessary, so you cannot specify a prefix that ends with a
157 partial file or directory name.
158
159 opener = None
160
161 Overrides the default urllib2.OpenerDirector provided to urllib2
162 when making requests. This option exists so that the urllib2
163 handler chain may be customized. Note that the range, reget,
164 proxy, and keepalive features require that custom handlers be
165 provided to urllib2 in order to function properly. If an opener
166 option is provided, no attempt is made by urlgrabber to ensure
167 chain integrity. You are responsible for ensuring that any
168 extension handlers are present if said features are required.
169
170 data = None
171
172 Only relevant for the HTTP family (and ignored for other
173 protocols), this allows HTTP POSTs. When the data kwarg is
174 present (and not None), an HTTP request will automatically become
175 a POST rather than GET. This is done by direct passthrough to
176 urllib2. If you use this, you may also want to set the
177 'Content-length' and 'Content-type' headers with the http_headers
178 option. Note that python 2.2 handles the case of these
179 badly and if you do not use the proper case (shown here), your
180 values will be overridden with the defaults.
181
182
183RETRY RELATED ARGUMENTS
184
185 retry = None
186
187 the number of times to retry the grab before bailing. If this is
188 zero, it will retry forever. This was intentional... really, it
189 was :). If this value is not supplied or is supplied but is None
190 retrying does not occur.
191
192 retrycodes = [-1,2,4,5,6,7]
193
194 a sequence of errorcodes (values of e.errno) for which it should
195 retry. See the doc on URLGrabError for more details on this. You
196 might consider modifying a copy of the default codes rather than
197 building yours from scratch so that if the list is extended in the
198 future (or one code is split into two) you can still enjoy the
199 benefits of the default list. You can do that with something like
200 this:
201
202 retrycodes = urlgrabber.grabber.URLGrabberOptions().retrycodes
203 if 12 not in retrycodes:
204 retrycodes.append(12)
205
206 checkfunc = None
207
208 a function to do additional checks. This defaults to None, which
209 means no additional checking. The function should simply return
210 on a successful check. It should raise URLGrabError on an
211 unsuccessful check. Raising of any other exception will be
212 considered immediate failure and no retries will occur.
213
214 If it raises URLGrabError, the error code will determine the retry
215 behavior. Negative error numbers are reserved for use by these
216 passed in functions, so you can use many negative numbers for
217 different types of failure. By default, -1 results in a retry,
218 but this can be customized with retrycodes.
219
220 If you simply pass in a function, it will be given exactly one
221 argument: a CallbackObject instance with the .url attribute
222 defined and either .filename (for urlgrab) or .data (for urlread).
223 For urlgrab, .filename is the name of the local file. For
224 urlread, .data is the actual string data. If you need other
225 arguments passed to the callback (program state of some sort), you
226 can do so like this:
227
228 checkfunc=(function, ('arg1', 2), {'kwarg': 3})
229
230 if the downloaded file has filename /tmp/stuff, then this will
231 result in this call (for urlgrab):
232
233 function(obj, 'arg1', 2, kwarg=3)
234 # obj.filename = '/tmp/stuff'
235 # obj.url = 'http://foo.com/stuff'
236
237 NOTE: both the "args" tuple and "kwargs" dict must be present if
238 you use this syntax, but either (or both) can be empty.
239
240 failure_callback = None
241
242 The callback that gets called during retries when an attempt to
243 fetch a file fails. The syntax for specifying the callback is
244 identical to checkfunc, except for the attributes defined in the
245 CallbackObject instance. The attributes for failure_callback are:
246
247 exception = the raised exception
248 url = the url we're trying to fetch
249 tries = the number of tries so far (including this one)
250 retry = the value of the retry option
251
252 The callback is present primarily to inform the calling program of
253 the failure, but if it raises an exception (including the one it's
254 passed) that exception will NOT be caught and will therefore cause
255 future retries to be aborted.
256
257 The callback is called for EVERY failure, including the last one.
258 On the last try, the callback can raise an alternate exception,
259 but it cannot (without severe trickiness) prevent the exception
260 from being raised.
261
262 interrupt_callback = None
263
264 This callback is called if KeyboardInterrupt is received at any
265 point in the transfer. Basically, this callback can have three
266 impacts on the fetch process based on the way it exits:
267
268 1) raise no exception: the current fetch will be aborted, but
269 any further retries will still take place
270
271 2) raise a URLGrabError: if you're using a MirrorGroup, then
272 this will prompt a failover to the next mirror according to
273 the behavior of the MirrorGroup subclass. It is recommended
274 that you raise URLGrabError with code 15, 'user abort'. If
275 you are NOT using a MirrorGroup subclass, then this is the
276 same as (3).
277
278 3) raise some other exception (such as KeyboardInterrupt), which
279 will not be caught at either the grabber or mirror levels.
280 That is, it will be raised up all the way to the caller.
281
282 This callback is very similar to failure_callback. They are
283 passed the same arguments, so you could use the same function for
284 both.
285
286 urlparser = URLParser()
287
288 The URLParser class handles pre-processing of URLs, including
289 auth-handling for user/pass encoded in http urls, file handing
290 (that is, filenames not sent as a URL), and URL quoting. If you
291 want to override any of this behavior, you can pass in a
292 replacement instance. See also the 'quote' option.
293
294 quote = None
295
296 Whether or not to quote the path portion of a url.
297 quote = 1 -> quote the URLs (they're not quoted yet)
298 quote = 0 -> do not quote them (they're already quoted)
299 quote = None -> guess what to do
300
301 This option only affects proper urls like 'file:///etc/passwd'; it
302 does not affect 'raw' filenames like '/etc/passwd'. The latter
303 will always be quoted as they are converted to URLs. Also, only
304 the path part of a url is quoted. If you need more fine-grained
305 control, you should probably subclass URLParser and pass it in via
306 the 'urlparser' option.
307
308BANDWIDTH THROTTLING
309
310 urlgrabber supports throttling via two values: throttle and
311 bandwidth Between the two, you can either specify and absolute
312 throttle threshold or specify a theshold as a fraction of maximum
313 available bandwidth.
314
315 throttle is a number - if it's an int, it's the bytes/second
316 throttle limit. If it's a float, it is first multiplied by
317 bandwidth. If throttle == 0, throttling is disabled. If None, the
318 module-level default (which can be set with set_throttle) is used.
319
320 bandwidth is the nominal max bandwidth in bytes/second. If throttle
321 is a float and bandwidth == 0, throttling is disabled. If None, the
322 module-level default (which can be set with set_bandwidth) is used.
323
324 THROTTLING EXAMPLES:
325
326 Lets say you have a 100 Mbps connection. This is (about) 10^8 bits
327 per second, or 12,500,000 Bytes per second. You have a number of
328 throttling options:
329
330 *) set_bandwidth(12500000); set_throttle(0.5) # throttle is a float
331
332 This will limit urlgrab to use half of your available bandwidth.
333
334 *) set_throttle(6250000) # throttle is an int
335
336 This will also limit urlgrab to use half of your available
337 bandwidth, regardless of what bandwidth is set to.
338
339 *) set_throttle(6250000); set_throttle(1.0) # float
340
341 Use half your bandwidth
342
343 *) set_throttle(6250000); set_throttle(2.0) # float
344
345 Use up to 12,500,000 Bytes per second (your nominal max bandwidth)
346
347 *) set_throttle(6250000); set_throttle(0) # throttle = 0
348
349 Disable throttling - this is more efficient than a very large
350 throttle setting.
351
352 *) set_throttle(0); set_throttle(1.0) # throttle is float, bandwidth = 0
353
354 Disable throttling - this is the default when the module is loaded.
355
356 SUGGESTED AUTHOR IMPLEMENTATION (THROTTLING)
357
358 While this is flexible, it's not extremely obvious to the user. I
359 suggest you implement a float throttle as a percent to make the
360 distinction between absolute and relative throttling very explicit.
361
362 Also, you may want to convert the units to something more convenient
363 than bytes/second, such as kbps or kB/s, etc.
364
365"""
366
367# $Id: grabber.py,v 1.48 2006/09/22 00:58:05 mstenner Exp $
368
369import os
370import os.path
371import sys
372import urlparse
373import rfc822
374import time
375import string
376import urllib
377import urllib2
378from stat import * # S_* and ST_*
379
380########################################################################
381# MODULE INITIALIZATION
382########################################################################
383try:
384 exec('from ' + (__name__.split('.'))[0] + ' import __version__')
385except:
386 __version__ = '???'
387
388import sslfactory
389
390auth_handler = urllib2.HTTPBasicAuthHandler( \
391 urllib2.HTTPPasswordMgrWithDefaultRealm())
392
393try:
394 from i18n import _
395except ImportError, msg:
396 def _(st): return st
397
398try:
399 from httplib import HTTPException
400except ImportError, msg:
401 HTTPException = None
402
403try:
404 # This is a convenient way to make keepalive optional.
405 # Just rename the module so it can't be imported.
406 import keepalive
407 from keepalive import HTTPHandler, HTTPSHandler
408 have_keepalive = True
409except ImportError, msg:
410 have_keepalive = False
411
412try:
413 # add in range support conditionally too
414 import byterange
415 from byterange import HTTPRangeHandler, HTTPSRangeHandler, \
416 FileRangeHandler, FTPRangeHandler, range_tuple_normalize, \
417 range_tuple_to_header, RangeError
418except ImportError, msg:
419 range_handlers = ()
420 RangeError = None
421 have_range = 0
422else:
423 range_handlers = (HTTPRangeHandler(), HTTPSRangeHandler(),
424 FileRangeHandler(), FTPRangeHandler())
425 have_range = 1
426
427
428# check whether socket timeout support is available (Python >= 2.3)
429import socket
430try:
431 TimeoutError = socket.timeout
432 have_socket_timeout = True
433except AttributeError:
434 TimeoutError = None
435 have_socket_timeout = False
436
437########################################################################
438# functions for debugging output. These functions are here because they
439# are also part of the module initialization.
440DEBUG = None
441def set_logger(DBOBJ):
442 """Set the DEBUG object. This is called by _init_default_logger when
443 the environment variable URLGRABBER_DEBUG is set, but can also be
444 called by a calling program. Basically, if the calling program uses
445 the logging module and would like to incorporate urlgrabber logging,
446 then it can do so this way. It's probably not necessary as most
447 internal logging is only for debugging purposes.
448
449 The passed-in object should be a logging.Logger instance. It will
450 be pushed into the keepalive and byterange modules if they're
451 being used. The mirror module pulls this object in on import, so
452 you will need to manually push into it. In fact, you may find it
453 tidier to simply push your logging object (or objects) into each
454 of these modules independently.
455 """
456
457 global DEBUG
458 DEBUG = DBOBJ
459 if have_keepalive and keepalive.DEBUG is None:
460 keepalive.DEBUG = DBOBJ
461 if have_range and byterange.DEBUG is None:
462 byterange.DEBUG = DBOBJ
463 if sslfactory.DEBUG is None:
464 sslfactory.DEBUG = DBOBJ
465
466def _init_default_logger():
467 '''Examines the environment variable URLGRABBER_DEBUG and creates
468 a logging object (logging.logger) based on the contents. It takes
469 the form
470
471 URLGRABBER_DEBUG=level,filename
472
473 where "level" can be either an integer or a log level from the
474 logging module (DEBUG, INFO, etc). If the integer is zero or
475 less, logging will be disabled. Filename is the filename where
476 logs will be sent. If it is "-", then stdout will be used. If
477 the filename is empty or missing, stderr will be used. If the
478 variable cannot be processed or the logging module cannot be
479 imported (python < 2.3) then logging will be disabled. Here are
480 some examples:
481
482 URLGRABBER_DEBUG=1,debug.txt # log everything to debug.txt
483 URLGRABBER_DEBUG=WARNING,- # log warning and higher to stdout
484 URLGRABBER_DEBUG=INFO # log info and higher to stderr
485
486 This funtion is called during module initialization. It is not
487 intended to be called from outside. The only reason it is a
488 function at all is to keep the module-level namespace tidy and to
489 collect the code into a nice block.'''
490
491 try:
492 dbinfo = os.environ['URLGRABBER_DEBUG'].split(',')
493 import logging
494 level = logging._levelNames.get(dbinfo[0], int(dbinfo[0]))
495 if level < 1: raise ValueError()
496
497 formatter = logging.Formatter('%(asctime)s %(message)s')
498 if len(dbinfo) > 1: filename = dbinfo[1]
499 else: filename = ''
500 if filename == '': handler = logging.StreamHandler(sys.stderr)
501 elif filename == '-': handler = logging.StreamHandler(sys.stdout)
502 else: handler = logging.FileHandler(filename)
503 handler.setFormatter(formatter)
504 DBOBJ = logging.getLogger('urlgrabber')
505 DBOBJ.addHandler(handler)
506 DBOBJ.setLevel(level)
507 except (KeyError, ImportError, ValueError):
508 DBOBJ = None
509 set_logger(DBOBJ)
510
511_init_default_logger()
512########################################################################
513# END MODULE INITIALIZATION
514########################################################################
515
516
517
518class URLGrabError(IOError):
519 """
520 URLGrabError error codes:
521
522 URLGrabber error codes (0 -- 255)
523 0 - everything looks good (you should never see this)
524 1 - malformed url
525 2 - local file doesn't exist
526 3 - request for non-file local file (dir, etc)
527 4 - IOError on fetch
528 5 - OSError on fetch
529 6 - no content length header when we expected one
530 7 - HTTPException
531 8 - Exceeded read limit (for urlread)
532 9 - Requested byte range not satisfiable.
533 10 - Byte range requested, but range support unavailable
534 11 - Illegal reget mode
535 12 - Socket timeout
536 13 - malformed proxy url
537 14 - HTTPError (includes .code and .exception attributes)
538 15 - user abort
539
540 MirrorGroup error codes (256 -- 511)
541 256 - No more mirrors left to try
542
543 Custom (non-builtin) classes derived from MirrorGroup (512 -- 767)
544 [ this range reserved for application-specific error codes ]
545
546 Retry codes (< 0)
547 -1 - retry the download, unknown reason
548
549 Note: to test which group a code is in, you can simply do integer
550 division by 256: e.errno / 256
551
552 Negative codes are reserved for use by functions passed in to
553 retrygrab with checkfunc. The value -1 is built in as a generic
554 retry code and is already included in the retrycodes list.
555 Therefore, you can create a custom check function that simply
556 returns -1 and the fetch will be re-tried. For more customized
557 retries, you can use other negative number and include them in
558 retry-codes. This is nice for outputting useful messages about
559 what failed.
560
561 You can use these error codes like so:
562 try: urlgrab(url)
563 except URLGrabError, e:
564 if e.errno == 3: ...
565 # or
566 print e.strerror
567 # or simply
568 print e #### print '[Errno %i] %s' % (e.errno, e.strerror)
569 """
570 pass
571
572class CallbackObject:
573 """Container for returned callback data.
574
575 This is currently a dummy class into which urlgrabber can stuff
576 information for passing to callbacks. This way, the prototype for
577 all callbacks is the same, regardless of the data that will be
578 passed back. Any function that accepts a callback function as an
579 argument SHOULD document what it will define in this object.
580
581 It is possible that this class will have some greater
582 functionality in the future.
583 """
584 def __init__(self, **kwargs):
585 self.__dict__.update(kwargs)
586
587def urlgrab(url, filename=None, **kwargs):
588 """grab the file at <url> and make a local copy at <filename>
589 If filename is none, the basename of the url is used.
590 urlgrab returns the filename of the local file, which may be different
591 from the passed-in filename if the copy_local kwarg == 0.
592
593 See module documentation for a description of possible kwargs.
594 """
595 return default_grabber.urlgrab(url, filename, **kwargs)
596
597def urlopen(url, **kwargs):
598 """open the url and return a file object
599 If a progress object or throttle specifications exist, then
600 a special file object will be returned that supports them.
601 The file object can be treated like any other file object.
602
603 See module documentation for a description of possible kwargs.
604 """
605 return default_grabber.urlopen(url, **kwargs)
606
607def urlread(url, limit=None, **kwargs):
608 """read the url into a string, up to 'limit' bytes
609 If the limit is exceeded, an exception will be thrown. Note that urlread
610 is NOT intended to be used as a way of saying "I want the first N bytes"
611 but rather 'read the whole file into memory, but don't use too much'
612
613 See module documentation for a description of possible kwargs.
614 """
615 return default_grabber.urlread(url, limit, **kwargs)
616
617
618class URLParser:
619 """Process the URLs before passing them to urllib2.
620
621 This class does several things:
622
623 * add any prefix
624 * translate a "raw" file to a proper file: url
625 * handle any http or https auth that's encoded within the url
626 * quote the url
627
628 Only the "parse" method is called directly, and it calls sub-methods.
629
630 An instance of this class is held in the options object, which
631 means that it's easy to change the behavior by sub-classing and
632 passing the replacement in. It need only have a method like:
633
634 url, parts = urlparser.parse(url, opts)
635 """
636
637 def parse(self, url, opts):
638 """parse the url and return the (modified) url and its parts
639
640 Note: a raw file WILL be quoted when it's converted to a URL.
641 However, other urls (ones which come with a proper scheme) may
642 or may not be quoted according to opts.quote
643
644 opts.quote = 1 --> quote it
645 opts.quote = 0 --> do not quote it
646 opts.quote = None --> guess
647 """
648 quote = opts.quote
649
650 if opts.prefix:
651 url = self.add_prefix(url, opts.prefix)
652
653 parts = urlparse.urlparse(url)
654 (scheme, host, path, parm, query, frag) = parts
655
656 if not scheme or (len(scheme) == 1 and scheme in string.letters):
657 # if a scheme isn't specified, we guess that it's "file:"
658 if url[0] not in '/\\': url = os.path.abspath(url)
659 url = 'file:' + urllib.pathname2url(url)
660 parts = urlparse.urlparse(url)
661 quote = 0 # pathname2url quotes, so we won't do it again
662
663 if scheme in ['http', 'https']:
664 parts = self.process_http(parts)
665
666 if quote is None:
667 quote = self.guess_should_quote(parts)
668 if quote:
669 parts = self.quote(parts)
670
671 url = urlparse.urlunparse(parts)
672 return url, parts
673
674 def add_prefix(self, url, prefix):
675 if prefix[-1] == '/' or url[0] == '/':
676 url = prefix + url
677 else:
678 url = prefix + '/' + url
679 return url
680
681 def process_http(self, parts):
682 (scheme, host, path, parm, query, frag) = parts
683
684 if '@' in host and auth_handler:
685 try:
686 user_pass, host = host.split('@', 1)
687 if ':' in user_pass:
688 user, password = user_pass.split(':', 1)
689 except ValueError, e:
690 raise URLGrabError(1, _('Bad URL: %s') % url)
691 if DEBUG: DEBUG.info('adding HTTP auth: %s, XXXXXXXX', user)
692 auth_handler.add_password(None, host, user, password)
693
694 return (scheme, host, path, parm, query, frag)
695
696 def quote(self, parts):
697 """quote the URL
698
699 This method quotes ONLY the path part. If you need to quote
700 other parts, you should override this and pass in your derived
701 class. The other alternative is to quote other parts before
702 passing into urlgrabber.
703 """
704 (scheme, host, path, parm, query, frag) = parts
705 path = urllib.quote(path)
706 return (scheme, host, path, parm, query, frag)
707
708 hexvals = '0123456789ABCDEF'
709 def guess_should_quote(self, parts):
710 """
711 Guess whether we should quote a path. This amounts to
712 guessing whether it's already quoted.
713
714 find ' ' -> 1
715 find '%' -> 1
716 find '%XX' -> 0
717 else -> 1
718 """
719 (scheme, host, path, parm, query, frag) = parts
720 if ' ' in path:
721 return 1
722 ind = string.find(path, '%')
723 if ind > -1:
724 while ind > -1:
725 if len(path) < ind+3:
726 return 1
727 code = path[ind+1:ind+3].upper()
728 if code[0] not in self.hexvals or \
729 code[1] not in self.hexvals:
730 return 1
731 ind = string.find(path, '%', ind+1)
732 return 0
733 return 1
734
735class URLGrabberOptions:
736 """Class to ease kwargs handling."""
737
738 def __init__(self, delegate=None, **kwargs):
739 """Initialize URLGrabberOptions object.
740 Set default values for all options and then update options specified
741 in kwargs.
742 """
743 self.delegate = delegate
744 if delegate is None:
745 self._set_defaults()
746 self._set_attributes(**kwargs)
747
748 def __getattr__(self, name):
749 if self.delegate and hasattr(self.delegate, name):
750 return getattr(self.delegate, name)
751 raise AttributeError, name
752
753 def raw_throttle(self):
754 """Calculate raw throttle value from throttle and bandwidth
755 values.
756 """
757 if self.throttle <= 0:
758 return 0
759 elif type(self.throttle) == type(0):
760 return float(self.throttle)
761 else: # throttle is a float
762 return self.bandwidth * self.throttle
763
764 def derive(self, **kwargs):
765 """Create a derived URLGrabberOptions instance.
766 This method creates a new instance and overrides the
767 options specified in kwargs.
768 """
769 return URLGrabberOptions(delegate=self, **kwargs)
770
771 def _set_attributes(self, **kwargs):
772 """Update object attributes with those provided in kwargs."""
773 self.__dict__.update(kwargs)
774 if have_range and kwargs.has_key('range'):
775 # normalize the supplied range value
776 self.range = range_tuple_normalize(self.range)
777 if not self.reget in [None, 'simple', 'check_timestamp']:
778 raise URLGrabError(11, _('Illegal reget mode: %s') \
779 % (self.reget, ))
780
781 def _set_defaults(self):
782 """Set all options to their default values.
783 When adding new options, make sure a default is
784 provided here.
785 """
786 self.progress_obj = None
787 self.throttle = 1.0
788 self.bandwidth = 0
789 self.retry = None
790 self.retrycodes = [-1,2,4,5,6,7]
791 self.checkfunc = None
792 self.copy_local = 0
793 self.close_connection = 0
794 self.range = None
795 self.user_agent = 'urlgrabber/%s' % __version__
796 self.keepalive = 1
797 self.proxies = None
798 self.reget = None
799 self.failure_callback = None
800 self.interrupt_callback = None
801 self.prefix = None
802 self.opener = None
803 self.cache_openers = True
804 self.timeout = None
805 self.text = None
806 self.http_headers = None
807 self.ftp_headers = None
808 self.data = None
809 self.urlparser = URLParser()
810 self.quote = None
811 self.ssl_ca_cert = None
812 self.ssl_context = None
813
814class URLGrabber:
815 """Provides easy opening of URLs with a variety of options.
816
817 All options are specified as kwargs. Options may be specified when
818 the class is created and may be overridden on a per request basis.
819
820 New objects inherit default values from default_grabber.
821 """
822
823 def __init__(self, **kwargs):
824 self.opts = URLGrabberOptions(**kwargs)
825
826 def _retry(self, opts, func, *args):
827 tries = 0
828 while 1:
829 # there are only two ways out of this loop. The second has
830 # several "sub-ways"
831 # 1) via the return in the "try" block
832 # 2) by some exception being raised
833 # a) an excepton is raised that we don't "except"
834 # b) a callback raises ANY exception
835 # c) we're not retry-ing or have run out of retries
836 # d) the URLGrabError code is not in retrycodes
837 # beware of infinite loops :)
838 tries = tries + 1
839 exception = None
840 retrycode = None
841 callback = None
842 if DEBUG: DEBUG.info('attempt %i/%s: %s',
843 tries, opts.retry, args[0])
844 try:
845 r = apply(func, (opts,) + args, {})
846 if DEBUG: DEBUG.info('success')
847 return r
848 except URLGrabError, e:
849 exception = e
850 callback = opts.failure_callback
851 retrycode = e.errno
852 except KeyboardInterrupt, e:
853 exception = e
854 callback = opts.interrupt_callback
855
856 if DEBUG: DEBUG.info('exception: %s', exception)
857 if callback:
858 if DEBUG: DEBUG.info('calling callback: %s', callback)
859 cb_func, cb_args, cb_kwargs = self._make_callback(callback)
860 obj = CallbackObject(exception=exception, url=args[0],
861 tries=tries, retry=opts.retry)
862 cb_func(obj, *cb_args, **cb_kwargs)
863
864 if (opts.retry is None) or (tries == opts.retry):
865 if DEBUG: DEBUG.info('retries exceeded, re-raising')
866 raise
867
868 if (retrycode is not None) and (retrycode not in opts.retrycodes):
869 if DEBUG: DEBUG.info('retrycode (%i) not in list %s, re-raising',
870 retrycode, opts.retrycodes)
871 raise
872
873 def urlopen(self, url, **kwargs):
874 """open the url and return a file object
875 If a progress object or throttle value specified when this
876 object was created, then a special file object will be
877 returned that supports them. The file object can be treated
878 like any other file object.
879 """
880 opts = self.opts.derive(**kwargs)
881 (url,parts) = opts.urlparser.parse(url, opts)
882 def retryfunc(opts, url):
883 return URLGrabberFileObject(url, filename=None, opts=opts)
884 return self._retry(opts, retryfunc, url)
885
886 def urlgrab(self, url, filename=None, **kwargs):
887 """grab the file at <url> and make a local copy at <filename>
888 If filename is none, the basename of the url is used.
889 urlgrab returns the filename of the local file, which may be
890 different from the passed-in filename if copy_local == 0.
891 """
892 opts = self.opts.derive(**kwargs)
893 (url,parts) = opts.urlparser.parse(url, opts)
894 (scheme, host, path, parm, query, frag) = parts
895 if filename is None:
896 filename = os.path.basename( urllib.unquote(path) )
897 if scheme == 'file' and not opts.copy_local:
898 # just return the name of the local file - don't make a
899 # copy currently
900 path = urllib.url2pathname(path)
901 if host:
902 path = os.path.normpath('//' + host + path)
903 if not os.path.exists(path):
904 raise URLGrabError(2,
905 _('Local file does not exist: %s') % (path, ))
906 elif not os.path.isfile(path):
907 raise URLGrabError(3,
908 _('Not a normal file: %s') % (path, ))
909 elif not opts.range:
910 return path
911
912 def retryfunc(opts, url, filename):
913 fo = URLGrabberFileObject(url, filename, opts)
914 try:
915 fo._do_grab()
916 if not opts.checkfunc is None:
917 cb_func, cb_args, cb_kwargs = \
918 self._make_callback(opts.checkfunc)
919 obj = CallbackObject()
920 obj.filename = filename
921 obj.url = url
922 apply(cb_func, (obj, )+cb_args, cb_kwargs)
923 finally:
924 fo.close()
925 return filename
926
927 return self._retry(opts, retryfunc, url, filename)
928
929 def urlread(self, url, limit=None, **kwargs):
930 """read the url into a string, up to 'limit' bytes
931 If the limit is exceeded, an exception will be thrown. Note
932 that urlread is NOT intended to be used as a way of saying
933 "I want the first N bytes" but rather 'read the whole file
934 into memory, but don't use too much'
935 """
936 opts = self.opts.derive(**kwargs)
937 (url,parts) = opts.urlparser.parse(url, opts)
938 if limit is not None:
939 limit = limit + 1
940
941 def retryfunc(opts, url, limit):
942 fo = URLGrabberFileObject(url, filename=None, opts=opts)
943 s = ''
944 try:
945 # this is an unfortunate thing. Some file-like objects
946 # have a default "limit" of None, while the built-in (real)
947 # file objects have -1. They each break the other, so for
948 # now, we just force the default if necessary.
949 if limit is None: s = fo.read()
950 else: s = fo.read(limit)
951
952 if not opts.checkfunc is None:
953 cb_func, cb_args, cb_kwargs = \
954 self._make_callback(opts.checkfunc)
955 obj = CallbackObject()
956 obj.data = s
957 obj.url = url
958 apply(cb_func, (obj, )+cb_args, cb_kwargs)
959 finally:
960 fo.close()
961 return s
962
963 s = self._retry(opts, retryfunc, url, limit)
964 if limit and len(s) > limit:
965 raise URLGrabError(8,
966 _('Exceeded limit (%i): %s') % (limit, url))
967 return s
968
969 def _make_callback(self, callback_obj):
970 if callable(callback_obj):
971 return callback_obj, (), {}
972 else:
973 return callback_obj
974
975# create the default URLGrabber used by urlXXX functions.
976# NOTE: actual defaults are set in URLGrabberOptions
977default_grabber = URLGrabber()
978
979class URLGrabberFileObject:
980 """This is a file-object wrapper that supports progress objects
981 and throttling.
982
983 This exists to solve the following problem: lets say you want to
984 drop-in replace a normal open with urlopen. You want to use a
985 progress meter and/or throttling, but how do you do that without
986 rewriting your code? Answer: urlopen will return a wrapped file
987 object that does the progress meter and-or throttling internally.
988 """
989
990 def __init__(self, url, filename, opts):
991 self.url = url
992 self.filename = filename
993 self.opts = opts
994 self.fo = None
995 self._rbuf = ''
996 self._rbufsize = 1024*8
997 self._ttime = time.time()
998 self._tsize = 0
999 self._amount_read = 0
1000 self._opener = None
1001 self._do_open()
1002
1003 def __getattr__(self, name):
1004 """This effectively allows us to wrap at the instance level.
1005 Any attribute not found in _this_ object will be searched for
1006 in self.fo. This includes methods."""
1007 if hasattr(self.fo, name):
1008 return getattr(self.fo, name)
1009 raise AttributeError, name
1010
1011 def _get_opener(self):
1012 """Build a urllib2 OpenerDirector based on request options."""
1013 if self.opts.opener:
1014 return self.opts.opener
1015 elif self._opener is None:
1016 handlers = []
1017 need_keepalive_handler = (have_keepalive and self.opts.keepalive)
1018 need_range_handler = (range_handlers and \
1019 (self.opts.range or self.opts.reget))
1020 # if you specify a ProxyHandler when creating the opener
1021 # it _must_ come before all other handlers in the list or urllib2
1022 # chokes.
1023 if self.opts.proxies:
1024 handlers.append( CachedProxyHandler(self.opts.proxies) )
1025
1026 # -------------------------------------------------------
1027 # OK, these next few lines are a serious kludge to get
1028 # around what I think is a bug in python 2.2's
1029 # urllib2. The basic idea is that default handlers
1030 # get applied first. If you override one (like a
1031 # proxy handler), then the default gets pulled, but
1032 # the replacement goes on the end. In the case of
1033 # proxies, this means the normal handler picks it up
1034 # first and the proxy isn't used. Now, this probably
1035 # only happened with ftp or non-keepalive http, so not
1036 # many folks saw it. The simple approach to fixing it
1037 # is just to make sure you override the other
1038 # conflicting defaults as well. I would LOVE to see
1039 # these go way or be dealt with more elegantly. The
1040 # problem isn't there after 2.2. -MDS 2005/02/24
1041 if not need_keepalive_handler:
1042 handlers.append( urllib2.HTTPHandler() )
1043 if not need_range_handler:
1044 handlers.append( urllib2.FTPHandler() )
1045 # -------------------------------------------------------
1046
1047 ssl_factory = sslfactory.get_factory(self.opts.ssl_ca_cert,
1048 self.opts.ssl_context)
1049
1050 if need_keepalive_handler:
1051 handlers.append(HTTPHandler())
1052 handlers.append(HTTPSHandler(ssl_factory))
1053 if need_range_handler:
1054 handlers.extend( range_handlers )
1055 handlers.append( auth_handler )
1056 if self.opts.cache_openers:
1057 self._opener = CachedOpenerDirector(ssl_factory, *handlers)
1058 else:
1059 self._opener = ssl_factory.create_opener(*handlers)
1060 # OK, I don't like to do this, but otherwise, we end up with
1061 # TWO user-agent headers.
1062 self._opener.addheaders = []
1063 return self._opener
1064
1065 def _do_open(self):
1066 opener = self._get_opener()
1067
1068 req = urllib2.Request(self.url, self.opts.data) # build request object
1069 self._add_headers(req) # add misc headers that we need
1070 self._build_range(req) # take care of reget and byterange stuff
1071
1072 fo, hdr = self._make_request(req, opener)
1073 if self.reget_time and self.opts.reget == 'check_timestamp':
1074 # do this if we have a local file with known timestamp AND
1075 # we're in check_timestamp reget mode.
1076 fetch_again = 0
1077 try:
1078 modified_tuple = hdr.getdate_tz('last-modified')
1079 modified_stamp = rfc822.mktime_tz(modified_tuple)
1080 if modified_stamp > self.reget_time: fetch_again = 1
1081 except (TypeError,):
1082 fetch_again = 1
1083
1084 if fetch_again:
1085 # the server version is newer than the (incomplete) local
1086 # version, so we should abandon the version we're getting
1087 # and fetch the whole thing again.
1088 fo.close()
1089 self.opts.reget = None
1090 del req.headers['Range']
1091 self._build_range(req)
1092 fo, hdr = self._make_request(req, opener)
1093
1094 (scheme, host, path, parm, query, frag) = urlparse.urlparse(self.url)
1095 path = urllib.unquote(path)
1096 if not (self.opts.progress_obj or self.opts.raw_throttle() \
1097 or self.opts.timeout):
1098 # if we're not using the progress_obj, throttling, or timeout
1099 # we can get a performance boost by going directly to
1100 # the underlying fileobject for reads.
1101 self.read = fo.read
1102 if hasattr(fo, 'readline'):
1103 self.readline = fo.readline
1104 elif self.opts.progress_obj:
1105 try:
1106 length = int(hdr['Content-Length'])
1107 length = length + self._amount_read # Account for regets
1108 except (KeyError, ValueError, TypeError):
1109 length = None
1110
1111 self.opts.progress_obj.start(str(self.filename),
1112 urllib.unquote(self.url),
1113 os.path.basename(path),
1114 length, text=self.opts.text)
1115 self.opts.progress_obj.update(0)
1116 (self.fo, self.hdr) = (fo, hdr)
1117
1118 def _add_headers(self, req):
1119 if self.opts.user_agent:
1120 req.add_header('User-agent', self.opts.user_agent)
1121 try: req_type = req.get_type()
1122 except ValueError: req_type = None
1123 if self.opts.http_headers and req_type in ('http', 'https'):
1124 for h, v in self.opts.http_headers:
1125 req.add_header(h, v)
1126 if self.opts.ftp_headers and req_type == 'ftp':
1127 for h, v in self.opts.ftp_headers:
1128 req.add_header(h, v)
1129
1130 def _build_range(self, req):
1131 self.reget_time = None
1132 self.append = 0
1133 reget_length = 0
1134 rt = None
1135 if have_range and self.opts.reget and type(self.filename) == type(''):
1136 # we have reget turned on and we're dumping to a file
1137 try:
1138 s = os.stat(self.filename)
1139 except OSError:
1140 pass
1141 else:
1142 self.reget_time = s[ST_MTIME]
1143 reget_length = s[ST_SIZE]
1144
1145 # Set initial length when regetting
1146 self._amount_read = reget_length
1147
1148 rt = reget_length, ''
1149 self.append = 1
1150
1151 if self.opts.range:
1152 if not have_range:
1153 raise URLGrabError(10, _('Byte range requested but range '\
1154 'support unavailable'))
1155 rt = self.opts.range
1156 if rt[0]: rt = (rt[0] + reget_length, rt[1])
1157
1158 if rt:
1159 header = range_tuple_to_header(rt)
1160 if header: req.add_header('Range', header)
1161
1162 def _make_request(self, req, opener):
1163 try:
1164 if have_socket_timeout and self.opts.timeout:
1165 old_to = socket.getdefaulttimeout()
1166 socket.setdefaulttimeout(self.opts.timeout)
1167 try:
1168 fo = opener.open(req)
1169 finally:
1170 socket.setdefaulttimeout(old_to)
1171 else:
1172 fo = opener.open(req)
1173 hdr = fo.info()
1174 except ValueError, e:
1175 raise URLGrabError(1, _('Bad URL: %s') % (e, ))
1176 except RangeError, e:
1177 raise URLGrabError(9, str(e))
1178 except urllib2.HTTPError, e:
1179 new_e = URLGrabError(14, str(e))
1180 new_e.code = e.code
1181 new_e.exception = e
1182 raise new_e
1183 except IOError, e:
1184 if hasattr(e, 'reason') and have_socket_timeout and \
1185 isinstance(e.reason, TimeoutError):
1186 raise URLGrabError(12, _('Timeout: %s') % (e, ))
1187 else:
1188 raise URLGrabError(4, _('IOError: %s') % (e, ))
1189 except OSError, e:
1190 raise URLGrabError(5, _('OSError: %s') % (e, ))
1191 except HTTPException, e:
1192 raise URLGrabError(7, _('HTTP Exception (%s): %s') % \
1193 (e.__class__.__name__, e))
1194 else:
1195 return (fo, hdr)
1196
1197 def _do_grab(self):
1198 """dump the file to self.filename."""
1199 if self.append: new_fo = open(self.filename, 'ab')
1200 else: new_fo = open(self.filename, 'wb')
1201 bs = 1024*8
1202 size = 0
1203
1204 block = self.read(bs)
1205 size = size + len(block)
1206 while block:
1207 new_fo.write(block)
1208 block = self.read(bs)
1209 size = size + len(block)
1210
1211 new_fo.close()
1212 try:
1213 modified_tuple = self.hdr.getdate_tz('last-modified')
1214 modified_stamp = rfc822.mktime_tz(modified_tuple)
1215 os.utime(self.filename, (modified_stamp, modified_stamp))
1216 except (TypeError,), e: pass
1217
1218 return size
1219
1220 def _fill_buffer(self, amt=None):
1221 """fill the buffer to contain at least 'amt' bytes by reading
1222 from the underlying file object. If amt is None, then it will
1223 read until it gets nothing more. It updates the progress meter
1224 and throttles after every self._rbufsize bytes."""
1225 # the _rbuf test is only in this first 'if' for speed. It's not
1226 # logically necessary
1227 if self._rbuf and not amt is None:
1228 L = len(self._rbuf)
1229 if amt > L:
1230 amt = amt - L
1231 else:
1232 return
1233
1234 # if we've made it here, then we don't have enough in the buffer
1235 # and we need to read more.
1236
1237 buf = [self._rbuf]
1238 bufsize = len(self._rbuf)
1239 while amt is None or amt:
1240 # first, delay if necessary for throttling reasons
1241 if self.opts.raw_throttle():
1242 diff = self._tsize/self.opts.raw_throttle() - \
1243 (time.time() - self._ttime)
1244 if diff > 0: time.sleep(diff)
1245 self._ttime = time.time()
1246
1247 # now read some data, up to self._rbufsize
1248 if amt is None: readamount = self._rbufsize
1249 else: readamount = min(amt, self._rbufsize)
1250 try:
1251 new = self.fo.read(readamount)
1252 except socket.error, e:
1253 raise URLGrabError(4, _('Socket Error: %s') % (e, ))
1254 except TimeoutError, e:
1255 raise URLGrabError(12, _('Timeout: %s') % (e, ))
1256 except IOError, e:
1257 raise URLGrabError(4, _('IOError: %s') %(e,))
1258 newsize = len(new)
1259 if not newsize: break # no more to read
1260
1261 if amt: amt = amt - newsize
1262 buf.append(new)
1263 bufsize = bufsize + newsize
1264 self._tsize = newsize
1265 self._amount_read = self._amount_read + newsize
1266 if self.opts.progress_obj:
1267 self.opts.progress_obj.update(self._amount_read)
1268
1269 self._rbuf = string.join(buf, '')
1270 return
1271
1272 def read(self, amt=None):
1273 self._fill_buffer(amt)
1274 if amt is None:
1275 s, self._rbuf = self._rbuf, ''
1276 else:
1277 s, self._rbuf = self._rbuf[:amt], self._rbuf[amt:]
1278 return s
1279
1280 def readline(self, limit=-1):
1281 i = string.find(self._rbuf, '\n')
1282 while i < 0 and not (0 < limit <= len(self._rbuf)):
1283 L = len(self._rbuf)
1284 self._fill_buffer(L + self._rbufsize)
1285 if not len(self._rbuf) > L: break
1286 i = string.find(self._rbuf, '\n', L)
1287
1288 if i < 0: i = len(self._rbuf)
1289 else: i = i+1
1290 if 0 <= limit < len(self._rbuf): i = limit
1291
1292 s, self._rbuf = self._rbuf[:i], self._rbuf[i:]
1293 return s
1294
1295 def close(self):
1296 if self.opts.progress_obj:
1297 self.opts.progress_obj.end(self._amount_read)
1298 self.fo.close()
1299 if self.opts.close_connection:
1300 try: self.fo.close_connection()
1301 except: pass
1302
1303_handler_cache = []
1304def CachedOpenerDirector(ssl_factory = None, *handlers):
1305 for (cached_handlers, opener) in _handler_cache:
1306 if cached_handlers == handlers:
1307 for handler in opener.handlers:
1308 handler.add_parent(opener)
1309 return opener
1310 if not ssl_factory:
1311 ssl_factory = sslfactory.get_factory()
1312 opener = ssl_factory.create_opener(*handlers)
1313 _handler_cache.append( (handlers, opener) )
1314 return opener
1315
1316_proxy_cache = []
1317def CachedProxyHandler(proxies):
1318 for (pdict, handler) in _proxy_cache:
1319 if pdict == proxies:
1320 if DEBUG: DEBUG.debug('re-using proxy settings: %s', proxies)
1321 break
1322 else:
1323 for k, v in proxies.items():
1324 utype, url = urllib.splittype(v)
1325 host, other = urllib.splithost(url)
1326 if (utype is None) or (host is None):
1327 raise URLGrabError(13, _('Bad proxy URL: %s') % v)
1328
1329 if DEBUG: DEBUG.info('creating new proxy handler: %s', proxies)
1330 handler = urllib2.ProxyHandler(proxies)
1331 _proxy_cache.append( (proxies, handler) )
1332 return handler
1333
1334#####################################################################
1335# DEPRECATED FUNCTIONS
1336def set_throttle(new_throttle):
1337 """Deprecated. Use: default_grabber.throttle = new_throttle"""
1338 default_grabber.throttle = new_throttle
1339
1340def set_bandwidth(new_bandwidth):
1341 """Deprecated. Use: default_grabber.bandwidth = new_bandwidth"""
1342 default_grabber.bandwidth = new_bandwidth
1343
1344def set_progress_obj(new_progress_obj):
1345 """Deprecated. Use: default_grabber.progress_obj = new_progress_obj"""
1346 default_grabber.progress_obj = new_progress_obj
1347
1348def set_user_agent(new_user_agent):
1349 """Deprecated. Use: default_grabber.user_agent = new_user_agent"""
1350 default_grabber.user_agent = new_user_agent
1351
1352def retrygrab(url, filename=None, copy_local=0, close_connection=0,
1353 progress_obj=None, throttle=None, bandwidth=None,
1354 numtries=3, retrycodes=[-1,2,4,5,6,7], checkfunc=None):
1355 """Deprecated. Use: urlgrab() with the retry arg instead"""
1356 kwargs = {'copy_local' : copy_local,
1357 'close_connection' : close_connection,
1358 'progress_obj' : progress_obj,
1359 'throttle' : throttle,
1360 'bandwidth' : bandwidth,
1361 'retry' : numtries,
1362 'retrycodes' : retrycodes,
1363 'checkfunc' : checkfunc
1364 }
1365 return urlgrab(url, filename, **kwargs)
1366
1367
1368#####################################################################
1369# TESTING
1370def _main_test():
1371 import sys
1372 try: url, filename = sys.argv[1:3]
1373 except ValueError:
1374 print 'usage:', sys.argv[0], \
1375 '<url> <filename> [copy_local=0|1] [close_connection=0|1]'
1376 sys.exit()
1377
1378 kwargs = {}
1379 for a in sys.argv[3:]:
1380 k, v = string.split(a, '=', 1)
1381 kwargs[k] = int(v)
1382
1383 set_throttle(1.0)
1384 set_bandwidth(32 * 1024)
1385 print "throttle: %s, throttle bandwidth: %s B/s" % (default_grabber.throttle,
1386 default_grabber.bandwidth)
1387
1388 try: from progress import text_progress_meter
1389 except ImportError, e: pass
1390 else: kwargs['progress_obj'] = text_progress_meter()
1391
1392 try: name = apply(urlgrab, (url, filename), kwargs)
1393 except URLGrabError, e: print e
1394 else: print 'LOCAL FILE:', name
1395
1396
1397def _retry_test():
1398 import sys
1399 try: url, filename = sys.argv[1:3]
1400 except ValueError:
1401 print 'usage:', sys.argv[0], \
1402 '<url> <filename> [copy_local=0|1] [close_connection=0|1]'
1403 sys.exit()
1404
1405 kwargs = {}
1406 for a in sys.argv[3:]:
1407 k, v = string.split(a, '=', 1)
1408 kwargs[k] = int(v)
1409
1410 try: from progress import text_progress_meter
1411 except ImportError, e: pass
1412 else: kwargs['progress_obj'] = text_progress_meter()
1413
1414 def cfunc(filename, hello, there='foo'):
1415 print hello, there
1416 import random
1417 rnum = random.random()
1418 if rnum < .5:
1419 print 'forcing retry'
1420 raise URLGrabError(-1, 'forcing retry')
1421 if rnum < .75:
1422 print 'forcing failure'
1423 raise URLGrabError(-2, 'forcing immediate failure')
1424 print 'success'
1425 return
1426
1427 kwargs['checkfunc'] = (cfunc, ('hello',), {'there':'there'})
1428 try: name = apply(retrygrab, (url, filename), kwargs)
1429 except URLGrabError, e: print e
1430 else: print 'LOCAL FILE:', name
1431
1432def _file_object_test(filename=None):
1433 import random, cStringIO, sys
1434 if filename is None:
1435 filename = __file__
1436 print 'using file "%s" for comparisons' % filename
1437 fo = open(filename)
1438 s_input = fo.read()
1439 fo.close()
1440
1441 for testfunc in [_test_file_object_smallread,
1442 _test_file_object_readall,
1443 _test_file_object_readline,
1444 _test_file_object_readlines]:
1445 fo_input = cStringIO.StringIO(s_input)
1446 fo_output = cStringIO.StringIO()
1447 wrapper = URLGrabberFileObject(fo_input, None, 0)
1448 print 'testing %-30s ' % testfunc.__name__,
1449 testfunc(wrapper, fo_output)
1450 s_output = fo_output.getvalue()
1451 if s_output == s_input: print 'passed'
1452 else: print 'FAILED'
1453
1454def _test_file_object_smallread(wrapper, fo_output):
1455 while 1:
1456 s = wrapper.read(23)
1457 fo_output.write(s)
1458 if not s: return
1459
1460def _test_file_object_readall(wrapper, fo_output):
1461 s = wrapper.read()
1462 fo_output.write(s)
1463
1464def _test_file_object_readline(wrapper, fo_output):
1465 while 1:
1466 s = wrapper.readline()
1467 fo_output.write(s)
1468 if not s: return
1469
1470def _test_file_object_readlines(wrapper, fo_output):
1471 li = wrapper.readlines()
1472 fo_output.write(string.join(li, ''))
1473
1474if __name__ == '__main__':
1475 _main_test()
1476 _retry_test()
1477 _file_object_test('test')
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/keepalive.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/keepalive.py
new file mode 100644
index 0000000000..71393e2b8d
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/keepalive.py
@@ -0,0 +1,617 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
19
20"""An HTTP handler for urllib2 that supports HTTP 1.1 and keepalive.
21
22>>> import urllib2
23>>> from keepalive import HTTPHandler
24>>> keepalive_handler = HTTPHandler()
25>>> opener = urllib2.build_opener(keepalive_handler)
26>>> urllib2.install_opener(opener)
27>>>
28>>> fo = urllib2.urlopen('http://www.python.org')
29
30If a connection to a given host is requested, and all of the existing
31connections are still in use, another connection will be opened. If
32the handler tries to use an existing connection but it fails in some
33way, it will be closed and removed from the pool.
34
35To remove the handler, simply re-run build_opener with no arguments, and
36install that opener.
37
38You can explicitly close connections by using the close_connection()
39method of the returned file-like object (described below) or you can
40use the handler methods:
41
42 close_connection(host)
43 close_all()
44 open_connections()
45
46NOTE: using the close_connection and close_all methods of the handler
47should be done with care when using multiple threads.
48 * there is nothing that prevents another thread from creating new
49 connections immediately after connections are closed
50 * no checks are done to prevent in-use connections from being closed
51
52>>> keepalive_handler.close_all()
53
54EXTRA ATTRIBUTES AND METHODS
55
56 Upon a status of 200, the object returned has a few additional
57 attributes and methods, which should not be used if you want to
58 remain consistent with the normal urllib2-returned objects:
59
60 close_connection() - close the connection to the host
61 readlines() - you know, readlines()
62 status - the return status (ie 404)
63 reason - english translation of status (ie 'File not found')
64
65 If you want the best of both worlds, use this inside an
66 AttributeError-catching try:
67
68 >>> try: status = fo.status
69 >>> except AttributeError: status = None
70
71 Unfortunately, these are ONLY there if status == 200, so it's not
72 easy to distinguish between non-200 responses. The reason is that
73 urllib2 tries to do clever things with error codes 301, 302, 401,
74 and 407, and it wraps the object upon return.
75
76 For python versions earlier than 2.4, you can avoid this fancy error
77 handling by setting the module-level global HANDLE_ERRORS to zero.
78 You see, prior to 2.4, it's the HTTP Handler's job to determine what
79 to handle specially, and what to just pass up. HANDLE_ERRORS == 0
80 means "pass everything up". In python 2.4, however, this job no
81 longer belongs to the HTTP Handler and is now done by a NEW handler,
82 HTTPErrorProcessor. Here's the bottom line:
83
84 python version < 2.4
85 HANDLE_ERRORS == 1 (default) pass up 200, treat the rest as
86 errors
87 HANDLE_ERRORS == 0 pass everything up, error processing is
88 left to the calling code
89 python version >= 2.4
90 HANDLE_ERRORS == 1 pass up 200, treat the rest as errors
91 HANDLE_ERRORS == 0 (default) pass everything up, let the
92 other handlers (specifically,
93 HTTPErrorProcessor) decide what to do
94
95 In practice, setting the variable either way makes little difference
96 in python 2.4, so for the most consistent behavior across versions,
97 you probably just want to use the defaults, which will give you
98 exceptions on errors.
99
100"""
101
102# $Id: keepalive.py,v 1.16 2006/09/22 00:58:05 mstenner Exp $
103
104import urllib2
105import httplib
106import socket
107import thread
108
109DEBUG = None
110
111import sslfactory
112
113import sys
114if sys.version_info < (2, 4): HANDLE_ERRORS = 1
115else: HANDLE_ERRORS = 0
116
117class ConnectionManager:
118 """
119 The connection manager must be able to:
120 * keep track of all existing
121 """
122 def __init__(self):
123 self._lock = thread.allocate_lock()
124 self._hostmap = {} # map hosts to a list of connections
125 self._connmap = {} # map connections to host
126 self._readymap = {} # map connection to ready state
127
128 def add(self, host, connection, ready):
129 self._lock.acquire()
130 try:
131 if not self._hostmap.has_key(host): self._hostmap[host] = []
132 self._hostmap[host].append(connection)
133 self._connmap[connection] = host
134 self._readymap[connection] = ready
135 finally:
136 self._lock.release()
137
138 def remove(self, connection):
139 self._lock.acquire()
140 try:
141 try:
142 host = self._connmap[connection]
143 except KeyError:
144 pass
145 else:
146 del self._connmap[connection]
147 del self._readymap[connection]
148 self._hostmap[host].remove(connection)
149 if not self._hostmap[host]: del self._hostmap[host]
150 finally:
151 self._lock.release()
152
153 def set_ready(self, connection, ready):
154 try: self._readymap[connection] = ready
155 except KeyError: pass
156
157 def get_ready_conn(self, host):
158 conn = None
159 self._lock.acquire()
160 try:
161 if self._hostmap.has_key(host):
162 for c in self._hostmap[host]:
163 if self._readymap[c]:
164 self._readymap[c] = 0
165 conn = c
166 break
167 finally:
168 self._lock.release()
169 return conn
170
171 def get_all(self, host=None):
172 if host:
173 return list(self._hostmap.get(host, []))
174 else:
175 return dict(self._hostmap)
176
177class KeepAliveHandler:
178 def __init__(self):
179 self._cm = ConnectionManager()
180
181 #### Connection Management
182 def open_connections(self):
183 """return a list of connected hosts and the number of connections
184 to each. [('foo.com:80', 2), ('bar.org', 1)]"""
185 return [(host, len(li)) for (host, li) in self._cm.get_all().items()]
186
187 def close_connection(self, host):
188 """close connection(s) to <host>
189 host is the host:port spec, as in 'www.cnn.com:8080' as passed in.
190 no error occurs if there is no connection to that host."""
191 for h in self._cm.get_all(host):
192 self._cm.remove(h)
193 h.close()
194
195 def close_all(self):
196 """close all open connections"""
197 for host, conns in self._cm.get_all().items():
198 for h in conns:
199 self._cm.remove(h)
200 h.close()
201
202 def _request_closed(self, request, host, connection):
203 """tells us that this request is now closed and the the
204 connection is ready for another request"""
205 self._cm.set_ready(connection, 1)
206
207 def _remove_connection(self, host, connection, close=0):
208 if close: connection.close()
209 self._cm.remove(connection)
210
211 #### Transaction Execution
212 def do_open(self, req):
213 host = req.get_host()
214 if not host:
215 raise urllib2.URLError('no host given')
216
217 try:
218 h = self._cm.get_ready_conn(host)
219 while h:
220 r = self._reuse_connection(h, req, host)
221
222 # if this response is non-None, then it worked and we're
223 # done. Break out, skipping the else block.
224 if r: break
225
226 # connection is bad - possibly closed by server
227 # discard it and ask for the next free connection
228 h.close()
229 self._cm.remove(h)
230 h = self._cm.get_ready_conn(host)
231 else:
232 # no (working) free connections were found. Create a new one.
233 h = self._get_connection(host)
234 if DEBUG: DEBUG.info("creating new connection to %s (%d)",
235 host, id(h))
236 self._cm.add(host, h, 0)
237 self._start_transaction(h, req)
238 r = h.getresponse()
239 except (socket.error, httplib.HTTPException), err:
240 raise urllib2.URLError(err)
241
242 # if not a persistent connection, don't try to reuse it
243 if r.will_close: self._cm.remove(h)
244
245 if DEBUG: DEBUG.info("STATUS: %s, %s", r.status, r.reason)
246 r._handler = self
247 r._host = host
248 r._url = req.get_full_url()
249 r._connection = h
250 r.code = r.status
251 r.headers = r.msg
252 r.msg = r.reason
253
254 if r.status == 200 or not HANDLE_ERRORS:
255 return r
256 else:
257 return self.parent.error('http', req, r,
258 r.status, r.msg, r.headers)
259
260 def _reuse_connection(self, h, req, host):
261 """start the transaction with a re-used connection
262 return a response object (r) upon success or None on failure.
263 This DOES not close or remove bad connections in cases where
264 it returns. However, if an unexpected exception occurs, it
265 will close and remove the connection before re-raising.
266 """
267 try:
268 self._start_transaction(h, req)
269 r = h.getresponse()
270 # note: just because we got something back doesn't mean it
271 # worked. We'll check the version below, too.
272 except (socket.error, httplib.HTTPException):
273 r = None
274 except:
275 # adding this block just in case we've missed
276 # something we will still raise the exception, but
277 # lets try and close the connection and remove it
278 # first. We previously got into a nasty loop
279 # where an exception was uncaught, and so the
280 # connection stayed open. On the next try, the
281 # same exception was raised, etc. The tradeoff is
282 # that it's now possible this call will raise
283 # a DIFFERENT exception
284 if DEBUG: DEBUG.error("unexpected exception - closing " + \
285 "connection to %s (%d)", host, id(h))
286 self._cm.remove(h)
287 h.close()
288 raise
289
290 if r is None or r.version == 9:
291 # httplib falls back to assuming HTTP 0.9 if it gets a
292 # bad header back. This is most likely to happen if
293 # the socket has been closed by the server since we
294 # last used the connection.
295 if DEBUG: DEBUG.info("failed to re-use connection to %s (%d)",
296 host, id(h))
297 r = None
298 else:
299 if DEBUG: DEBUG.info("re-using connection to %s (%d)", host, id(h))
300
301 return r
302
303 def _start_transaction(self, h, req):
304 try:
305 if req.has_data():
306 data = req.get_data()
307 h.putrequest('POST', req.get_selector())
308 if not req.headers.has_key('Content-type'):
309 h.putheader('Content-type',
310 'application/x-www-form-urlencoded')
311 if not req.headers.has_key('Content-length'):
312 h.putheader('Content-length', '%d' % len(data))
313 else:
314 h.putrequest('GET', req.get_selector())
315 except (socket.error, httplib.HTTPException), err:
316 raise urllib2.URLError(err)
317
318 for args in self.parent.addheaders:
319 h.putheader(*args)
320 for k, v in req.headers.items():
321 h.putheader(k, v)
322 h.endheaders()
323 if req.has_data():
324 h.send(data)
325
326 def _get_connection(self, host):
327 return NotImplementedError
328
329class HTTPHandler(KeepAliveHandler, urllib2.HTTPHandler):
330 def __init__(self):
331 KeepAliveHandler.__init__(self)
332
333 def http_open(self, req):
334 return self.do_open(req)
335
336 def _get_connection(self, host):
337 return HTTPConnection(host)
338
339class HTTPSHandler(KeepAliveHandler, urllib2.HTTPSHandler):
340 def __init__(self, ssl_factory=None):
341 KeepAliveHandler.__init__(self)
342 if not ssl_factory:
343 ssl_factory = sslfactory.get_factory()
344 self._ssl_factory = ssl_factory
345
346 def https_open(self, req):
347 return self.do_open(req)
348
349 def _get_connection(self, host):
350 return self._ssl_factory.get_https_connection(host)
351
352class HTTPResponse(httplib.HTTPResponse):
353 # we need to subclass HTTPResponse in order to
354 # 1) add readline() and readlines() methods
355 # 2) add close_connection() methods
356 # 3) add info() and geturl() methods
357
358 # in order to add readline(), read must be modified to deal with a
359 # buffer. example: readline must read a buffer and then spit back
360 # one line at a time. The only real alternative is to read one
361 # BYTE at a time (ick). Once something has been read, it can't be
362 # put back (ok, maybe it can, but that's even uglier than this),
363 # so if you THEN do a normal read, you must first take stuff from
364 # the buffer.
365
366 # the read method wraps the original to accomodate buffering,
367 # although read() never adds to the buffer.
368 # Both readline and readlines have been stolen with almost no
369 # modification from socket.py
370
371
372 def __init__(self, sock, debuglevel=0, strict=0, method=None):
373 if method: # the httplib in python 2.3 uses the method arg
374 httplib.HTTPResponse.__init__(self, sock, debuglevel, method)
375 else: # 2.2 doesn't
376 httplib.HTTPResponse.__init__(self, sock, debuglevel)
377 self.fileno = sock.fileno
378 self.code = None
379 self._rbuf = ''
380 self._rbufsize = 8096
381 self._handler = None # inserted by the handler later
382 self._host = None # (same)
383 self._url = None # (same)
384 self._connection = None # (same)
385
386 _raw_read = httplib.HTTPResponse.read
387
388 def close(self):
389 if self.fp:
390 self.fp.close()
391 self.fp = None
392 if self._handler:
393 self._handler._request_closed(self, self._host,
394 self._connection)
395
396 def close_connection(self):
397 self._handler._remove_connection(self._host, self._connection, close=1)
398 self.close()
399
400 def info(self):
401 return self.headers
402
403 def geturl(self):
404 return self._url
405
406 def read(self, amt=None):
407 # the _rbuf test is only in this first if for speed. It's not
408 # logically necessary
409 if self._rbuf and not amt is None:
410 L = len(self._rbuf)
411 if amt > L:
412 amt -= L
413 else:
414 s = self._rbuf[:amt]
415 self._rbuf = self._rbuf[amt:]
416 return s
417
418 s = self._rbuf + self._raw_read(amt)
419 self._rbuf = ''
420 return s
421
422 def readline(self, limit=-1):
423 data = ""
424 i = self._rbuf.find('\n')
425 while i < 0 and not (0 < limit <= len(self._rbuf)):
426 new = self._raw_read(self._rbufsize)
427 if not new: break
428 i = new.find('\n')
429 if i >= 0: i = i + len(self._rbuf)
430 self._rbuf = self._rbuf + new
431 if i < 0: i = len(self._rbuf)
432 else: i = i+1
433 if 0 <= limit < len(self._rbuf): i = limit
434 data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
435 return data
436
437 def readlines(self, sizehint = 0):
438 total = 0
439 list = []
440 while 1:
441 line = self.readline()
442 if not line: break
443 list.append(line)
444 total += len(line)
445 if sizehint and total >= sizehint:
446 break
447 return list
448
449
450class HTTPConnection(httplib.HTTPConnection):
451 # use the modified response class
452 response_class = HTTPResponse
453
454class HTTPSConnection(httplib.HTTPSConnection):
455 response_class = HTTPResponse
456
457#########################################################################
458##### TEST FUNCTIONS
459#########################################################################
460
461def error_handler(url):
462 global HANDLE_ERRORS
463 orig = HANDLE_ERRORS
464 keepalive_handler = HTTPHandler()
465 opener = urllib2.build_opener(keepalive_handler)
466 urllib2.install_opener(opener)
467 pos = {0: 'off', 1: 'on'}
468 for i in (0, 1):
469 print " fancy error handling %s (HANDLE_ERRORS = %i)" % (pos[i], i)
470 HANDLE_ERRORS = i
471 try:
472 fo = urllib2.urlopen(url)
473 foo = fo.read()
474 fo.close()
475 try: status, reason = fo.status, fo.reason
476 except AttributeError: status, reason = None, None
477 except IOError, e:
478 print " EXCEPTION: %s" % e
479 raise
480 else:
481 print " status = %s, reason = %s" % (status, reason)
482 HANDLE_ERRORS = orig
483 hosts = keepalive_handler.open_connections()
484 print "open connections:", hosts
485 keepalive_handler.close_all()
486
487def continuity(url):
488 import md5
489 format = '%25s: %s'
490
491 # first fetch the file with the normal http handler
492 opener = urllib2.build_opener()
493 urllib2.install_opener(opener)
494 fo = urllib2.urlopen(url)
495 foo = fo.read()
496 fo.close()
497 m = md5.new(foo)
498 print format % ('normal urllib', m.hexdigest())
499
500 # now install the keepalive handler and try again
501 opener = urllib2.build_opener(HTTPHandler())
502 urllib2.install_opener(opener)
503
504 fo = urllib2.urlopen(url)
505 foo = fo.read()
506 fo.close()
507 m = md5.new(foo)
508 print format % ('keepalive read', m.hexdigest())
509
510 fo = urllib2.urlopen(url)
511 foo = ''
512 while 1:
513 f = fo.readline()
514 if f: foo = foo + f
515 else: break
516 fo.close()
517 m = md5.new(foo)
518 print format % ('keepalive readline', m.hexdigest())
519
520def comp(N, url):
521 print ' making %i connections to:\n %s' % (N, url)
522
523 sys.stdout.write(' first using the normal urllib handlers')
524 # first use normal opener
525 opener = urllib2.build_opener()
526 urllib2.install_opener(opener)
527 t1 = fetch(N, url)
528 print ' TIME: %.3f s' % t1
529
530 sys.stdout.write(' now using the keepalive handler ')
531 # now install the keepalive handler and try again
532 opener = urllib2.build_opener(HTTPHandler())
533 urllib2.install_opener(opener)
534 t2 = fetch(N, url)
535 print ' TIME: %.3f s' % t2
536 print ' improvement factor: %.2f' % (t1/t2, )
537
538def fetch(N, url, delay=0):
539 import time
540 lens = []
541 starttime = time.time()
542 for i in range(N):
543 if delay and i > 0: time.sleep(delay)
544 fo = urllib2.urlopen(url)
545 foo = fo.read()
546 fo.close()
547 lens.append(len(foo))
548 diff = time.time() - starttime
549
550 j = 0
551 for i in lens[1:]:
552 j = j + 1
553 if not i == lens[0]:
554 print "WARNING: inconsistent length on read %i: %i" % (j, i)
555
556 return diff
557
558def test_timeout(url):
559 global DEBUG
560 dbbackup = DEBUG
561 class FakeLogger:
562 def debug(self, msg, *args): print msg % args
563 info = warning = error = debug
564 DEBUG = FakeLogger()
565 print " fetching the file to establish a connection"
566 fo = urllib2.urlopen(url)
567 data1 = fo.read()
568 fo.close()
569
570 i = 20
571 print " waiting %i seconds for the server to close the connection" % i
572 while i > 0:
573 sys.stdout.write('\r %2i' % i)
574 sys.stdout.flush()
575 time.sleep(1)
576 i -= 1
577 sys.stderr.write('\r')
578
579 print " fetching the file a second time"
580 fo = urllib2.urlopen(url)
581 data2 = fo.read()
582 fo.close()
583
584 if data1 == data2:
585 print ' data are identical'
586 else:
587 print ' ERROR: DATA DIFFER'
588
589 DEBUG = dbbackup
590
591
592def test(url, N=10):
593 print "checking error hander (do this on a non-200)"
594 try: error_handler(url)
595 except IOError, e:
596 print "exiting - exception will prevent further tests"
597 sys.exit()
598 print
599 print "performing continuity test (making sure stuff isn't corrupted)"
600 continuity(url)
601 print
602 print "performing speed comparison"
603 comp(N, url)
604 print
605 print "performing dropped-connection check"
606 test_timeout(url)
607
608if __name__ == '__main__':
609 import time
610 import sys
611 try:
612 N = int(sys.argv[1])
613 url = sys.argv[2]
614 except:
615 print "%s <integer> <url>" % sys.argv[0]
616 else:
617 test(url, N)
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/mirror.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/mirror.py
new file mode 100644
index 0000000000..9664c6b5c5
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/mirror.py
@@ -0,0 +1,458 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
19
20"""Module for downloading files from a pool of mirrors
21
22DESCRIPTION
23
24 This module provides support for downloading files from a pool of
25 mirrors with configurable failover policies. To a large extent, the
26 failover policy is chosen by using different classes derived from
27 the main class, MirrorGroup.
28
29 Instances of MirrorGroup (and cousins) act very much like URLGrabber
30 instances in that they have urlread, urlgrab, and urlopen methods.
31 They can therefore, be used in very similar ways.
32
33 from urlgrabber.grabber import URLGrabber
34 from urlgrabber.mirror import MirrorGroup
35 gr = URLGrabber()
36 mg = MirrorGroup(gr, ['http://foo.com/some/directory/',
37 'http://bar.org/maybe/somewhere/else/',
38 'ftp://baz.net/some/other/place/entirely/']
39 mg.urlgrab('relative/path.zip')
40
41 The assumption is that all mirrors are identical AFTER the base urls
42 specified, so that any mirror can be used to fetch any file.
43
44FAILOVER
45
46 The failover mechanism is designed to be customized by subclassing
47 from MirrorGroup to change the details of the behavior. In general,
48 the classes maintain a master mirror list and a "current mirror"
49 index. When a download is initiated, a copy of this list and index
50 is created for that download only. The specific failover policy
51 depends on the class used, and so is documented in the class
52 documentation. Note that ANY behavior of the class can be
53 overridden, so any failover policy at all is possible (although
54 you may need to change the interface in extreme cases).
55
56CUSTOMIZATION
57
58 Most customization of a MirrorGroup object is done at instantiation
59 time (or via subclassing). There are four major types of
60 customization:
61
62 1) Pass in a custom urlgrabber - The passed in urlgrabber will be
63 used (by default... see #2) for the grabs, so options to it
64 apply for the url-fetching
65
66 2) Custom mirror list - Mirror lists can simply be a list of
67 stings mirrors (as shown in the example above) but each can
68 also be a dict, allowing for more options. For example, the
69 first mirror in the list above could also have been:
70
71 {'mirror': 'http://foo.com/some/directory/',
72 'grabber': <a custom grabber to be used for this mirror>,
73 'kwargs': { <a dict of arguments passed to the grabber> }}
74
75 All mirrors are converted to this format internally. If
76 'grabber' is omitted, the default grabber will be used. If
77 kwargs are omitted, then (duh) they will not be used.
78
79 3) Pass keyword arguments when instantiating the mirror group.
80 See, for example, the failure_callback argument.
81
82 4) Finally, any kwargs passed in for the specific file (to the
83 urlgrab method, for example) will be folded in. The options
84 passed into the grabber's urlXXX methods will override any
85 options specified in a custom mirror dict.
86
87"""
88
89# $Id: mirror.py,v 1.14 2006/02/22 18:26:46 mstenner Exp $
90
91import random
92import thread # needed for locking to make this threadsafe
93
94from grabber import URLGrabError, CallbackObject, DEBUG
95
96try:
97 from i18n import _
98except ImportError, msg:
99 def _(st): return st
100
101class GrabRequest:
102 """This is a dummy class used to hold information about the specific
103 request. For example, a single file. By maintaining this information
104 separately, we can accomplish two things:
105
106 1) make it a little easier to be threadsafe
107 2) have request-specific parameters
108 """
109 pass
110
111class MirrorGroup:
112 """Base Mirror class
113
114 Instances of this class are built with a grabber object and a list
115 of mirrors. Then all calls to urlXXX should be passed relative urls.
116 The requested file will be searched for on the first mirror. If the
117 grabber raises an exception (possibly after some retries) then that
118 mirror will be removed from the list, and the next will be attempted.
119 If all mirrors are exhausted, then an exception will be raised.
120
121 MirrorGroup has the following failover policy:
122
123 * downloads begin with the first mirror
124
125 * by default (see default_action below) a failure (after retries)
126 causes it to increment the local AND master indices. Also,
127 the current mirror is removed from the local list (but NOT the
128 master list - the mirror can potentially be used for other
129 files)
130
131 * if the local list is ever exhausted, a URLGrabError will be
132 raised (errno=256, no more mirrors)
133
134 OPTIONS
135
136 In addition to the required arguments "grabber" and "mirrors",
137 MirrorGroup also takes the following optional arguments:
138
139 default_action
140
141 A dict that describes the actions to be taken upon failure
142 (after retries). default_action can contain any of the
143 following keys (shown here with their default values):
144
145 default_action = {'increment': 1,
146 'increment_master': 1,
147 'remove': 1,
148 'remove_master': 0,
149 'fail': 0}
150
151 In this context, 'increment' means "use the next mirror" and
152 'remove' means "never use this mirror again". The two
153 'master' values refer to the instance-level mirror list (used
154 for all files), whereas the non-master values refer to the
155 current download only.
156
157 The 'fail' option will cause immediate failure by re-raising
158 the exception and no further attempts to get the current
159 download.
160
161 This dict can be set at instantiation time,
162 mg = MirrorGroup(grabber, mirrors, default_action={'fail':1})
163 at method-execution time (only applies to current fetch),
164 filename = mg.urlgrab(url, default_action={'increment': 0})
165 or by returning an action dict from the failure_callback
166 return {'fail':0}
167 in increasing precedence.
168
169 If all three of these were done, the net result would be:
170 {'increment': 0, # set in method
171 'increment_master': 1, # class default
172 'remove': 1, # class default
173 'remove_master': 0, # class default
174 'fail': 0} # set at instantiation, reset
175 # from callback
176
177 failure_callback
178
179 this is a callback that will be called when a mirror "fails",
180 meaning the grabber raises some URLGrabError. If this is a
181 tuple, it is interpreted to be of the form (cb, args, kwargs)
182 where cb is the actual callable object (function, method,
183 etc). Otherwise, it is assumed to be the callable object
184 itself. The callback will be passed a grabber.CallbackObject
185 instance along with args and kwargs (if present). The following
186 attributes are defined withing the instance:
187
188 obj.exception = < exception that was raised >
189 obj.mirror = < the mirror that was tried >
190 obj.relative_url = < url relative to the mirror >
191 obj.url = < full url that failed >
192 # .url is just the combination of .mirror
193 # and .relative_url
194
195 The failure callback can return an action dict, as described
196 above.
197
198 Like default_action, the failure_callback can be set at
199 instantiation time or when the urlXXX method is called. In
200 the latter case, it applies only for that fetch.
201
202 The callback can re-raise the exception quite easily. For
203 example, this is a perfectly adequate callback function:
204
205 def callback(obj): raise obj.exception
206
207 WARNING: do not save the exception object (or the
208 CallbackObject instance). As they contain stack frame
209 references, they can lead to circular references.
210
211 Notes:
212 * The behavior can be customized by deriving and overriding the
213 'CONFIGURATION METHODS'
214 * The 'grabber' instance is kept as a reference, not copied.
215 Therefore, the grabber instance can be modified externally
216 and changes will take effect immediately.
217 """
218
219 # notes on thread-safety:
220
221 # A GrabRequest should never be shared by multiple threads because
222 # it's never saved inside the MG object and never returned outside it.
223 # therefore, it should be safe to access/modify grabrequest data
224 # without a lock. However, accessing the mirrors and _next attributes
225 # of the MG itself must be done when locked to prevent (for example)
226 # removal of the wrong mirror.
227
228 ##############################################################
229 # CONFIGURATION METHODS - intended to be overridden to
230 # customize behavior
231 def __init__(self, grabber, mirrors, **kwargs):
232 """Initialize the MirrorGroup object.
233
234 REQUIRED ARGUMENTS
235
236 grabber - URLGrabber instance
237 mirrors - a list of mirrors
238
239 OPTIONAL ARGUMENTS
240
241 failure_callback - callback to be used when a mirror fails
242 default_action - dict of failure actions
243
244 See the module-level and class level documentation for more
245 details.
246 """
247
248 # OVERRIDE IDEAS:
249 # shuffle the list to randomize order
250 self.grabber = grabber
251 self.mirrors = self._parse_mirrors(mirrors)
252 self._next = 0
253 self._lock = thread.allocate_lock()
254 self.default_action = None
255 self._process_kwargs(kwargs)
256
257 # if these values are found in **kwargs passed to one of the urlXXX
258 # methods, they will be stripped before getting passed on to the
259 # grabber
260 options = ['default_action', 'failure_callback']
261
262 def _process_kwargs(self, kwargs):
263 self.failure_callback = kwargs.get('failure_callback')
264 self.default_action = kwargs.get('default_action')
265
266 def _parse_mirrors(self, mirrors):
267 parsed_mirrors = []
268 for m in mirrors:
269 if type(m) == type(''): m = {'mirror': m}
270 parsed_mirrors.append(m)
271 return parsed_mirrors
272
273 def _load_gr(self, gr):
274 # OVERRIDE IDEAS:
275 # shuffle gr list
276 self._lock.acquire()
277 gr.mirrors = list(self.mirrors)
278 gr._next = self._next
279 self._lock.release()
280
281 def _get_mirror(self, gr):
282 # OVERRIDE IDEAS:
283 # return a random mirror so that multiple mirrors get used
284 # even without failures.
285 if not gr.mirrors:
286 raise URLGrabError(256, _('No more mirrors to try.'))
287 return gr.mirrors[gr._next]
288
289 def _failure(self, gr, cb_obj):
290 # OVERRIDE IDEAS:
291 # inspect the error - remove=1 for 404, remove=2 for connection
292 # refused, etc. (this can also be done via
293 # the callback)
294 cb = gr.kw.get('failure_callback') or self.failure_callback
295 if cb:
296 if type(cb) == type( () ):
297 cb, args, kwargs = cb
298 else:
299 args, kwargs = (), {}
300 action = cb(cb_obj, *args, **kwargs) or {}
301 else:
302 action = {}
303 # XXXX - decide - there are two ways to do this
304 # the first is action-overriding as a whole - use the entire action
305 # or fall back on module level defaults
306 #action = action or gr.kw.get('default_action') or self.default_action
307 # the other is to fall through for each element in the action dict
308 a = dict(self.default_action or {})
309 a.update(gr.kw.get('default_action', {}))
310 a.update(action)
311 action = a
312 self.increment_mirror(gr, action)
313 if action and action.get('fail', 0): raise
314
315 def increment_mirror(self, gr, action={}):
316 """Tell the mirror object increment the mirror index
317
318 This increments the mirror index, which amounts to telling the
319 mirror object to use a different mirror (for this and future
320 downloads).
321
322 This is a SEMI-public method. It will be called internally,
323 and you may never need to call it. However, it is provided
324 (and is made public) so that the calling program can increment
325 the mirror choice for methods like urlopen. For example, with
326 urlopen, there's no good way for the mirror group to know that
327 an error occurs mid-download (it's already returned and given
328 you the file object).
329
330 remove --- can have several values
331 0 do not remove the mirror from the list
332 1 remove the mirror for this download only
333 2 remove the mirror permanently
334
335 beware of remove=0 as it can lead to infinite loops
336 """
337 badmirror = gr.mirrors[gr._next]
338
339 self._lock.acquire()
340 try:
341 ind = self.mirrors.index(badmirror)
342 except ValueError:
343 pass
344 else:
345 if action.get('remove_master', 0):
346 del self.mirrors[ind]
347 elif self._next == ind and action.get('increment_master', 1):
348 self._next += 1
349 if self._next >= len(self.mirrors): self._next = 0
350 self._lock.release()
351
352 if action.get('remove', 1):
353 del gr.mirrors[gr._next]
354 elif action.get('increment', 1):
355 gr._next += 1
356 if gr._next >= len(gr.mirrors): gr._next = 0
357
358 if DEBUG:
359 grm = [m['mirror'] for m in gr.mirrors]
360 DEBUG.info('GR mirrors: [%s] %i', ' '.join(grm), gr._next)
361 selfm = [m['mirror'] for m in self.mirrors]
362 DEBUG.info('MAIN mirrors: [%s] %i', ' '.join(selfm), self._next)
363
364 #####################################################################
365 # NON-CONFIGURATION METHODS
366 # these methods are designed to be largely workhorse methods that
367 # are not intended to be overridden. That doesn't mean you can't;
368 # if you want to, feel free, but most things can be done by
369 # by overriding the configuration methods :)
370
371 def _join_url(self, base_url, rel_url):
372 if base_url.endswith('/') or rel_url.startswith('/'):
373 return base_url + rel_url
374 else:
375 return base_url + '/' + rel_url
376
377 def _mirror_try(self, func, url, kw):
378 gr = GrabRequest()
379 gr.func = func
380 gr.url = url
381 gr.kw = dict(kw)
382 self._load_gr(gr)
383
384 for k in self.options:
385 try: del kw[k]
386 except KeyError: pass
387
388 while 1:
389 mirrorchoice = self._get_mirror(gr)
390 fullurl = self._join_url(mirrorchoice['mirror'], gr.url)
391 kwargs = dict(mirrorchoice.get('kwargs', {}))
392 kwargs.update(kw)
393 grabber = mirrorchoice.get('grabber') or self.grabber
394 func_ref = getattr(grabber, func)
395 if DEBUG: DEBUG.info('MIRROR: trying %s -> %s', url, fullurl)
396 try:
397 return func_ref( *(fullurl,), **kwargs )
398 except URLGrabError, e:
399 if DEBUG: DEBUG.info('MIRROR: failed')
400 obj = CallbackObject()
401 obj.exception = e
402 obj.mirror = mirrorchoice['mirror']
403 obj.relative_url = gr.url
404 obj.url = fullurl
405 self._failure(gr, obj)
406
407 def urlgrab(self, url, filename=None, **kwargs):
408 kw = dict(kwargs)
409 kw['filename'] = filename
410 func = 'urlgrab'
411 return self._mirror_try(func, url, kw)
412
413 def urlopen(self, url, **kwargs):
414 kw = dict(kwargs)
415 func = 'urlopen'
416 return self._mirror_try(func, url, kw)
417
418 def urlread(self, url, limit=None, **kwargs):
419 kw = dict(kwargs)
420 kw['limit'] = limit
421 func = 'urlread'
422 return self._mirror_try(func, url, kw)
423
424
425class MGRandomStart(MirrorGroup):
426 """A mirror group that starts at a random mirror in the list.
427
428 This behavior of this class is identical to MirrorGroup, except that
429 it starts at a random location in the mirror list.
430 """
431
432 def __init__(self, grabber, mirrors, **kwargs):
433 """Initialize the object
434
435 The arguments for intialization are the same as for MirrorGroup
436 """
437 MirrorGroup.__init__(self, grabber, mirrors, **kwargs)
438 self._next = random.randrange(len(mirrors))
439
440class MGRandomOrder(MirrorGroup):
441 """A mirror group that uses mirrors in a random order.
442
443 This behavior of this class is identical to MirrorGroup, except that
444 it uses the mirrors in a random order. Note that the order is set at
445 initialization time and fixed thereafter. That is, it does not pick a
446 random mirror after each failure.
447 """
448
449 def __init__(self, grabber, mirrors, **kwargs):
450 """Initialize the object
451
452 The arguments for intialization are the same as for MirrorGroup
453 """
454 MirrorGroup.__init__(self, grabber, mirrors, **kwargs)
455 random.shuffle(self.mirrors)
456
457if __name__ == '__main__':
458 pass
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/progress.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/progress.py
new file mode 100644
index 0000000000..02db524e76
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/progress.py
@@ -0,0 +1,530 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18# Copyright 2002-2004 Michael D. Stenner, Ryan Tomayko
19
20# $Id: progress.py,v 1.7 2005/08/19 21:59:07 mstenner Exp $
21
22import sys
23import time
24import math
25import thread
26
27class BaseMeter:
28 def __init__(self):
29 self.update_period = 0.3 # seconds
30
31 self.filename = None
32 self.url = None
33 self.basename = None
34 self.text = None
35 self.size = None
36 self.start_time = None
37 self.last_amount_read = 0
38 self.last_update_time = None
39 self.re = RateEstimator()
40
41 def start(self, filename=None, url=None, basename=None,
42 size=None, now=None, text=None):
43 self.filename = filename
44 self.url = url
45 self.basename = basename
46 self.text = text
47
48 #size = None ######### TESTING
49 self.size = size
50 if not size is None: self.fsize = format_number(size) + 'B'
51
52 if now is None: now = time.time()
53 self.start_time = now
54 self.re.start(size, now)
55 self.last_amount_read = 0
56 self.last_update_time = now
57 self._do_start(now)
58
59 def _do_start(self, now=None):
60 pass
61
62 def update(self, amount_read, now=None):
63 # for a real gui, you probably want to override and put a call
64 # to your mainloop iteration function here
65 if now is None: now = time.time()
66 if (now >= self.last_update_time + self.update_period) or \
67 not self.last_update_time:
68 self.re.update(amount_read, now)
69 self.last_amount_read = amount_read
70 self.last_update_time = now
71 self._do_update(amount_read, now)
72
73 def _do_update(self, amount_read, now=None):
74 pass
75
76 def end(self, amount_read, now=None):
77 if now is None: now = time.time()
78 self.re.update(amount_read, now)
79 self.last_amount_read = amount_read
80 self.last_update_time = now
81 self._do_end(amount_read, now)
82
83 def _do_end(self, amount_read, now=None):
84 pass
85
86class TextMeter(BaseMeter):
87 def __init__(self, fo=sys.stderr):
88 BaseMeter.__init__(self)
89 self.fo = fo
90
91 def _do_update(self, amount_read, now=None):
92 etime = self.re.elapsed_time()
93 fetime = format_time(etime)
94 fread = format_number(amount_read)
95 #self.size = None
96 if self.text is not None:
97 text = self.text
98 else:
99 text = self.basename
100 if self.size is None:
101 out = '\r%-60.60s %5sB %s ' % \
102 (text, fread, fetime)
103 else:
104 rtime = self.re.remaining_time()
105 frtime = format_time(rtime)
106 frac = self.re.fraction_read()
107 bar = '='*int(25 * frac)
108
109 out = '\r%-25.25s %3i%% |%-25.25s| %5sB %8s ETA ' % \
110 (text, frac*100, bar, fread, frtime)
111
112 self.fo.write(out)
113 self.fo.flush()
114
115 def _do_end(self, amount_read, now=None):
116 total_time = format_time(self.re.elapsed_time())
117 total_size = format_number(amount_read)
118 if self.text is not None:
119 text = self.text
120 else:
121 text = self.basename
122 if self.size is None:
123 out = '\r%-60.60s %5sB %s ' % \
124 (text, total_size, total_time)
125 else:
126 bar = '='*25
127 out = '\r%-25.25s %3i%% |%-25.25s| %5sB %8s ' % \
128 (text, 100, bar, total_size, total_time)
129 self.fo.write(out + '\n')
130 self.fo.flush()
131
132text_progress_meter = TextMeter
133
134class MultiFileHelper(BaseMeter):
135 def __init__(self, master):
136 BaseMeter.__init__(self)
137 self.master = master
138
139 def _do_start(self, now):
140 self.master.start_meter(self, now)
141
142 def _do_update(self, amount_read, now):
143 # elapsed time since last update
144 self.master.update_meter(self, now)
145
146 def _do_end(self, amount_read, now):
147 self.ftotal_time = format_time(now - self.start_time)
148 self.ftotal_size = format_number(self.last_amount_read)
149 self.master.end_meter(self, now)
150
151 def failure(self, message, now=None):
152 self.master.failure_meter(self, message, now)
153
154 def message(self, message):
155 self.master.message_meter(self, message)
156
157class MultiFileMeter:
158 helperclass = MultiFileHelper
159 def __init__(self):
160 self.meters = []
161 self.in_progress_meters = []
162 self._lock = thread.allocate_lock()
163 self.update_period = 0.3 # seconds
164
165 self.numfiles = None
166 self.finished_files = 0
167 self.failed_files = 0
168 self.open_files = 0
169 self.total_size = None
170 self.failed_size = 0
171 self.start_time = None
172 self.finished_file_size = 0
173 self.last_update_time = None
174 self.re = RateEstimator()
175
176 def start(self, numfiles=None, total_size=None, now=None):
177 if now is None: now = time.time()
178 self.numfiles = numfiles
179 self.finished_files = 0
180 self.failed_files = 0
181 self.open_files = 0
182 self.total_size = total_size
183 self.failed_size = 0
184 self.start_time = now
185 self.finished_file_size = 0
186 self.last_update_time = now
187 self.re.start(total_size, now)
188 self._do_start(now)
189
190 def _do_start(self, now):
191 pass
192
193 def end(self, now=None):
194 if now is None: now = time.time()
195 self._do_end(now)
196
197 def _do_end(self, now):
198 pass
199
200 def lock(self): self._lock.acquire()
201 def unlock(self): self._lock.release()
202
203 ###########################################################
204 # child meter creation and destruction
205 def newMeter(self):
206 newmeter = self.helperclass(self)
207 self.meters.append(newmeter)
208 return newmeter
209
210 def removeMeter(self, meter):
211 self.meters.remove(meter)
212
213 ###########################################################
214 # child functions - these should only be called by helpers
215 def start_meter(self, meter, now):
216 if not meter in self.meters:
217 raise ValueError('attempt to use orphaned meter')
218 self._lock.acquire()
219 try:
220 if not meter in self.in_progress_meters:
221 self.in_progress_meters.append(meter)
222 self.open_files += 1
223 finally:
224 self._lock.release()
225 self._do_start_meter(meter, now)
226
227 def _do_start_meter(self, meter, now):
228 pass
229
230 def update_meter(self, meter, now):
231 if not meter in self.meters:
232 raise ValueError('attempt to use orphaned meter')
233 if (now >= self.last_update_time + self.update_period) or \
234 not self.last_update_time:
235 self.re.update(self._amount_read(), now)
236 self.last_update_time = now
237 self._do_update_meter(meter, now)
238
239 def _do_update_meter(self, meter, now):
240 pass
241
242 def end_meter(self, meter, now):
243 if not meter in self.meters:
244 raise ValueError('attempt to use orphaned meter')
245 self._lock.acquire()
246 try:
247 try: self.in_progress_meters.remove(meter)
248 except ValueError: pass
249 self.open_files -= 1
250 self.finished_files += 1
251 self.finished_file_size += meter.last_amount_read
252 finally:
253 self._lock.release()
254 self._do_end_meter(meter, now)
255
256 def _do_end_meter(self, meter, now):
257 pass
258
259 def failure_meter(self, meter, message, now):
260 if not meter in self.meters:
261 raise ValueError('attempt to use orphaned meter')
262 self._lock.acquire()
263 try:
264 try: self.in_progress_meters.remove(meter)
265 except ValueError: pass
266 self.open_files -= 1
267 self.failed_files += 1
268 if meter.size and self.failed_size is not None:
269 self.failed_size += meter.size
270 else:
271 self.failed_size = None
272 finally:
273 self._lock.release()
274 self._do_failure_meter(meter, message, now)
275
276 def _do_failure_meter(self, meter, message, now):
277 pass
278
279 def message_meter(self, meter, message):
280 pass
281
282 ########################################################
283 # internal functions
284 def _amount_read(self):
285 tot = self.finished_file_size
286 for m in self.in_progress_meters:
287 tot += m.last_amount_read
288 return tot
289
290
291class TextMultiFileMeter(MultiFileMeter):
292 def __init__(self, fo=sys.stderr):
293 self.fo = fo
294 MultiFileMeter.__init__(self)
295
296 # files: ###/### ###% data: ######/###### ###% time: ##:##:##/##:##:##
297 def _do_update_meter(self, meter, now):
298 self._lock.acquire()
299 try:
300 format = "files: %3i/%-3i %3i%% data: %6.6s/%-6.6s %3i%% " \
301 "time: %8.8s/%8.8s"
302 df = self.finished_files
303 tf = self.numfiles or 1
304 pf = 100 * float(df)/tf + 0.49
305 dd = self.re.last_amount_read
306 td = self.total_size
307 pd = 100 * (self.re.fraction_read() or 0) + 0.49
308 dt = self.re.elapsed_time()
309 rt = self.re.remaining_time()
310 if rt is None: tt = None
311 else: tt = dt + rt
312
313 fdd = format_number(dd) + 'B'
314 ftd = format_number(td) + 'B'
315 fdt = format_time(dt, 1)
316 ftt = format_time(tt, 1)
317
318 out = '%-79.79s' % (format % (df, tf, pf, fdd, ftd, pd, fdt, ftt))
319 self.fo.write('\r' + out)
320 self.fo.flush()
321 finally:
322 self._lock.release()
323
324 def _do_end_meter(self, meter, now):
325 self._lock.acquire()
326 try:
327 format = "%-30.30s %6.6s %8.8s %9.9s"
328 fn = meter.basename
329 size = meter.last_amount_read
330 fsize = format_number(size) + 'B'
331 et = meter.re.elapsed_time()
332 fet = format_time(et, 1)
333 frate = format_number(size / et) + 'B/s'
334
335 out = '%-79.79s' % (format % (fn, fsize, fet, frate))
336 self.fo.write('\r' + out + '\n')
337 finally:
338 self._lock.release()
339 self._do_update_meter(meter, now)
340
341 def _do_failure_meter(self, meter, message, now):
342 self._lock.acquire()
343 try:
344 format = "%-30.30s %6.6s %s"
345 fn = meter.basename
346 if type(message) in (type(''), type(u'')):
347 message = message.splitlines()
348 if not message: message = ['']
349 out = '%-79s' % (format % (fn, 'FAILED', message[0] or ''))
350 self.fo.write('\r' + out + '\n')
351 for m in message[1:]: self.fo.write(' ' + m + '\n')
352 self._lock.release()
353 finally:
354 self._do_update_meter(meter, now)
355
356 def message_meter(self, meter, message):
357 self._lock.acquire()
358 try:
359 pass
360 finally:
361 self._lock.release()
362
363 def _do_end(self, now):
364 self._do_update_meter(None, now)
365 self._lock.acquire()
366 try:
367 self.fo.write('\n')
368 self.fo.flush()
369 finally:
370 self._lock.release()
371
372######################################################################
373# support classes and functions
374
375class RateEstimator:
376 def __init__(self, timescale=5.0):
377 self.timescale = timescale
378
379 def start(self, total=None, now=None):
380 if now is None: now = time.time()
381 self.total = total
382 self.start_time = now
383 self.last_update_time = now
384 self.last_amount_read = 0
385 self.ave_rate = None
386
387 def update(self, amount_read, now=None):
388 if now is None: now = time.time()
389 if amount_read == 0:
390 # if we just started this file, all bets are off
391 self.last_update_time = now
392 self.last_amount_read = 0
393 self.ave_rate = None
394 return
395
396 #print 'times', now, self.last_update_time
397 time_diff = now - self.last_update_time
398 read_diff = amount_read - self.last_amount_read
399 self.last_update_time = now
400 self.last_amount_read = amount_read
401 self.ave_rate = self._temporal_rolling_ave(\
402 time_diff, read_diff, self.ave_rate, self.timescale)
403 #print 'results', time_diff, read_diff, self.ave_rate
404
405 #####################################################################
406 # result methods
407 def average_rate(self):
408 "get the average transfer rate (in bytes/second)"
409 return self.ave_rate
410
411 def elapsed_time(self):
412 "the time between the start of the transfer and the most recent update"
413 return self.last_update_time - self.start_time
414
415 def remaining_time(self):
416 "estimated time remaining"
417 if not self.ave_rate or not self.total: return None
418 return (self.total - self.last_amount_read) / self.ave_rate
419
420 def fraction_read(self):
421 """the fraction of the data that has been read
422 (can be None for unknown transfer size)"""
423 if self.total is None: return None
424 elif self.total == 0: return 1.0
425 else: return float(self.last_amount_read)/self.total
426
427 #########################################################################
428 # support methods
429 def _temporal_rolling_ave(self, time_diff, read_diff, last_ave, timescale):
430 """a temporal rolling average performs smooth averaging even when
431 updates come at irregular intervals. This is performed by scaling
432 the "epsilon" according to the time since the last update.
433 Specifically, epsilon = time_diff / timescale
434
435 As a general rule, the average will take on a completely new value
436 after 'timescale' seconds."""
437 epsilon = time_diff / timescale
438 if epsilon > 1: epsilon = 1.0
439 return self._rolling_ave(time_diff, read_diff, last_ave, epsilon)
440
441 def _rolling_ave(self, time_diff, read_diff, last_ave, epsilon):
442 """perform a "rolling average" iteration
443 a rolling average "folds" new data into an existing average with
444 some weight, epsilon. epsilon must be between 0.0 and 1.0 (inclusive)
445 a value of 0.0 means only the old value (initial value) counts,
446 and a value of 1.0 means only the newest value is considered."""
447
448 try:
449 recent_rate = read_diff / time_diff
450 except ZeroDivisionError:
451 recent_rate = None
452 if last_ave is None: return recent_rate
453 elif recent_rate is None: return last_ave
454
455 # at this point, both last_ave and recent_rate are numbers
456 return epsilon * recent_rate + (1 - epsilon) * last_ave
457
458 def _round_remaining_time(self, rt, start_time=15.0):
459 """round the remaining time, depending on its size
460 If rt is between n*start_time and (n+1)*start_time round downward
461 to the nearest multiple of n (for any counting number n).
462 If rt < start_time, round down to the nearest 1.
463 For example (for start_time = 15.0):
464 2.7 -> 2.0
465 25.2 -> 25.0
466 26.4 -> 26.0
467 35.3 -> 34.0
468 63.6 -> 60.0
469 """
470
471 if rt < 0: return 0.0
472 shift = int(math.log(rt/start_time)/math.log(2))
473 rt = int(rt)
474 if shift <= 0: return rt
475 return float(int(rt) >> shift << shift)
476
477
478def format_time(seconds, use_hours=0):
479 if seconds is None or seconds < 0:
480 if use_hours: return '--:--:--'
481 else: return '--:--'
482 else:
483 seconds = int(seconds)
484 minutes = seconds / 60
485 seconds = seconds % 60
486 if use_hours:
487 hours = minutes / 60
488 minutes = minutes % 60
489 return '%02i:%02i:%02i' % (hours, minutes, seconds)
490 else:
491 return '%02i:%02i' % (minutes, seconds)
492
493def format_number(number, SI=0, space=' '):
494 """Turn numbers into human-readable metric-like numbers"""
495 symbols = ['', # (none)
496 'k', # kilo
497 'M', # mega
498 'G', # giga
499 'T', # tera
500 'P', # peta
501 'E', # exa
502 'Z', # zetta
503 'Y'] # yotta
504
505 if SI: step = 1000.0
506 else: step = 1024.0
507
508 thresh = 999
509 depth = 0
510 max_depth = len(symbols) - 1
511
512 # we want numbers between 0 and thresh, but don't exceed the length
513 # of our list. In that event, the formatting will be screwed up,
514 # but it'll still show the right number.
515 while number > thresh and depth < max_depth:
516 depth = depth + 1
517 number = number / step
518
519 if type(number) == type(1) or type(number) == type(1L):
520 # it's an int or a long, which means it didn't get divided,
521 # which means it's already short enough
522 format = '%i%s%s'
523 elif number < 9.95:
524 # must use 9.95 for proper sizing. For example, 9.99 will be
525 # rounded to 10.0 with the .1f format string (which is too long)
526 format = '%.1f%s%s'
527 else:
528 format = '%.0f%s%s'
529
530 return(format % (float(number or 0), space, symbols[depth]))
diff --git a/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/sslfactory.py b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/sslfactory.py
new file mode 100644
index 0000000000..07848dac7c
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/urlgrabber/sslfactory.py
@@ -0,0 +1,90 @@
1# This library is free software; you can redistribute it and/or
2# modify it under the terms of the GNU Lesser General Public
3# License as published by the Free Software Foundation; either
4# version 2.1 of the License, or (at your option) any later version.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the
13# Free Software Foundation, Inc.,
14# 59 Temple Place, Suite 330,
15# Boston, MA 02111-1307 USA
16
17# This file is part of urlgrabber, a high-level cross-protocol url-grabber
18
19import httplib
20import urllib2
21
22try:
23 from M2Crypto import SSL
24 from M2Crypto import httpslib
25 from M2Crypto import m2urllib2
26
27 SSL.Connection.clientPostConnectionCheck = None
28 have_m2crypto = True
29except ImportError:
30 have_m2crypto = False
31
32DEBUG = None
33
34if have_m2crypto:
35
36 class M2SSLFactory:
37
38 def __init__(self, ssl_ca_cert, ssl_context):
39 self.ssl_context = self._get_ssl_context(ssl_ca_cert, ssl_context)
40
41 def _get_ssl_context(self, ssl_ca_cert, ssl_context):
42 """
43 Create an ssl context using the CA cert file or ssl context.
44
45 The CA cert is used first if it was passed as an option. If not,
46 then the supplied ssl context is used. If no ssl context was supplied,
47 None is returned.
48 """
49 if ssl_ca_cert:
50 context = SSL.Context()
51 context.load_verify_locations(ssl_ca_cert)
52 context.set_verify(SSL.verify_none, -1)
53 return context
54 else:
55 return ssl_context
56
57 def create_https_connection(self, host, response_class = None):
58 connection = httplib.HTTPSConnection(host, self.ssl_context)
59 if response_class:
60 connection.response_class = response_class
61 return connection
62
63 def create_opener(self, *handlers):
64 return m2urllib2.build_opener(self.ssl_context, *handlers)
65
66
67class SSLFactory:
68
69 def create_https_connection(self, host, response_class = None):
70 connection = httplib.HTTPSConnection(host)
71 if response_class:
72 connection.response_class = response_class
73 return connection
74
75 def create_opener(self, *handlers):
76 return urllib2.build_opener(*handlers)
77
78
79
80def get_factory(ssl_ca_cert = None, ssl_context = None):
81 """ Return an SSLFactory, based on if M2Crypto is available. """
82 if have_m2crypto:
83 return M2SSLFactory(ssl_ca_cert, ssl_context)
84 else:
85 # Log here if someone provides the args but we don't use them.
86 if ssl_ca_cert or ssl_context:
87 if DEBUG:
88 DEBUG.warning("SSL arguments supplied, but M2Crypto is not available. "
89 "Using Python SSL.")
90 return SSLFactory()
diff --git a/scripts/lib/mic/3rdparty/pykickstart/version.py b/scripts/lib/mic/3rdparty/pykickstart/version.py
new file mode 100644
index 0000000000..102cc37d80
--- /dev/null
+++ b/scripts/lib/mic/3rdparty/pykickstart/version.py
@@ -0,0 +1,197 @@
1#
2# Chris Lumens <clumens@redhat.com>
3#
4# Copyright 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
5#
6# This copyrighted material is made available to anyone wishing to use, modify,
7# copy, or redistribute it subject to the terms and conditions of the GNU
8# General Public License v.2. This program is distributed in the hope that it
9# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
10# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11# See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with
14# this program; if not, write to the Free Software Foundation, Inc., 51
15# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat
16# trademarks that are incorporated in the source code or documentation are not
17# subject to the GNU General Public License and may only be used or replicated
18# with the express permission of Red Hat, Inc.
19#
20"""
21Methods for working with kickstart versions.
22
23This module defines several symbolic constants that specify kickstart syntax
24versions. Each version corresponds roughly to one release of Red Hat Linux,
25Red Hat Enterprise Linux, or Fedora Core as these are where most syntax
26changes take place.
27
28This module also exports several functions:
29
30 makeVersion - Given a version number, return an instance of the
31 matching handler class.
32
33 returnClassForVersion - Given a version number, return the matching
34 handler class. This does not return an
35 instance of that class, however.
36
37 stringToVersion - Convert a string representation of a version number
38 into the symbolic constant.
39
40 versionToString - Perform the reverse mapping.
41
42 versionFromFile - Read a kickstart file and determine the version of
43 syntax it uses. This requires the kickstart file to
44 have a version= comment in it.
45"""
46import imputil, re, sys
47from urlgrabber import urlopen
48
49import gettext
50_ = lambda x: gettext.ldgettext("pykickstart", x)
51
52from pykickstart.errors import KickstartVersionError
53
54# Symbolic names for internal version numbers.
55RHEL3 = 900
56FC3 = 1000
57RHEL4 = 1100
58FC4 = 2000
59FC5 = 3000
60FC6 = 4000
61RHEL5 = 4100
62F7 = 5000
63F8 = 6000
64F9 = 7000
65F10 = 8000
66F11 = 9000
67F12 = 10000
68F13 = 11000
69RHEL6 = 11100
70F14 = 12000
71F15 = 13000
72F16 = 14000
73
74# This always points at the latest version and is the default.
75DEVEL = F16
76
77# A one-to-one mapping from string representations to version numbers.
78versionMap = {
79 "DEVEL": DEVEL,
80 "FC3": FC3, "FC4": FC4, "FC5": FC5, "FC6": FC6, "F7": F7, "F8": F8,
81 "F9": F9, "F10": F10, "F11": F11, "F12": F12, "F13": F13,
82 "F14": F14, "F15": F15, "F16": F16,
83 "RHEL3": RHEL3, "RHEL4": RHEL4, "RHEL5": RHEL5, "RHEL6": RHEL6
84}
85
86def stringToVersion(s):
87 """Convert string into one of the provided version constants. Raises
88 KickstartVersionError if string does not match anything.
89 """
90 # First try these short forms.
91 try:
92 return versionMap[s.upper()]
93 except KeyError:
94 pass
95
96 # Now try the Fedora versions.
97 m = re.match("^fedora.* (\d+)$", s, re.I)
98
99 if m and m.group(1):
100 if versionMap.has_key("FC" + m.group(1)):
101 return versionMap["FC" + m.group(1)]
102 elif versionMap.has_key("F" + m.group(1)):
103 return versionMap["F" + m.group(1)]
104 else:
105 raise KickstartVersionError(_("Unsupported version specified: %s") % s)
106
107 # Now try the RHEL versions.
108 m = re.match("^red hat enterprise linux.* (\d+)([\.\d]*)$", s, re.I)
109
110 if m and m.group(1):
111 if versionMap.has_key("RHEL" + m.group(1)):
112 return versionMap["RHEL" + m.group(1)]
113 else:
114 raise KickstartVersionError(_("Unsupported version specified: %s") % s)
115
116 # If nothing else worked, we're out of options.
117 raise KickstartVersionError(_("Unsupported version specified: %s") % s)
118
119def versionToString(version, skipDevel=False):
120 """Convert version into a string representation of the version number.
121 This is the reverse operation of stringToVersion. Raises
122 KickstartVersionError if version does not match anything.
123 """
124 if not skipDevel and version == versionMap["DEVEL"]:
125 return "DEVEL"
126
127 for (key, val) in versionMap.iteritems():
128 if key == "DEVEL":
129 continue
130 elif val == version:
131 return key
132
133 raise KickstartVersionError(_("Unsupported version specified: %s") % version)
134
135def versionFromFile(f):
136 """Given a file or URL, look for a line starting with #version= and
137 return the version number. If no version is found, return DEVEL.
138 """
139 v = DEVEL
140
141 fh = urlopen(f)
142
143 while True:
144 try:
145 l = fh.readline()
146 except StopIteration:
147 break
148
149 # At the end of the file?
150 if l == "":
151 break
152
153 if l.isspace() or l.strip() == "":
154 continue
155
156 if l[:9] == "#version=":
157 v = stringToVersion(l[9:].rstrip())
158 break
159
160 fh.close()
161 return v
162
163def returnClassForVersion(version=DEVEL):
164 """Return the class of the syntax handler for version. version can be
165 either a string or the matching constant. Raises KickstartValueError
166 if version does not match anything.
167 """
168 try:
169 version = int(version)
170 module = "%s" % versionToString(version, skipDevel=True)
171 except ValueError:
172 module = "%s" % version
173 version = stringToVersion(version)
174
175 module = module.lower()
176
177 try:
178 import pykickstart.handlers
179 sys.path.extend(pykickstart.handlers.__path__)
180 found = imputil.imp.find_module(module)
181 loaded = imputil.imp.load_module(module, found[0], found[1], found[2])
182
183 for (k, v) in loaded.__dict__.iteritems():
184 if k.lower().endswith("%shandler" % module):
185 return v
186 except:
187 raise KickstartVersionError(_("Unsupported version specified: %s") % version)
188
189def makeVersion(version=DEVEL):
190 """Return a new instance of the syntax handler for version. version can be
191 either a string or the matching constant. This function is useful for
192 standalone programs which just need to handle a specific version of
193 kickstart syntax (as provided by a command line argument, for example)
194 and need to instantiate the correct object.
195 """
196 cl = returnClassForVersion(version)
197 return cl()
diff --git a/scripts/lib/mic/__init__.py b/scripts/lib/mic/__init__.py
new file mode 100644
index 0000000000..63c1d9c846
--- /dev/null
+++ b/scripts/lib/mic/__init__.py
@@ -0,0 +1,4 @@
1import os, sys
2
3cur_path = os.path.dirname(__file__) or '.'
4sys.path.insert(0, cur_path + '/3rdparty')
diff --git a/scripts/lib/mic/__version__.py b/scripts/lib/mic/__version__.py
new file mode 100644
index 0000000000..60d7626cac
--- /dev/null
+++ b/scripts/lib/mic/__version__.py
@@ -0,0 +1 @@
VERSION = "0.14"
diff --git a/scripts/lib/mic/bootstrap.py b/scripts/lib/mic/bootstrap.py
new file mode 100644
index 0000000000..66c291b0a8
--- /dev/null
+++ b/scripts/lib/mic/bootstrap.py
@@ -0,0 +1,279 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from __future__ import with_statement
19import os
20import sys
21import tempfile
22import shutil
23import subprocess
24import rpm
25from mic import msger
26from mic.utils import errors, proxy, misc
27from mic.utils.rpmmisc import readRpmHeader, RPMInstallCallback
28from mic.chroot import cleanup_mounts, setup_chrootenv, cleanup_chrootenv
29
30PATH_BOOTSTRAP = "/usr/sbin:/usr/bin:/sbin:/bin"
31
32RPMTRANS_FLAGS = [
33 rpm.RPMTRANS_FLAG_ALLFILES,
34 rpm.RPMTRANS_FLAG_NOSCRIPTS,
35 rpm.RPMTRANS_FLAG_NOTRIGGERS,
36 ]
37
38RPMVSF_FLAGS = [
39 rpm._RPMVSF_NOSIGNATURES,
40 rpm._RPMVSF_NODIGESTS
41 ]
42
43RPMPROB_FLAGS = [
44 rpm.RPMPROB_FILTER_OLDPACKAGE,
45 rpm.RPMPROB_FILTER_REPLACEPKG,
46 rpm.RPMPROB_FILTER_IGNOREARCH
47 ]
48
49class MiniBackend(object):
50 def __init__(self, rootdir, arch=None, repomd=None):
51 self._ts = None
52 self.rootdir = os.path.abspath(rootdir)
53 self.arch = arch
54 self.repomd = repomd
55 self.dlpkgs = []
56 self.localpkgs = {}
57 self.optionals = []
58 self.preins = {}
59 self.postins = {}
60 self.scriptlets = False
61
62 def __del__(self):
63 try:
64 del self.ts
65 except:
66 pass
67
68 def get_ts(self):
69 if not self._ts:
70 self._ts = rpm.TransactionSet(self.rootdir)
71 self._ts.setFlags(reduce(lambda x, y: x|y, RPMTRANS_FLAGS))
72 self._ts.setVSFlags(reduce(lambda x, y: x|y, RPMVSF_FLAGS))
73 self._ts.setProbFilter(reduce(lambda x, y: x|y, RPMPROB_FLAGS))
74
75 return self._ts
76
77 def del_ts(self):
78 if self._ts:
79 self._ts.closeDB()
80 self._ts = None
81
82 ts = property(fget = lambda self: self.get_ts(),
83 fdel = lambda self: self.del_ts(),
84 doc="TransactionSet object")
85
86 def selectPackage(self, pkg):
87 if not pkg in self.dlpkgs:
88 self.dlpkgs.append(pkg)
89
90 def runInstall(self):
91 # FIXME: check space
92 self.downloadPkgs()
93 self.installPkgs()
94
95 if not self.scriptlets:
96 return
97
98 for pkg in self.preins.keys():
99 prog, script = self.preins[pkg]
100 self.run_pkg_script(pkg, prog, script, '0')
101 for pkg in self.postins.keys():
102 prog, script = self.postins[pkg]
103 self.run_pkg_script(pkg, prog, script, '1')
104
105 def downloadPkgs(self):
106 nonexist = []
107 for pkg in self.dlpkgs:
108 localpth = misc.get_package(pkg, self.repomd, self.arch)
109 if localpth:
110 self.localpkgs[pkg] = localpth
111 elif pkg in self.optionals:
112 # skip optional rpm
113 continue
114 else:
115 # mark nonexist rpm
116 nonexist.append(pkg)
117
118 if nonexist:
119 raise errors.BootstrapError("Can't get rpm binary: %s" %
120 ','.join(nonexist))
121
122 def installPkgs(self):
123 for pkg in self.localpkgs.keys():
124 rpmpath = self.localpkgs[pkg]
125
126 hdr = readRpmHeader(self.ts, rpmpath)
127
128 # save prein and postin scripts
129 self.preins[pkg] = (hdr['PREINPROG'], hdr['PREIN'])
130 self.postins[pkg] = (hdr['POSTINPROG'], hdr['POSTIN'])
131
132 # mark pkg as install
133 self.ts.addInstall(hdr, rpmpath, 'u')
134
135 # run transaction
136 self.ts.order()
137 cb = RPMInstallCallback(self.ts)
138 self.ts.run(cb.callback, '')
139
140 def run_pkg_script(self, pkg, prog, script, arg):
141 mychroot = lambda: os.chroot(self.rootdir)
142
143 if not script:
144 return
145
146 if prog == "<lua>":
147 prog = "/usr/bin/lua"
148
149 tmpdir = os.path.join(self.rootdir, "tmp")
150 if not os.path.exists(tmpdir):
151 os.makedirs(tmpdir)
152 tmpfd, tmpfp = tempfile.mkstemp(dir=tmpdir, prefix="%s.pre-" % pkg)
153 script = script.replace('\r', '')
154 os.write(tmpfd, script)
155 os.close(tmpfd)
156 os.chmod(tmpfp, 0700)
157
158 try:
159 script_fp = os.path.join('/tmp', os.path.basename(tmpfp))
160 subprocess.call([prog, script_fp, arg], preexec_fn=mychroot)
161 except (OSError, IOError), err:
162 msger.warning(str(err))
163 finally:
164 os.unlink(tmpfp)
165
166class Bootstrap(object):
167 def __init__(self, rootdir, distro, arch=None):
168 self.rootdir = misc.mkdtemp(dir=rootdir, prefix=distro)
169 self.distro = distro
170 self.arch = arch
171 self.logfile = None
172 self.pkgslist = []
173 self.repomd = None
174
175 def __del__(self):
176 self.cleanup()
177
178 def get_rootdir(self):
179 if os.path.exists(self.rootdir):
180 shutil.rmtree(self.rootdir, ignore_errors=True)
181 os.makedirs(self.rootdir)
182 return self.rootdir
183
184 def dirsetup(self, rootdir=None):
185 _path = lambda pth: os.path.join(rootdir, pth.lstrip('/'))
186
187 if not rootdir:
188 rootdir = self.rootdir
189
190 try:
191 # make /tmp and /etc path
192 tmpdir = _path('/tmp')
193 if not os.path.exists(tmpdir):
194 os.makedirs(tmpdir)
195 etcdir = _path('/etc')
196 if not os.path.exists(etcdir):
197 os.makedirs(etcdir)
198
199 # touch distro file
200 tzdist = _path('/etc/%s-release' % self.distro)
201 if not os.path.exists(tzdist):
202 with open(tzdist, 'w') as wf:
203 wf.write("bootstrap")
204 except:
205 pass
206
207 def create(self, repomd, pkglist, optlist=()):
208 try:
209 pkgmgr = MiniBackend(self.get_rootdir())
210 pkgmgr.arch = self.arch
211 pkgmgr.repomd = repomd
212 pkgmgr.optionals = list(optlist)
213 map(pkgmgr.selectPackage, pkglist + list(optlist))
214 pkgmgr.runInstall()
215 except (OSError, IOError, errors.CreatorError), err:
216 raise errors.BootstrapError("%s" % err)
217
218 def run(self, cmd, chdir, rootdir=None, bindmounts=None):
219 def mychroot():
220 os.chroot(rootdir)
221 os.chdir(chdir)
222
223 def sync_timesetting(rootdir):
224 try:
225 # sync time and zone info to bootstrap
226 if os.path.exists(rootdir + "/etc/localtime"):
227 os.unlink(rootdir + "/etc/localtime")
228 shutil.copyfile("/etc/localtime", rootdir + "/etc/localtime")
229 except:
230 pass
231
232 def sync_passwdfile(rootdir):
233 try:
234 # sync passwd file to bootstrap, saving the user info
235 if os.path.exists(rootdir + "/etc/passwd"):
236 os.unlink(rootdir + "/etc/passwd")
237 shutil.copyfile("/etc/passwd", rootdir + "/etc/passwd")
238 except:
239 pass
240
241 if not rootdir:
242 rootdir = self.rootdir
243
244 if isinstance(cmd, list):
245 shell = False
246 else:
247 shell = True
248
249 env = os.environ
250 env['PATH'] = "%s:%s" % (PATH_BOOTSTRAP, env['PATH'])
251
252 retcode = 0
253 gloablmounts = None
254 try:
255 proxy.set_proxy_environ()
256 gloablmounts = setup_chrootenv(rootdir, bindmounts, False)
257 sync_timesetting(rootdir)
258 sync_passwdfile(rootdir)
259 retcode = subprocess.call(cmd, preexec_fn=mychroot, env=env, shell=shell)
260 except (OSError, IOError):
261 # add additional information to original exception
262 value, tb = sys.exc_info()[1:]
263 value = '%s: %s' % (value, ' '.join(cmd))
264 raise RuntimeError, value, tb
265 finally:
266 if self.logfile and os.path.isfile(self.logfile):
267 msger.log(file(self.logfile).read())
268 cleanup_chrootenv(rootdir, bindmounts, gloablmounts)
269 proxy.unset_proxy_environ()
270 return retcode
271
272 def cleanup(self):
273 try:
274 # clean mounts
275 cleanup_mounts(self.rootdir)
276 # remove rootdir
277 shutil.rmtree(self.rootdir, ignore_errors=True)
278 except:
279 pass
diff --git a/scripts/lib/mic/chroot.py b/scripts/lib/mic/chroot.py
new file mode 100644
index 0000000000..99fb9a2c17
--- /dev/null
+++ b/scripts/lib/mic/chroot.py
@@ -0,0 +1,343 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from __future__ import with_statement
19import os
20import shutil
21import subprocess
22
23from mic import msger
24from mic.conf import configmgr
25from mic.utils import misc, errors, runner, fs_related
26
27chroot_lockfd = -1
28chroot_lock = ""
29BIND_MOUNTS = (
30 "/proc",
31 "/proc/sys/fs/binfmt_misc",
32 "/sys",
33 "/dev",
34 "/dev/pts",
35 "/dev/shm",
36 "/var/lib/dbus",
37 "/var/run/dbus",
38 "/var/lock",
39 )
40
41def cleanup_after_chroot(targettype,imgmount,tmpdir,tmpmnt):
42 if imgmount and targettype == "img":
43 imgmount.cleanup()
44
45 if tmpdir:
46 shutil.rmtree(tmpdir, ignore_errors = True)
47
48 if tmpmnt:
49 shutil.rmtree(tmpmnt, ignore_errors = True)
50
51def check_bind_mounts(chrootdir, bindmounts):
52 chrootmounts = []
53 for mount in bindmounts.split(";"):
54 if not mount:
55 continue
56
57 srcdst = mount.split(":")
58 if len(srcdst) == 1:
59 srcdst.append("none")
60
61 if not os.path.isdir(srcdst[0]):
62 return False
63
64 if srcdst[1] == "" or srcdst[1] == "none":
65 srcdst[1] = None
66
67 if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/':
68 continue
69
70 if chrootdir:
71 if not srcdst[1]:
72 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[0]))
73 else:
74 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
75
76 tmpdir = chrootdir + "/" + srcdst[1]
77 if os.path.isdir(tmpdir):
78 msger.warning("Warning: dir %s has existed." % tmpdir)
79
80 return True
81
82def cleanup_mounts(chrootdir):
83 umountcmd = misc.find_binary_path("umount")
84 abs_chrootdir = os.path.abspath(chrootdir)
85 mounts = open('/proc/mounts').readlines()
86 for line in reversed(mounts):
87 if abs_chrootdir not in line:
88 continue
89
90 point = line.split()[1]
91
92 # '/' to avoid common name prefix
93 if abs_chrootdir == point or point.startswith(abs_chrootdir + '/'):
94 args = [ umountcmd, "-l", point ]
95 ret = runner.quiet(args)
96 if ret != 0:
97 msger.warning("failed to unmount %s" % point)
98
99 return 0
100
101def setup_chrootenv(chrootdir, bindmounts = None, mountparent = True):
102 global chroot_lockfd, chroot_lock
103
104 def get_bind_mounts(chrootdir, bindmounts, mountparent = True):
105 chrootmounts = []
106 if bindmounts in ("", None):
107 bindmounts = ""
108
109 for mount in bindmounts.split(";"):
110 if not mount:
111 continue
112
113 srcdst = mount.split(":")
114 srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0]))
115 if len(srcdst) == 1:
116 srcdst.append("none")
117
118 # if some bindmount is not existed, but it's created inside
119 # chroot, this is not expected
120 if not os.path.exists(srcdst[0]):
121 os.makedirs(srcdst[0])
122
123 if not os.path.isdir(srcdst[0]):
124 continue
125
126 if srcdst[0] in BIND_MOUNTS or srcdst[0] == '/':
127 msger.verbose("%s will be mounted by default." % srcdst[0])
128 continue
129
130 if srcdst[1] == "" or srcdst[1] == "none":
131 srcdst[1] = None
132 else:
133 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
134 if os.path.isdir(chrootdir + "/" + srcdst[1]):
135 msger.warning("%s has existed in %s , skip it."\
136 % (srcdst[1], chrootdir))
137 continue
138
139 chrootmounts.append(fs_related.BindChrootMount(srcdst[0],
140 chrootdir,
141 srcdst[1]))
142
143 """Default bind mounts"""
144 for pt in BIND_MOUNTS:
145 if not os.path.exists(pt):
146 continue
147 chrootmounts.append(fs_related.BindChrootMount(pt,
148 chrootdir,
149 None))
150
151 if mountparent:
152 chrootmounts.append(fs_related.BindChrootMount("/",
153 chrootdir,
154 "/parentroot",
155 "ro"))
156
157 for kernel in os.listdir("/lib/modules"):
158 chrootmounts.append(fs_related.BindChrootMount(
159 "/lib/modules/"+kernel,
160 chrootdir,
161 None,
162 "ro"))
163
164 return chrootmounts
165
166 def bind_mount(chrootmounts):
167 for b in chrootmounts:
168 msger.verbose("bind_mount: %s -> %s" % (b.src, b.dest))
169 b.mount()
170
171 def setup_resolv(chrootdir):
172 try:
173 shutil.copyfile("/etc/resolv.conf", chrootdir + "/etc/resolv.conf")
174 except:
175 pass
176
177 globalmounts = get_bind_mounts(chrootdir, bindmounts, mountparent)
178 bind_mount(globalmounts)
179
180 setup_resolv(chrootdir)
181
182 mtab = "/etc/mtab"
183 dstmtab = chrootdir + mtab
184 if not os.path.islink(dstmtab):
185 shutil.copyfile(mtab, dstmtab)
186
187 chroot_lock = os.path.join(chrootdir, ".chroot.lock")
188 chroot_lockfd = open(chroot_lock, "w")
189
190 return globalmounts
191
192def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()):
193 global chroot_lockfd, chroot_lock
194
195 def bind_unmount(chrootmounts):
196 for b in reversed(chrootmounts):
197 msger.verbose("bind_unmount: %s -> %s" % (b.src, b.dest))
198 b.unmount()
199
200 def cleanup_resolv(chrootdir):
201 try:
202 fd = open(chrootdir + "/etc/resolv.conf", "w")
203 fd.truncate(0)
204 fd.close()
205 except:
206 pass
207
208 def kill_processes(chrootdir):
209 import glob
210 for fp in glob.glob("/proc/*/root"):
211 try:
212 if os.readlink(fp) == chrootdir:
213 pid = int(fp.split("/")[2])
214 os.kill(pid, 9)
215 except:
216 pass
217
218 def cleanup_mountdir(chrootdir, bindmounts):
219 if bindmounts == "" or bindmounts == None:
220 return
221 chrootmounts = []
222 for mount in bindmounts.split(";"):
223 if not mount:
224 continue
225
226 srcdst = mount.split(":")
227
228 if len(srcdst) == 1:
229 srcdst.append("none")
230
231 if srcdst[0] == "/":
232 continue
233
234 if srcdst[1] == "" or srcdst[1] == "none":
235 srcdst[1] = srcdst[0]
236
237 srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
238 tmpdir = chrootdir + "/" + srcdst[1]
239 if os.path.isdir(tmpdir):
240 if len(os.listdir(tmpdir)) == 0:
241 shutil.rmtree(tmpdir, ignore_errors = True)
242 else:
243 msger.warning("Warning: dir %s isn't empty." % tmpdir)
244
245 chroot_lockfd.close()
246 bind_unmount(globalmounts)
247
248 if not fs_related.my_fuser(chroot_lock):
249 tmpdir = chrootdir + "/parentroot"
250 if os.path.exists(tmpdir) and len(os.listdir(tmpdir)) == 0:
251 shutil.rmtree(tmpdir, ignore_errors = True)
252
253 cleanup_resolv(chrootdir)
254
255 if os.path.exists(chrootdir + "/etc/mtab"):
256 os.unlink(chrootdir + "/etc/mtab")
257
258 kill_processes(chrootdir)
259
260 cleanup_mountdir(chrootdir, bindmounts)
261
262def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"):
263 def mychroot():
264 os.chroot(chrootdir)
265 os.chdir("/")
266
267 if configmgr.chroot['saveto']:
268 savefs = True
269 saveto = configmgr.chroot['saveto']
270 wrnmsg = "Can't save chroot fs for dir %s exists" % saveto
271 if saveto == chrootdir:
272 savefs = False
273 wrnmsg = "Dir %s is being used to chroot" % saveto
274 elif os.path.exists(saveto):
275 if msger.ask("Dir %s already exists, cleanup and continue?" %
276 saveto):
277 shutil.rmtree(saveto, ignore_errors = True)
278 savefs = True
279 else:
280 savefs = False
281
282 if savefs:
283 msger.info("Saving image to directory %s" % saveto)
284 fs_related.makedirs(os.path.dirname(os.path.abspath(saveto)))
285 runner.quiet("cp -af %s %s" % (chrootdir, saveto))
286 devs = ['dev/fd',
287 'dev/stdin',
288 'dev/stdout',
289 'dev/stderr',
290 'etc/mtab']
291 ignlst = [os.path.join(saveto, x) for x in devs]
292 map(os.unlink, filter(os.path.exists, ignlst))
293 else:
294 msger.warning(wrnmsg)
295
296 dev_null = os.open("/dev/null", os.O_WRONLY)
297 files_to_check = ["/bin/bash", "/sbin/init"]
298
299 architecture_found = False
300
301 """ Register statically-linked qemu-arm if it is an ARM fs """
302 qemu_emulator = None
303
304 for ftc in files_to_check:
305 ftc = "%s/%s" % (chrootdir,ftc)
306
307 # Return code of 'file' is "almost always" 0 based on some man pages
308 # so we need to check the file existance first.
309 if not os.path.exists(ftc):
310 continue
311
312 for line in runner.outs(['file', ftc]).splitlines():
313 if 'ARM' in line:
314 qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm")
315 architecture_found = True
316 break
317
318 if 'Intel' in line:
319 architecture_found = True
320 break
321
322 if architecture_found:
323 break
324
325 os.close(dev_null)
326 if not architecture_found:
327 raise errors.CreatorError("Failed to get architecture from any of the "
328 "following files %s from chroot." \
329 % files_to_check)
330
331 try:
332 msger.info("Launching shell. Exit to continue.\n"
333 "----------------------------------")
334 globalmounts = setup_chrootenv(chrootdir, bindmounts)
335 subprocess.call(execute, preexec_fn = mychroot, shell=True)
336
337 except OSError, err:
338 raise errors.CreatorError("chroot err: %s" % str(err))
339
340 finally:
341 cleanup_chrootenv(chrootdir, bindmounts, globalmounts)
342 if qemu_emulator:
343 os.unlink(chrootdir + qemu_emulator)
diff --git a/scripts/lib/mic/conf.py b/scripts/lib/mic/conf.py
new file mode 100644
index 0000000000..b850d80520
--- /dev/null
+++ b/scripts/lib/mic/conf.py
@@ -0,0 +1,197 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys, re
19import ConfigParser
20
21from mic import msger
22from mic import kickstart
23from mic.utils import misc, runner, proxy, errors
24
25
26def get_siteconf():
27 mic_path = os.path.dirname(__file__)
28 eos = mic_path.find('scripts') + len('scripts')
29 scripts_path = mic_path[:eos]
30
31 return scripts_path + "/lib/image/config/wic.conf"
32
33class ConfigMgr(object):
34 prefer_backends = ["zypp", "yum"]
35
36 DEFAULTS = {'common': {
37 "distro_name": "Default Distribution",
38 "plugin_dir": "/usr/lib/wic/plugins", # TODO use prefix also?
39 },
40 'create': {
41 "tmpdir": '/var/tmp/wic',
42 "cachedir": '/var/tmp/wic/cache',
43 "outdir": './wic-output',
44
45 "arch": None, # None means auto-detect
46 "pkgmgr": "auto",
47 "name": "output",
48 "ksfile": None,
49 "ks": None,
50 "repomd": None,
51 "local_pkgs_path": None,
52 "release": None,
53 "logfile": None,
54 "record_pkgs": [],
55 "pack_to": None,
56 "name_prefix": None,
57 "name_suffix": None,
58 "proxy": None,
59 "no_proxy": None,
60 "copy_kernel": False,
61 "install_pkgs": None,
62 "repourl": {},
63 "localrepos": [], # save localrepos
64 "runtime": "bootstrap",
65 },
66 'chroot': {
67 "saveto": None,
68 },
69 'convert': {
70 "shell": False,
71 },
72 'bootstrap': {
73 "rootdir": '/var/tmp/wic-bootstrap',
74 "packages": [],
75 },
76 }
77
78 # make the manager class as singleton
79 _instance = None
80 def __new__(cls, *args, **kwargs):
81 if not cls._instance:
82 cls._instance = super(ConfigMgr, cls).__new__(cls, *args, **kwargs)
83
84 return cls._instance
85
86 def __init__(self, ksconf=None, siteconf=None):
87 # reset config options
88 self.reset()
89
90 if not siteconf:
91 siteconf = get_siteconf()
92
93 # initial options from siteconf
94 self._siteconf = siteconf
95
96 if ksconf:
97 self._ksconf = ksconf
98
99 def reset(self):
100 self.__ksconf = None
101 self.__siteconf = None
102
103 # initialize the values with defaults
104 for sec, vals in self.DEFAULTS.iteritems():
105 setattr(self, sec, vals)
106
107 def __set_siteconf(self, siteconf):
108 try:
109 self.__siteconf = siteconf
110 self._parse_siteconf(siteconf)
111 except ConfigParser.Error, error:
112 raise errors.ConfigError("%s" % error)
113 def __get_siteconf(self):
114 return self.__siteconf
115 _siteconf = property(__get_siteconf, __set_siteconf)
116
117 def __set_ksconf(self, ksconf):
118 if not os.path.isfile(ksconf):
119 msger.error('Cannot find ks file: %s' % ksconf)
120
121 self.__ksconf = ksconf
122 self._parse_kickstart(ksconf)
123 def __get_ksconf(self):
124 return self.__ksconf
125 _ksconf = property(__get_ksconf, __set_ksconf)
126
127 def _parse_siteconf(self, siteconf):
128 if not siteconf:
129 return
130
131 if not os.path.exists(siteconf):
132 msger.warning("cannot read config file: %s" % siteconf)
133 return
134
135 parser = ConfigParser.SafeConfigParser()
136 parser.read(siteconf)
137
138 for section in parser.sections():
139 if section in self.DEFAULTS:
140 getattr(self, section).update(dict(parser.items(section)))
141
142 # append common section items to other sections
143 for section in self.DEFAULTS.keys():
144 if section != "common":
145 getattr(self, section).update(self.common)
146
147 # check and normalize the scheme of proxy url
148 if self.create['proxy']:
149 m = re.match('^(\w+)://.*', self.create['proxy'])
150 if m:
151 scheme = m.group(1)
152 if scheme not in ('http', 'https', 'ftp', 'socks'):
153 msger.error("%s: proxy scheme is incorrect" % siteconf)
154 else:
155 msger.warning("%s: proxy url w/o scheme, use http as default"
156 % siteconf)
157 self.create['proxy'] = "http://" + self.create['proxy']
158
159 proxy.set_proxies(self.create['proxy'], self.create['no_proxy'])
160
161 # bootstrap option handling
162 self.set_runtime(self.create['runtime'])
163 if isinstance(self.bootstrap['packages'], basestring):
164 packages = self.bootstrap['packages'].replace('\n', ' ')
165 if packages.find(',') != -1:
166 packages = packages.split(',')
167 else:
168 packages = packages.split()
169 self.bootstrap['packages'] = packages
170
171 def _parse_kickstart(self, ksconf=None):
172 if not ksconf:
173 return
174
175 ksconf = misc.normalize_ksfile(ksconf,
176 self.create['release'],
177 self.create['arch'])
178
179 ks = kickstart.read_kickstart(ksconf)
180
181 self.create['ks'] = ks
182 self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0]
183
184 self.create['name'] = misc.build_name(ksconf,
185 self.create['release'],
186 self.create['name_prefix'],
187 self.create['name_suffix'])
188
189 def set_runtime(self, runtime):
190 if runtime not in ("bootstrap", "native"):
191 msger.error("Invalid runtime mode: %s" % runtime)
192
193 if misc.get_distro()[0] in ("tizen", "Tizen"):
194 runtime = "native"
195 self.create['runtime'] = runtime
196
197configmgr = ConfigMgr()
diff --git a/scripts/lib/mic/creator.py b/scripts/lib/mic/creator.py
new file mode 100644
index 0000000000..267928f877
--- /dev/null
+++ b/scripts/lib/mic/creator.py
@@ -0,0 +1,351 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys, re
19from optparse import SUPPRESS_HELP
20
21from mic import msger
22from mic.utils import cmdln, errors
23from mic.conf import configmgr
24from mic.plugin import pluginmgr
25
26
27class Creator(cmdln.Cmdln):
28 """${name}: create an image
29
30 Usage:
31 ${name} SUBCOMMAND <ksfile> [OPTS]
32
33 ${command_list}
34 ${option_list}
35 """
36
37 name = 'mic create(cr)'
38
39 def __init__(self, *args, **kwargs):
40 cmdln.Cmdln.__init__(self, *args, **kwargs)
41 self._subcmds = []
42
43 # get cmds from pluginmgr
44 # mix-in do_subcmd interface
45 for subcmd, klass in pluginmgr.get_plugins('imager').iteritems():
46 if not hasattr(klass, 'do_create'):
47 msger.warning("Unsurpport subcmd: %s" % subcmd)
48 continue
49
50 func = getattr(klass, 'do_create')
51 setattr(self.__class__, "do_"+subcmd, func)
52 self._subcmds.append(subcmd)
53
54 def get_optparser(self):
55 optparser = cmdln.CmdlnOptionParser(self)
56 optparser.add_option('-d', '--debug', action='store_true',
57 dest='debug',
58 help=SUPPRESS_HELP)
59 optparser.add_option('-v', '--verbose', action='store_true',
60 dest='verbose',
61 help=SUPPRESS_HELP)
62 optparser.add_option('', '--logfile', type='string', dest='logfile',
63 default=None,
64 help='Path of logfile')
65 optparser.add_option('-c', '--config', type='string', dest='config',
66 default=None,
67 help='Specify config file for mic')
68 optparser.add_option('-k', '--cachedir', type='string', action='store',
69 dest='cachedir', default=None,
70 help='Cache directory to store the downloaded')
71 optparser.add_option('-o', '--outdir', type='string', action='store',
72 dest='outdir', default=None,
73 help='Output directory')
74 optparser.add_option('-A', '--arch', type='string', dest='arch',
75 default=None,
76 help='Specify repo architecture')
77 optparser.add_option('', '--release', type='string', dest='release',
78 default=None, metavar='RID',
79 help='Generate a release of RID with all necessary'
80 ' files, when @BUILD_ID@ is contained in '
81 'kickstart file, it will be replaced by RID')
82 optparser.add_option("", "--record-pkgs", type="string",
83 dest="record_pkgs", default=None,
84 help='Record the info of installed packages, '
85 'multiple values can be specified which '
86 'joined by ",", valid values: "name", '
87 '"content", "license", "vcs"')
88 optparser.add_option('', '--pkgmgr', type='string', dest='pkgmgr',
89 default=None,
90 help='Specify backend package manager')
91 optparser.add_option('', '--local-pkgs-path', type='string',
92 dest='local_pkgs_path', default=None,
93 help='Path for local pkgs(rpms) to be installed')
94 optparser.add_option('', '--runtime', type='string',
95 dest='runtime', default=None,
96 help='Specify runtime mode, avaiable: bootstrap, native')
97 # --taring-to is alias to --pack-to
98 optparser.add_option('', '--taring-to', type='string',
99 dest='pack_to', default=None,
100 help=SUPPRESS_HELP)
101 optparser.add_option('', '--pack-to', type='string',
102 dest='pack_to', default=None,
103 help='Pack the images together into the specified'
104 ' achive, extension supported: .zip, .tar, '
105 '.tar.gz, .tar.bz2, etc. by default, .tar '
106 'will be used')
107 optparser.add_option('', '--copy-kernel', action='store_true',
108 dest='copy_kernel',
109 help='Copy kernel files from image /boot directory'
110 ' to the image output directory.')
111 optparser.add_option('', '--install-pkgs', type='string', action='store',
112 dest='install_pkgs', default=None,
113 help='Specify what type of packages to be installed,'
114 ' valid: source, debuginfo, debugsource')
115 optparser.add_option('', '--tmpfs', action='store_true', dest='enabletmpfs',
116 help='Setup tmpdir as tmpfs to accelerate, experimental'
117 ' feature, use it if you have more than 4G memory')
118 optparser.add_option('', '--repourl', action='append',
119 dest='repourl', default=[],
120 help=SUPPRESS_HELP)
121 return optparser
122
123 def preoptparse(self, argv):
124 optparser = self.get_optparser()
125
126 largs = []
127 rargs = []
128 while argv:
129 arg = argv.pop(0)
130
131 if arg in ('-h', '--help'):
132 rargs.append(arg)
133
134 elif optparser.has_option(arg):
135 largs.append(arg)
136
137 if optparser.get_option(arg).takes_value():
138 try:
139 largs.append(argv.pop(0))
140 except IndexError:
141 raise errors.Usage("option %s requires arguments" % arg)
142
143 else:
144 if arg.startswith("--"):
145 if "=" in arg:
146 opt = arg.split("=")[0]
147 else:
148 opt = None
149 elif arg.startswith("-") and len(arg) > 2:
150 opt = arg[0:2]
151 else:
152 opt = None
153
154 if opt and optparser.has_option(opt):
155 largs.append(arg)
156 else:
157 rargs.append(arg)
158
159 return largs + rargs
160
161 def postoptparse(self):
162 abspath = lambda pth: os.path.abspath(os.path.expanduser(pth))
163
164 if self.options.verbose:
165 msger.set_loglevel('verbose')
166 if self.options.debug:
167 msger.set_loglevel('debug')
168
169 if self.options.logfile:
170 logfile_abs_path = abspath(self.options.logfile)
171 if os.path.isdir(logfile_abs_path):
172 raise errors.Usage("logfile's path %s should be file"
173 % self.options.logfile)
174 if not os.path.exists(os.path.dirname(logfile_abs_path)):
175 os.makedirs(os.path.dirname(logfile_abs_path))
176 msger.set_interactive(False)
177 msger.set_logfile(logfile_abs_path)
178 configmgr.create['logfile'] = self.options.logfile
179
180 if self.options.config:
181 configmgr.reset()
182 configmgr._siteconf = self.options.config
183
184 if self.options.outdir is not None:
185 configmgr.create['outdir'] = abspath(self.options.outdir)
186 if self.options.cachedir is not None:
187 configmgr.create['cachedir'] = abspath(self.options.cachedir)
188 os.environ['ZYPP_LOCKFILE_ROOT'] = configmgr.create['cachedir']
189
190 for cdir in ('outdir', 'cachedir'):
191 if os.path.exists(configmgr.create[cdir]) \
192 and not os.path.isdir(configmgr.create[cdir]):
193 msger.error('Invalid directory specified: %s' \
194 % configmgr.create[cdir])
195
196 if self.options.local_pkgs_path is not None:
197 if not os.path.exists(self.options.local_pkgs_path):
198 msger.error('Local pkgs directory: \'%s\' not exist' \
199 % self.options.local_pkgs_path)
200 configmgr.create['local_pkgs_path'] = self.options.local_pkgs_path
201
202 if self.options.release:
203 configmgr.create['release'] = self.options.release.rstrip('/')
204
205 if self.options.record_pkgs:
206 configmgr.create['record_pkgs'] = []
207 for infotype in self.options.record_pkgs.split(','):
208 if infotype not in ('name', 'content', 'license', 'vcs'):
209 raise errors.Usage('Invalid pkg recording: %s, valid ones:'
210 ' "name", "content", "license", "vcs"' \
211 % infotype)
212
213 configmgr.create['record_pkgs'].append(infotype)
214
215 if self.options.arch is not None:
216 supported_arch = sorted(rpmmisc.archPolicies.keys(), reverse=True)
217 if self.options.arch in supported_arch:
218 configmgr.create['arch'] = self.options.arch
219 else:
220 raise errors.Usage('Invalid architecture: "%s".\n'
221 ' Supported architectures are: \n'
222 ' %s' % (self.options.arch,
223 ', '.join(supported_arch)))
224
225 if self.options.pkgmgr is not None:
226 configmgr.create['pkgmgr'] = self.options.pkgmgr
227
228 if self.options.runtime:
229 configmgr.set_runtime(self.options.runtime)
230
231 if self.options.pack_to is not None:
232 configmgr.create['pack_to'] = self.options.pack_to
233
234 if self.options.copy_kernel:
235 configmgr.create['copy_kernel'] = self.options.copy_kernel
236
237 if self.options.install_pkgs:
238 configmgr.create['install_pkgs'] = []
239 for pkgtype in self.options.install_pkgs.split(','):
240 if pkgtype not in ('source', 'debuginfo', 'debugsource'):
241 raise errors.Usage('Invalid parameter specified: "%s", '
242 'valid values: source, debuginfo, '
243 'debusource' % pkgtype)
244
245 configmgr.create['install_pkgs'].append(pkgtype)
246
247 if self.options.enabletmpfs:
248 configmgr.create['enabletmpfs'] = self.options.enabletmpfs
249
250 if self.options.repourl:
251 for item in self.options.repourl:
252 try:
253 key, val = item.split('=')
254 except:
255 continue
256 configmgr.create['repourl'][key] = val
257
258 def main(self, argv=None):
259 if argv is None:
260 argv = sys.argv
261 else:
262 argv = argv[:] # don't modify caller's list
263
264 self.optparser = self.get_optparser()
265 if self.optparser:
266 try:
267 argv = self.preoptparse(argv)
268 self.options, args = self.optparser.parse_args(argv)
269
270 except cmdln.CmdlnUserError, ex:
271 msg = "%s: %s\nTry '%s help' for info.\n"\
272 % (self.name, ex, self.name)
273 msger.error(msg)
274
275 except cmdln.StopOptionProcessing, ex:
276 return 0
277 else:
278 # optparser=None means no process for opts
279 self.options, args = None, argv[1:]
280
281 if not args:
282 return self.emptyline()
283
284 self.postoptparse()
285
286 return self.cmd(args)
287
288 def precmd(self, argv): # check help before cmd
289
290 if '-h' in argv or '?' in argv or '--help' in argv or 'help' in argv:
291 return argv
292
293 if len(argv) == 1:
294 return ['help', argv[0]]
295
296 return argv
297
298 def do_auto(self, subcmd, opts, *args):
299 """${cmd_name}: auto detect image type from magic header
300
301 Usage:
302 ${name} ${cmd_name} <ksfile>
303
304 ${cmd_option_list}
305 """
306 def parse_magic_line(re_str, pstr, ptype='mic'):
307 ptn = re.compile(re_str)
308 m = ptn.match(pstr)
309 if not m or not m.groups():
310 return None
311
312 inline_argv = m.group(1).strip()
313 if ptype == 'mic':
314 m2 = re.search('(?P<format>\w+)', inline_argv)
315 elif ptype == 'mic2':
316 m2 = re.search('(-f|--format(=)?)\s*(?P<format>\w+)',
317 inline_argv)
318 else:
319 return None
320
321 if m2:
322 cmdname = m2.group('format')
323 inline_argv = inline_argv.replace(m2.group(0), '')
324 return (cmdname, inline_argv)
325
326 return None
327
328 if len(args) != 1:
329 raise errors.Usage("Extra arguments given")
330
331 if not os.path.exists(args[0]):
332 raise errors.CreatorError("Can't find the file: %s" % args[0])
333
334 with open(args[0], 'r') as rf:
335 first_line = rf.readline()
336
337 mic_re = '^#\s*-\*-mic-options-\*-\s+(.*)\s+-\*-mic-options-\*-'
338 mic2_re = '^#\s*-\*-mic2-options-\*-\s+(.*)\s+-\*-mic2-options-\*-'
339
340 result = parse_magic_line(mic_re, first_line, 'mic') \
341 or parse_magic_line(mic2_re, first_line, 'mic2')
342 if not result:
343 raise errors.KsError("Invalid magic line in file: %s" % args[0])
344
345 if result[0] not in self._subcmds:
346 raise errors.KsError("Unsupport format '%s' in %s"
347 % (result[0], args[0]))
348
349 argv = ' '.join(result + args).split()
350 self.main(argv)
351
diff --git a/scripts/lib/mic/imager/__init__.py b/scripts/lib/mic/imager/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/mic/imager/__init__.py
diff --git a/scripts/lib/mic/imager/baseimager.py b/scripts/lib/mic/imager/baseimager.py
new file mode 100644
index 0000000000..b7212493b4
--- /dev/null
+++ b/scripts/lib/mic/imager/baseimager.py
@@ -0,0 +1,1263 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007 Red Hat Inc.
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19from __future__ import with_statement
20import os, sys
21import stat
22import tempfile
23import shutil
24import subprocess
25import re
26import tarfile
27import glob
28
29from mic import kickstart
30from mic import msger
31from mic.utils.errors import CreatorError, Abort
32from mic.utils import misc, runner, fs_related as fs
33
34class BaseImageCreator(object):
35 """Installs a system to a chroot directory.
36
37 ImageCreator is the simplest creator class available; it will install and
38 configure a system image according to the supplied kickstart file.
39
40 e.g.
41
42 import mic.imgcreate as imgcreate
43 ks = imgcreate.read_kickstart("foo.ks")
44 imgcreate.ImageCreator(ks, "foo").create()
45
46 """
47
48 def __del__(self):
49 self.cleanup()
50
51 def __init__(self, createopts = None, pkgmgr = None):
52 """Initialize an ImageCreator instance.
53
54 ks -- a pykickstart.KickstartParser instance; this instance will be
55 used to drive the install by e.g. providing the list of packages
56 to be installed, the system configuration and %post scripts
57
58 name -- a name for the image; used for e.g. image filenames or
59 filesystem labels
60 """
61
62 self.pkgmgr = pkgmgr
63
64 self.__builddir = None
65 self.__bindmounts = []
66
67 self.ks = None
68 self.name = "target"
69 self.tmpdir = "/var/tmp/wic"
70 self.cachedir = "/var/tmp/wic/cache"
71 self.workdir = "/var/tmp/wic/build"
72
73 self.destdir = "."
74 self.installerfw_prefix = "INSTALLERFW_"
75 self.target_arch = "noarch"
76 self._local_pkgs_path = None
77 self.pack_to = None
78 self.repourl = {}
79
80 # If the kernel is save to the destdir when copy_kernel cmd is called.
81 self._need_copy_kernel = False
82 # setup tmpfs tmpdir when enabletmpfs is True
83 self.enabletmpfs = False
84
85 if createopts:
86 # Mapping table for variables that have different names.
87 optmap = {"pkgmgr" : "pkgmgr_name",
88 "outdir" : "destdir",
89 "arch" : "target_arch",
90 "local_pkgs_path" : "_local_pkgs_path",
91 "copy_kernel" : "_need_copy_kernel",
92 }
93
94 # update setting from createopts
95 for key in createopts.keys():
96 if key in optmap:
97 option = optmap[key]
98 else:
99 option = key
100 setattr(self, option, createopts[key])
101
102 self.destdir = os.path.abspath(os.path.expanduser(self.destdir))
103
104 if 'release' in createopts and createopts['release']:
105 self.name = createopts['release'] + '_' + self.name
106
107 if self.pack_to:
108 if '@NAME@' in self.pack_to:
109 self.pack_to = self.pack_to.replace('@NAME@', self.name)
110 (tar, ext) = os.path.splitext(self.pack_to)
111 if ext in (".gz", ".bz2") and tar.endswith(".tar"):
112 ext = ".tar" + ext
113 if ext not in misc.pack_formats:
114 self.pack_to += ".tar"
115
116 self._dep_checks = ["ls", "bash", "cp", "echo", "modprobe"]
117
118 # Output image file names
119 self.outimage = []
120
121 # A flag to generate checksum
122 self._genchecksum = False
123
124 self._alt_initrd_name = None
125
126 self._recording_pkgs = []
127
128 # available size in root fs, init to 0
129 self._root_fs_avail = 0
130
131 # Name of the disk image file that is created.
132 self._img_name = None
133
134 self.image_format = None
135
136 # Save qemu emulator file name in order to clean up it finally
137 self.qemu_emulator = None
138
139 # No ks provided when called by convertor, so skip the dependency check
140 if self.ks:
141 # If we have btrfs partition we need to check necessary tools
142 for part in self.ks.handler.partition.partitions:
143 if part.fstype and part.fstype == "btrfs":
144 self._dep_checks.append("mkfs.btrfs")
145 break
146
147 if self.target_arch and self.target_arch.startswith("arm"):
148 for dep in self._dep_checks:
149 if dep == "extlinux":
150 self._dep_checks.remove(dep)
151
152 if not os.path.exists("/usr/bin/qemu-arm") or \
153 not misc.is_statically_linked("/usr/bin/qemu-arm"):
154 self._dep_checks.append("qemu-arm-static")
155
156 if os.path.exists("/proc/sys/vm/vdso_enabled"):
157 vdso_fh = open("/proc/sys/vm/vdso_enabled","r")
158 vdso_value = vdso_fh.read().strip()
159 vdso_fh.close()
160 if (int)(vdso_value) == 1:
161 msger.warning("vdso is enabled on your host, which might "
162 "cause problems with arm emulations.\n"
163 "\tYou can disable vdso with following command before "
164 "starting image build:\n"
165 "\techo 0 | sudo tee /proc/sys/vm/vdso_enabled")
166
167 # make sure the specified tmpdir and cachedir exist
168 if not os.path.exists(self.tmpdir):
169 os.makedirs(self.tmpdir)
170 if not os.path.exists(self.cachedir):
171 os.makedirs(self.cachedir)
172
173
174 #
175 # Properties
176 #
177 def __get_instroot(self):
178 if self.__builddir is None:
179 raise CreatorError("_instroot is not valid before calling mount()")
180 return self.__builddir + "/install_root"
181 _instroot = property(__get_instroot)
182 """The location of the install root directory.
183
184 This is the directory into which the system is installed. Subclasses may
185 mount a filesystem image here or copy files to/from here.
186
187 Note, this directory does not exist before ImageCreator.mount() is called.
188
189 Note also, this is a read-only attribute.
190
191 """
192
193 def __get_outdir(self):
194 if self.__builddir is None:
195 raise CreatorError("_outdir is not valid before calling mount()")
196 return self.__builddir + "/out"
197 _outdir = property(__get_outdir)
198 """The staging location for the final image.
199
200 This is where subclasses should stage any files that are part of the final
201 image. ImageCreator.package() will copy any files found here into the
202 requested destination directory.
203
204 Note, this directory does not exist before ImageCreator.mount() is called.
205
206 Note also, this is a read-only attribute.
207
208 """
209
210
211 #
212 # Hooks for subclasses
213 #
214 def _mount_instroot(self, base_on = None):
215 """Mount or prepare the install root directory.
216
217 This is the hook where subclasses may prepare the install root by e.g.
218 mounting creating and loopback mounting a filesystem image to
219 _instroot.
220
221 There is no default implementation.
222
223 base_on -- this is the value passed to mount() and can be interpreted
224 as the subclass wishes; it might e.g. be the location of
225 a previously created ISO containing a system image.
226
227 """
228 pass
229
230 def _unmount_instroot(self):
231 """Undo anything performed in _mount_instroot().
232
233 This is the hook where subclasses must undo anything which was done
234 in _mount_instroot(). For example, if a filesystem image was mounted
235 onto _instroot, it should be unmounted here.
236
237 There is no default implementation.
238
239 """
240 pass
241
242 def _create_bootconfig(self):
243 """Configure the image so that it's bootable.
244
245 This is the hook where subclasses may prepare the image for booting by
246 e.g. creating an initramfs and bootloader configuration.
247
248 This hook is called while the install root is still mounted, after the
249 packages have been installed and the kickstart configuration has been
250 applied, but before the %post scripts have been executed.
251
252 There is no default implementation.
253
254 """
255 pass
256
257 def _stage_final_image(self):
258 """Stage the final system image in _outdir.
259
260 This is the hook where subclasses should place the image in _outdir
261 so that package() can copy it to the requested destination directory.
262
263 By default, this moves the install root into _outdir.
264
265 """
266 shutil.move(self._instroot, self._outdir + "/" + self.name)
267
268 def get_installed_packages(self):
269 return self._pkgs_content.keys()
270
271 def _save_recording_pkgs(self, destdir):
272 """Save the list or content of installed packages to file.
273 """
274 pkgs = self._pkgs_content.keys()
275 pkgs.sort() # inplace op
276
277 if not os.path.exists(destdir):
278 os.makedirs(destdir)
279
280 content = None
281 if 'vcs' in self._recording_pkgs:
282 vcslst = ["%s %s" % (k, v) for (k, v) in self._pkgs_vcsinfo.items()]
283 content = '\n'.join(sorted(vcslst))
284 elif 'name' in self._recording_pkgs:
285 content = '\n'.join(pkgs)
286 if content:
287 namefile = os.path.join(destdir, self.name + '.packages')
288 f = open(namefile, "w")
289 f.write(content)
290 f.close()
291 self.outimage.append(namefile);
292
293 # if 'content', save more details
294 if 'content' in self._recording_pkgs:
295 contfile = os.path.join(destdir, self.name + '.files')
296 f = open(contfile, "w")
297
298 for pkg in pkgs:
299 content = pkg + '\n'
300
301 pkgcont = self._pkgs_content[pkg]
302 content += ' '
303 content += '\n '.join(pkgcont)
304 content += '\n'
305
306 content += '\n'
307 f.write(content)
308 f.close()
309 self.outimage.append(contfile)
310
311 if 'license' in self._recording_pkgs:
312 licensefile = os.path.join(destdir, self.name + '.license')
313 f = open(licensefile, "w")
314
315 f.write('Summary:\n')
316 for license in reversed(sorted(self._pkgs_license, key=\
317 lambda license: len(self._pkgs_license[license]))):
318 f.write(" - %s: %s\n" \
319 % (license, len(self._pkgs_license[license])))
320
321 f.write('\nDetails:\n')
322 for license in reversed(sorted(self._pkgs_license, key=\
323 lambda license: len(self._pkgs_license[license]))):
324 f.write(" - %s:\n" % (license))
325 for pkg in sorted(self._pkgs_license[license]):
326 f.write(" - %s\n" % (pkg))
327 f.write('\n')
328
329 f.close()
330 self.outimage.append(licensefile)
331
332 def _get_required_packages(self):
333 """Return a list of required packages.
334
335 This is the hook where subclasses may specify a set of packages which
336 it requires to be installed.
337
338 This returns an empty list by default.
339
340 Note, subclasses should usually chain up to the base class
341 implementation of this hook.
342
343 """
344 return []
345
346 def _get_excluded_packages(self):
347 """Return a list of excluded packages.
348
349 This is the hook where subclasses may specify a set of packages which
350 it requires _not_ to be installed.
351
352 This returns an empty list by default.
353
354 Note, subclasses should usually chain up to the base class
355 implementation of this hook.
356
357 """
358 return []
359
360 def _get_local_packages(self):
361 """Return a list of rpm path to be local installed.
362
363 This is the hook where subclasses may specify a set of rpms which
364 it requires to be installed locally.
365
366 This returns an empty list by default.
367
368 Note, subclasses should usually chain up to the base class
369 implementation of this hook.
370
371 """
372 if self._local_pkgs_path:
373 if os.path.isdir(self._local_pkgs_path):
374 return glob.glob(
375 os.path.join(self._local_pkgs_path, '*.rpm'))
376 elif os.path.splitext(self._local_pkgs_path)[-1] == '.rpm':
377 return [self._local_pkgs_path]
378
379 return []
380
381 def _get_fstab(self):
382 """Return the desired contents of /etc/fstab.
383
384 This is the hook where subclasses may specify the contents of
385 /etc/fstab by returning a string containing the desired contents.
386
387 A sensible default implementation is provided.
388
389 """
390 s = "/dev/root / %s %s 0 0\n" \
391 % (self._fstype,
392 "defaults,noatime" if not self._fsopts else self._fsopts)
393 s += self._get_fstab_special()
394 return s
395
396 def _get_fstab_special(self):
397 s = "devpts /dev/pts devpts gid=5,mode=620 0 0\n"
398 s += "tmpfs /dev/shm tmpfs defaults 0 0\n"
399 s += "proc /proc proc defaults 0 0\n"
400 s += "sysfs /sys sysfs defaults 0 0\n"
401 return s
402
403 def _set_part_env(self, pnum, prop, value):
404 """ This is a helper function which generates an environment variable
405 for a property "prop" with value "value" of a partition number "pnum".
406
407 The naming convention is:
408 * Variables start with INSTALLERFW_PART
409 * Then goes the partition number, the order is the same as
410 specified in the KS file
411 * Then goes the property name
412 """
413
414 if value == None:
415 value = ""
416 else:
417 value = str(value)
418
419 name = self.installerfw_prefix + ("PART%d_" % pnum) + prop
420 return { name : value }
421
422 def _get_post_scripts_env(self, in_chroot):
423 """Return an environment dict for %post scripts.
424
425 This is the hook where subclasses may specify some environment
426 variables for %post scripts by return a dict containing the desired
427 environment.
428
429 in_chroot -- whether this %post script is to be executed chroot()ed
430 into _instroot.
431 """
432
433 env = {}
434 pnum = 0
435
436 for p in kickstart.get_partitions(self.ks):
437 env.update(self._set_part_env(pnum, "SIZE", p.size))
438 env.update(self._set_part_env(pnum, "MOUNTPOINT", p.mountpoint))
439 env.update(self._set_part_env(pnum, "FSTYPE", p.fstype))
440 env.update(self._set_part_env(pnum, "LABEL", p.label))
441 env.update(self._set_part_env(pnum, "FSOPTS", p.fsopts))
442 env.update(self._set_part_env(pnum, "BOOTFLAG", p.active))
443 env.update(self._set_part_env(pnum, "ALIGN", p.align))
444 env.update(self._set_part_env(pnum, "TYPE_ID", p.part_type))
445 env.update(self._set_part_env(pnum, "DEVNODE",
446 "/dev/%s%d" % (p.disk, pnum + 1)))
447 pnum += 1
448
449 # Count of paritions
450 env[self.installerfw_prefix + "PART_COUNT"] = str(pnum)
451
452 # Partition table format
453 ptable_format = self.ks.handler.bootloader.ptable
454 env[self.installerfw_prefix + "PTABLE_FORMAT"] = ptable_format
455
456 # The kerned boot parameters
457 kernel_opts = self.ks.handler.bootloader.appendLine
458 env[self.installerfw_prefix + "KERNEL_OPTS"] = kernel_opts
459
460 # Name of the distribution
461 env[self.installerfw_prefix + "DISTRO_NAME"] = self.distro_name
462
463 # Name of the image creation tool
464 env[self.installerfw_prefix + "INSTALLER_NAME"] = "wic"
465
466 # The real current location of the mounted file-systems
467 if in_chroot:
468 mount_prefix = "/"
469 else:
470 mount_prefix = self._instroot
471 env[self.installerfw_prefix + "MOUNT_PREFIX"] = mount_prefix
472
473 # These are historical variables which lack the common name prefix
474 if not in_chroot:
475 env["INSTALL_ROOT"] = self._instroot
476 env["IMG_NAME"] = self._name
477
478 return env
479
480 def __get_imgname(self):
481 return self.name
482 _name = property(__get_imgname)
483 """The name of the image file.
484
485 """
486
487 def _get_kernel_versions(self):
488 """Return a dict detailing the available kernel types/versions.
489
490 This is the hook where subclasses may override what kernel types and
491 versions should be available for e.g. creating the booloader
492 configuration.
493
494 A dict should be returned mapping the available kernel types to a list
495 of the available versions for those kernels.
496
497 The default implementation uses rpm to iterate over everything
498 providing 'kernel', finds /boot/vmlinuz-* and returns the version
499 obtained from the vmlinuz filename. (This can differ from the kernel
500 RPM's n-v-r in the case of e.g. xen)
501
502 """
503 def get_kernel_versions(instroot):
504 ret = {}
505 versions = set()
506 files = glob.glob(instroot + "/boot/vmlinuz-*")
507 for file in files:
508 version = os.path.basename(file)[8:]
509 if version is None:
510 continue
511 versions.add(version)
512 ret["kernel"] = list(versions)
513 return ret
514
515 def get_version(header):
516 version = None
517 for f in header['filenames']:
518 if f.startswith('/boot/vmlinuz-'):
519 version = f[14:]
520 return version
521
522 if self.ks is None:
523 return get_kernel_versions(self._instroot)
524
525 ts = rpm.TransactionSet(self._instroot)
526
527 ret = {}
528 for header in ts.dbMatch('provides', 'kernel'):
529 version = get_version(header)
530 if version is None:
531 continue
532
533 name = header['name']
534 if not name in ret:
535 ret[name] = [version]
536 elif not version in ret[name]:
537 ret[name].append(version)
538
539 return ret
540
541
542 #
543 # Helpers for subclasses
544 #
545 def _do_bindmounts(self):
546 """Mount various system directories onto _instroot.
547
548 This method is called by mount(), but may also be used by subclasses
549 in order to re-mount the bindmounts after modifying the underlying
550 filesystem.
551
552 """
553 for b in self.__bindmounts:
554 b.mount()
555
556 def _undo_bindmounts(self):
557 """Unmount the bind-mounted system directories from _instroot.
558
559 This method is usually only called by unmount(), but may also be used
560 by subclasses in order to gain access to the filesystem obscured by
561 the bindmounts - e.g. in order to create device nodes on the image
562 filesystem.
563
564 """
565 self.__bindmounts.reverse()
566 for b in self.__bindmounts:
567 b.unmount()
568
569 def _chroot(self):
570 """Chroot into the install root.
571
572 This method may be used by subclasses when executing programs inside
573 the install root e.g.
574
575 subprocess.call(["/bin/ls"], preexec_fn = self.chroot)
576
577 """
578 os.chroot(self._instroot)
579 os.chdir("/")
580
581 def _mkdtemp(self, prefix = "tmp-"):
582 """Create a temporary directory.
583
584 This method may be used by subclasses to create a temporary directory
585 for use in building the final image - e.g. a subclass might create
586 a temporary directory in order to bundle a set of files into a package.
587
588 The subclass may delete this directory if it wishes, but it will be
589 automatically deleted by cleanup().
590
591 The absolute path to the temporary directory is returned.
592
593 Note, this method should only be called after mount() has been called.
594
595 prefix -- a prefix which should be used when creating the directory;
596 defaults to "tmp-".
597
598 """
599 self.__ensure_builddir()
600 return tempfile.mkdtemp(dir = self.__builddir, prefix = prefix)
601
602 def _mkstemp(self, prefix = "tmp-"):
603 """Create a temporary file.
604
605 This method may be used by subclasses to create a temporary file
606 for use in building the final image - e.g. a subclass might need
607 a temporary location to unpack a compressed file.
608
609 The subclass may delete this file if it wishes, but it will be
610 automatically deleted by cleanup().
611
612 A tuple containing a file descriptor (returned from os.open() and the
613 absolute path to the temporary directory is returned.
614
615 Note, this method should only be called after mount() has been called.
616
617 prefix -- a prefix which should be used when creating the file;
618 defaults to "tmp-".
619
620 """
621 self.__ensure_builddir()
622 return tempfile.mkstemp(dir = self.__builddir, prefix = prefix)
623
624 def _mktemp(self, prefix = "tmp-"):
625 """Create a temporary file.
626
627 This method simply calls _mkstemp() and closes the returned file
628 descriptor.
629
630 The absolute path to the temporary file is returned.
631
632 Note, this method should only be called after mount() has been called.
633
634 prefix -- a prefix which should be used when creating the file;
635 defaults to "tmp-".
636
637 """
638
639 (f, path) = self._mkstemp(prefix)
640 os.close(f)
641 return path
642
643
644 #
645 # Actual implementation
646 #
647 def __ensure_builddir(self):
648 if not self.__builddir is None:
649 return
650
651 try:
652 self.workdir = os.path.join(self.tmpdir, "build")
653 if not os.path.exists(self.workdir):
654 os.makedirs(self.workdir)
655 self.__builddir = tempfile.mkdtemp(dir = self.workdir,
656 prefix = "imgcreate-")
657 except OSError, (err, msg):
658 raise CreatorError("Failed create build directory in %s: %s" %
659 (self.tmpdir, msg))
660
661 def get_cachedir(self, cachedir = None):
662 if self.cachedir:
663 return self.cachedir
664
665 self.__ensure_builddir()
666 if cachedir:
667 self.cachedir = cachedir
668 else:
669 self.cachedir = self.__builddir + "/wic-cache"
670 fs.makedirs(self.cachedir)
671 return self.cachedir
672
673 def __sanity_check(self):
674 """Ensure that the config we've been given is sane."""
675 if not (kickstart.get_packages(self.ks) or
676 kickstart.get_groups(self.ks)):
677 raise CreatorError("No packages or groups specified")
678
679 kickstart.convert_method_to_repo(self.ks)
680
681 if not kickstart.get_repos(self.ks):
682 raise CreatorError("No repositories specified")
683
684 def __write_fstab(self):
685 fstab_contents = self._get_fstab()
686 if fstab_contents:
687 fstab = open(self._instroot + "/etc/fstab", "w")
688 fstab.write(fstab_contents)
689 fstab.close()
690
691 def __create_minimal_dev(self):
692 """Create a minimal /dev so that we don't corrupt the host /dev"""
693 origumask = os.umask(0000)
694 devices = (('null', 1, 3, 0666),
695 ('urandom',1, 9, 0666),
696 ('random', 1, 8, 0666),
697 ('full', 1, 7, 0666),
698 ('ptmx', 5, 2, 0666),
699 ('tty', 5, 0, 0666),
700 ('zero', 1, 5, 0666))
701
702 links = (("/proc/self/fd", "/dev/fd"),
703 ("/proc/self/fd/0", "/dev/stdin"),
704 ("/proc/self/fd/1", "/dev/stdout"),
705 ("/proc/self/fd/2", "/dev/stderr"))
706
707 for (node, major, minor, perm) in devices:
708 if not os.path.exists(self._instroot + "/dev/" + node):
709 os.mknod(self._instroot + "/dev/" + node,
710 perm | stat.S_IFCHR,
711 os.makedev(major,minor))
712
713 for (src, dest) in links:
714 if not os.path.exists(self._instroot + dest):
715 os.symlink(src, self._instroot + dest)
716
717 os.umask(origumask)
718
719 def __setup_tmpdir(self):
720 if not self.enabletmpfs:
721 return
722
723 runner.show('mount -t tmpfs -o size=4G tmpfs %s' % self.workdir)
724
725 def __clean_tmpdir(self):
726 if not self.enabletmpfs:
727 return
728
729 runner.show('umount -l %s' % self.workdir)
730
731 def mount(self, base_on = None, cachedir = None):
732 """Setup the target filesystem in preparation for an install.
733
734 This function sets up the filesystem which the ImageCreator will
735 install into and configure. The ImageCreator class merely creates an
736 install root directory, bind mounts some system directories (e.g. /dev)
737 and writes out /etc/fstab. Other subclasses may also e.g. create a
738 sparse file, format it and loopback mount it to the install root.
739
740 base_on -- a previous install on which to base this install; defaults
741 to None, causing a new image to be created
742
743 cachedir -- a directory in which to store the Yum cache; defaults to
744 None, causing a new cache to be created; by setting this
745 to another directory, the same cache can be reused across
746 multiple installs.
747
748 """
749 self.__setup_tmpdir()
750 self.__ensure_builddir()
751
752 self._mount_instroot(base_on)
753
754 def unmount(self):
755 """Unmounts the target filesystem.
756
757 The ImageCreator class detaches the system from the install root, but
758 other subclasses may also detach the loopback mounted filesystem image
759 from the install root.
760
761 """
762 self._unmount_instroot()
763
764
765 def cleanup(self):
766 """Unmounts the target filesystem and deletes temporary files.
767
768 This method calls unmount() and then deletes any temporary files and
769 directories that were created on the host system while building the
770 image.
771
772 Note, make sure to call this method once finished with the creator
773 instance in order to ensure no stale files are left on the host e.g.:
774
775 creator = ImageCreator(ks, name)
776 try:
777 creator.create()
778 finally:
779 creator.cleanup()
780
781 """
782 if not self.__builddir:
783 return
784
785 self.unmount()
786
787 shutil.rmtree(self.__builddir, ignore_errors = True)
788 self.__builddir = None
789
790 self.__clean_tmpdir()
791
792 def __is_excluded_pkg(self, pkg):
793 if pkg in self._excluded_pkgs:
794 self._excluded_pkgs.remove(pkg)
795 return True
796
797 for xpkg in self._excluded_pkgs:
798 if xpkg.endswith('*'):
799 if pkg.startswith(xpkg[:-1]):
800 return True
801 elif xpkg.startswith('*'):
802 if pkg.endswith(xpkg[1:]):
803 return True
804
805 return None
806
807 def __select_packages(self, pkg_manager):
808 skipped_pkgs = []
809 for pkg in self._required_pkgs:
810 e = pkg_manager.selectPackage(pkg)
811 if e:
812 if kickstart.ignore_missing(self.ks):
813 skipped_pkgs.append(pkg)
814 elif self.__is_excluded_pkg(pkg):
815 skipped_pkgs.append(pkg)
816 else:
817 raise CreatorError("Failed to find package '%s' : %s" %
818 (pkg, e))
819
820 for pkg in skipped_pkgs:
821 msger.warning("Skipping missing package '%s'" % (pkg,))
822
823 def __select_groups(self, pkg_manager):
824 skipped_groups = []
825 for group in self._required_groups:
826 e = pkg_manager.selectGroup(group.name, group.include)
827 if e:
828 if kickstart.ignore_missing(self.ks):
829 skipped_groups.append(group)
830 else:
831 raise CreatorError("Failed to find group '%s' : %s" %
832 (group.name, e))
833
834 for group in skipped_groups:
835 msger.warning("Skipping missing group '%s'" % (group.name,))
836
837 def __deselect_packages(self, pkg_manager):
838 for pkg in self._excluded_pkgs:
839 pkg_manager.deselectPackage(pkg)
840
841 def __localinst_packages(self, pkg_manager):
842 for rpm_path in self._get_local_packages():
843 pkg_manager.installLocal(rpm_path)
844
845 def __preinstall_packages(self, pkg_manager):
846 if not self.ks:
847 return
848
849 self._preinstall_pkgs = kickstart.get_pre_packages(self.ks)
850 for pkg in self._preinstall_pkgs:
851 pkg_manager.preInstall(pkg)
852
853 def __attachment_packages(self, pkg_manager):
854 if not self.ks:
855 return
856
857 self._attachment = []
858 for item in kickstart.get_attachment(self.ks):
859 if item.startswith('/'):
860 fpaths = os.path.join(self._instroot, item.lstrip('/'))
861 for fpath in glob.glob(fpaths):
862 self._attachment.append(fpath)
863 continue
864
865 filelist = pkg_manager.getFilelist(item)
866 if filelist:
867 # found rpm in rootfs
868 for pfile in pkg_manager.getFilelist(item):
869 fpath = os.path.join(self._instroot, pfile.lstrip('/'))
870 self._attachment.append(fpath)
871 continue
872
873 # try to retrieve rpm file
874 (url, proxies) = pkg_manager.package_url(item)
875 if not url:
876 msger.warning("Can't get url from repo for %s" % item)
877 continue
878 fpath = os.path.join(self.cachedir, os.path.basename(url))
879 if not os.path.exists(fpath):
880 # download pkgs
881 try:
882 fpath = grabber.myurlgrab(url, fpath, proxies, None)
883 except CreatorError:
884 raise
885
886 tmpdir = self._mkdtemp()
887 misc.extract_rpm(fpath, tmpdir)
888 for (root, dirs, files) in os.walk(tmpdir):
889 for fname in files:
890 fpath = os.path.join(root, fname)
891 self._attachment.append(fpath)
892
893 def install(self, repo_urls=None):
894 """Install packages into the install root.
895
896 This function installs the packages listed in the supplied kickstart
897 into the install root. By default, the packages are installed from the
898 repository URLs specified in the kickstart.
899
900 repo_urls -- a dict which maps a repository name to a repository URL;
901 if supplied, this causes any repository URLs specified in
902 the kickstart to be overridden.
903
904 """
905
906 # initialize pkg list to install
907 if self.ks:
908 self.__sanity_check()
909
910 self._required_pkgs = \
911 kickstart.get_packages(self.ks, self._get_required_packages())
912 self._excluded_pkgs = \
913 kickstart.get_excluded(self.ks, self._get_excluded_packages())
914 self._required_groups = kickstart.get_groups(self.ks)
915 else:
916 self._required_pkgs = None
917 self._excluded_pkgs = None
918 self._required_groups = None
919
920 pkg_manager = self.get_pkg_manager()
921 pkg_manager.setup()
922
923 if hasattr(self, 'install_pkgs') and self.install_pkgs:
924 if 'debuginfo' in self.install_pkgs:
925 pkg_manager.install_debuginfo = True
926
927 for repo in kickstart.get_repos(self.ks, repo_urls):
928 (name, baseurl, mirrorlist, inc, exc,
929 proxy, proxy_username, proxy_password, debuginfo,
930 source, gpgkey, disable, ssl_verify, nocache,
931 cost, priority) = repo
932
933 yr = pkg_manager.addRepository(name, baseurl, mirrorlist, proxy,
934 proxy_username, proxy_password, inc, exc, ssl_verify,
935 nocache, cost, priority)
936
937 if kickstart.exclude_docs(self.ks):
938 rpm.addMacro("_excludedocs", "1")
939 rpm.addMacro("_dbpath", "/var/lib/rpm")
940 rpm.addMacro("__file_context_path", "%{nil}")
941 if kickstart.inst_langs(self.ks) != None:
942 rpm.addMacro("_install_langs", kickstart.inst_langs(self.ks))
943
944 try:
945 self.__preinstall_packages(pkg_manager)
946 self.__select_packages(pkg_manager)
947 self.__select_groups(pkg_manager)
948 self.__deselect_packages(pkg_manager)
949 self.__localinst_packages(pkg_manager)
950
951 BOOT_SAFEGUARD = 256L * 1024 * 1024 # 256M
952 checksize = self._root_fs_avail
953 if checksize:
954 checksize -= BOOT_SAFEGUARD
955 if self.target_arch:
956 pkg_manager._add_prob_flags(rpm.RPMPROB_FILTER_IGNOREARCH)
957 pkg_manager.runInstall(checksize)
958 except CreatorError, e:
959 raise
960 except KeyboardInterrupt:
961 raise
962 else:
963 self._pkgs_content = pkg_manager.getAllContent()
964 self._pkgs_license = pkg_manager.getPkgsLicense()
965 self._pkgs_vcsinfo = pkg_manager.getVcsInfo()
966 self.__attachment_packages(pkg_manager)
967 finally:
968 pkg_manager.close()
969
970 # hook post install
971 self.postinstall()
972
973 # do some clean up to avoid lvm info leakage. this sucks.
974 for subdir in ("cache", "backup", "archive"):
975 lvmdir = self._instroot + "/etc/lvm/" + subdir
976 try:
977 for f in os.listdir(lvmdir):
978 os.unlink(lvmdir + "/" + f)
979 except:
980 pass
981
982 def postinstall(self):
983 self.copy_attachment()
984
985 def __run_post_scripts(self):
986 msger.info("Running scripts ...")
987 if os.path.exists(self._instroot + "/tmp"):
988 shutil.rmtree(self._instroot + "/tmp")
989 os.mkdir (self._instroot + "/tmp", 0755)
990 for s in kickstart.get_post_scripts(self.ks):
991 (fd, path) = tempfile.mkstemp(prefix = "ks-script-",
992 dir = self._instroot + "/tmp")
993
994 s.script = s.script.replace("\r", "")
995 os.write(fd, s.script)
996 os.close(fd)
997 os.chmod(path, 0700)
998
999 env = self._get_post_scripts_env(s.inChroot)
1000
1001 if not s.inChroot:
1002 preexec = None
1003 script = path
1004 else:
1005 preexec = self._chroot
1006 script = "/tmp/" + os.path.basename(path)
1007
1008 try:
1009 try:
1010 subprocess.call([s.interp, script],
1011 preexec_fn = preexec,
1012 env = env,
1013 stdout = sys.stdout,
1014 stderr = sys.stderr)
1015 except OSError, (err, msg):
1016 raise CreatorError("Failed to execute %%post script "
1017 "with '%s' : %s" % (s.interp, msg))
1018 finally:
1019 os.unlink(path)
1020
1021 def __save_repo_keys(self, repodata):
1022 if not repodata:
1023 return None
1024
1025 gpgkeydir = "/etc/pki/rpm-gpg"
1026 fs.makedirs(self._instroot + gpgkeydir)
1027 for repo in repodata:
1028 if repo["repokey"]:
1029 repokey = gpgkeydir + "/RPM-GPG-KEY-%s" % repo["name"]
1030 shutil.copy(repo["repokey"], self._instroot + repokey)
1031
1032 def configure(self, repodata = None):
1033 """Configure the system image according to the kickstart.
1034
1035 This method applies the (e.g. keyboard or network) configuration
1036 specified in the kickstart and executes the kickstart %post scripts.
1037
1038 If necessary, it also prepares the image to be bootable by e.g.
1039 creating an initrd and bootloader configuration.
1040
1041 """
1042 ksh = self.ks.handler
1043
1044 msger.info('Applying configurations ...')
1045 try:
1046 kickstart.LanguageConfig(self._instroot).apply(ksh.lang)
1047 kickstart.KeyboardConfig(self._instroot).apply(ksh.keyboard)
1048 kickstart.TimezoneConfig(self._instroot).apply(ksh.timezone)
1049 #kickstart.AuthConfig(self._instroot).apply(ksh.authconfig)
1050 kickstart.FirewallConfig(self._instroot).apply(ksh.firewall)
1051 kickstart.RootPasswordConfig(self._instroot).apply(ksh.rootpw)
1052 kickstart.UserConfig(self._instroot).apply(ksh.user)
1053 kickstart.ServicesConfig(self._instroot).apply(ksh.services)
1054 kickstart.XConfig(self._instroot).apply(ksh.xconfig)
1055 kickstart.NetworkConfig(self._instroot).apply(ksh.network)
1056 kickstart.RPMMacroConfig(self._instroot).apply(self.ks)
1057 kickstart.DesktopConfig(self._instroot).apply(ksh.desktop)
1058 self.__save_repo_keys(repodata)
1059 kickstart.MoblinRepoConfig(self._instroot).apply(ksh.repo, repodata, self.repourl)
1060 except:
1061 msger.warning("Failed to apply configuration to image")
1062 raise
1063
1064 self._create_bootconfig()
1065 self.__run_post_scripts()
1066
1067 def launch_shell(self, launch):
1068 """Launch a shell in the install root.
1069
1070 This method is launches a bash shell chroot()ed in the install root;
1071 this can be useful for debugging.
1072
1073 """
1074 if launch:
1075 msger.info("Launching shell. Exit to continue.")
1076 subprocess.call(["/bin/bash"], preexec_fn = self._chroot)
1077
1078 def do_genchecksum(self, image_name):
1079 if not self._genchecksum:
1080 return
1081
1082 md5sum = misc.get_md5sum(image_name)
1083 with open(image_name + ".md5sum", "w") as f:
1084 f.write("%s %s" % (md5sum, os.path.basename(image_name)))
1085 self.outimage.append(image_name+".md5sum")
1086
1087 def package(self, destdir = "."):
1088 """Prepares the created image for final delivery.
1089
1090 In its simplest form, this method merely copies the install root to the
1091 supplied destination directory; other subclasses may choose to package
1092 the image by e.g. creating a bootable ISO containing the image and
1093 bootloader configuration.
1094
1095 destdir -- the directory into which the final image should be moved;
1096 this defaults to the current directory.
1097
1098 """
1099 self._stage_final_image()
1100
1101 if not os.path.exists(destdir):
1102 fs.makedirs(destdir)
1103
1104 if self._recording_pkgs:
1105 self._save_recording_pkgs(destdir)
1106
1107 # For image formats with two or multiple image files, it will be
1108 # better to put them under a directory
1109 if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"):
1110 destdir = os.path.join(destdir, "%s-%s" \
1111 % (self.name, self.image_format))
1112 msger.debug("creating destination dir: %s" % destdir)
1113 fs.makedirs(destdir)
1114
1115 # Ensure all data is flushed to _outdir
1116 runner.quiet('sync')
1117
1118 misc.check_space_pre_cp(self._outdir, destdir)
1119 for f in os.listdir(self._outdir):
1120 shutil.move(os.path.join(self._outdir, f),
1121 os.path.join(destdir, f))
1122 self.outimage.append(os.path.join(destdir, f))
1123 self.do_genchecksum(os.path.join(destdir, f))
1124
1125 def print_outimage_info(self):
1126 msg = "The new image can be found here:\n"
1127 self.outimage.sort()
1128 for file in self.outimage:
1129 msg += ' %s\n' % os.path.abspath(file)
1130
1131 msger.info(msg)
1132
1133 def check_depend_tools(self):
1134 for tool in self._dep_checks:
1135 fs.find_binary_path(tool)
1136
1137 def package_output(self, image_format, destdir = ".", package="none"):
1138 if not package or package == "none":
1139 return
1140
1141 destdir = os.path.abspath(os.path.expanduser(destdir))
1142 (pkg, comp) = os.path.splitext(package)
1143 if comp:
1144 comp=comp.lstrip(".")
1145
1146 if pkg == "tar":
1147 if comp:
1148 dst = "%s/%s-%s.tar.%s" %\
1149 (destdir, self.name, image_format, comp)
1150 else:
1151 dst = "%s/%s-%s.tar" %\
1152 (destdir, self.name, image_format)
1153
1154 msger.info("creating %s" % dst)
1155 tar = tarfile.open(dst, "w:" + comp)
1156
1157 for file in self.outimage:
1158 msger.info("adding %s to %s" % (file, dst))
1159 tar.add(file,
1160 arcname=os.path.join("%s-%s" \
1161 % (self.name, image_format),
1162 os.path.basename(file)))
1163 if os.path.isdir(file):
1164 shutil.rmtree(file, ignore_errors = True)
1165 else:
1166 os.remove(file)
1167
1168 tar.close()
1169
1170 '''All the file in outimage has been packaged into tar.* file'''
1171 self.outimage = [dst]
1172
1173 def release_output(self, config, destdir, release):
1174 """ Create release directory and files
1175 """
1176
1177 def _rpath(fn):
1178 """ release path """
1179 return os.path.join(destdir, fn)
1180
1181 outimages = self.outimage
1182
1183 # new ks
1184 new_kspath = _rpath(self.name+'.ks')
1185 with open(config) as fr:
1186 with open(new_kspath, "w") as wf:
1187 # When building a release we want to make sure the .ks
1188 # file generates the same build even when --release not used.
1189 wf.write(fr.read().replace("@BUILD_ID@", release))
1190 outimages.append(new_kspath)
1191
1192 # save log file, logfile is only available in creator attrs
1193 if hasattr(self, 'logfile') and not self.logfile:
1194 log_path = _rpath(self.name + ".log")
1195 # touch the log file, else outimages will filter it out
1196 with open(log_path, 'w') as wf:
1197 wf.write('')
1198 msger.set_logfile(log_path)
1199 outimages.append(_rpath(self.name + ".log"))
1200
1201 # rename iso and usbimg
1202 for f in os.listdir(destdir):
1203 if f.endswith(".iso"):
1204 newf = f[:-4] + '.img'
1205 elif f.endswith(".usbimg"):
1206 newf = f[:-7] + '.img'
1207 else:
1208 continue
1209 os.rename(_rpath(f), _rpath(newf))
1210 outimages.append(_rpath(newf))
1211
1212 # generate MD5SUMS
1213 with open(_rpath("MD5SUMS"), "w") as wf:
1214 for f in os.listdir(destdir):
1215 if f == "MD5SUMS":
1216 continue
1217
1218 if os.path.isdir(os.path.join(destdir, f)):
1219 continue
1220
1221 md5sum = misc.get_md5sum(_rpath(f))
1222 # There needs to be two spaces between the sum and
1223 # filepath to match the syntax with md5sum.
1224 # This way also md5sum -c MD5SUMS can be used by users
1225 wf.write("%s *%s\n" % (md5sum, f))
1226
1227 outimages.append("%s/MD5SUMS" % destdir)
1228
1229 # Filter out the nonexist file
1230 for fp in outimages[:]:
1231 if not os.path.exists("%s" % fp):
1232 outimages.remove(fp)
1233
1234 def copy_kernel(self):
1235 """ Copy kernel files to the outimage directory.
1236 NOTE: This needs to be called before unmounting the instroot.
1237 """
1238
1239 if not self._need_copy_kernel:
1240 return
1241
1242 if not os.path.exists(self.destdir):
1243 os.makedirs(self.destdir)
1244
1245 for kernel in glob.glob("%s/boot/vmlinuz-*" % self._instroot):
1246 kernelfilename = "%s/%s-%s" % (self.destdir,
1247 self.name,
1248 os.path.basename(kernel))
1249 msger.info('copy kernel file %s as %s' % (os.path.basename(kernel),
1250 kernelfilename))
1251 shutil.copy(kernel, kernelfilename)
1252 self.outimage.append(kernelfilename)
1253
1254 def copy_attachment(self):
1255 """ Subclass implement it to handle attachment files
1256 NOTE: This needs to be called before unmounting the instroot.
1257 """
1258 pass
1259
1260 def get_pkg_manager(self):
1261 return self.pkgmgr(target_arch = self.target_arch,
1262 instroot = self._instroot,
1263 cachedir = self.cachedir)
diff --git a/scripts/lib/mic/imager/direct.py b/scripts/lib/mic/imager/direct.py
new file mode 100644
index 0000000000..fef9d0ed32
--- /dev/null
+++ b/scripts/lib/mic/imager/direct.py
@@ -0,0 +1,384 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'direct' image creator class for 'wic', based
22# loosely on the raw image creator from 'mic'
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] linux.intel.com>
26#
27
28import os
29import stat
30import shutil
31
32from mic import kickstart, msger
33from mic.utils import fs_related, runner, misc
34from mic.utils.partitionedfs import PartitionedMount
35from mic.utils.errors import CreatorError, MountError
36from mic.imager.baseimager import BaseImageCreator
37from mic.utils.oe.misc import *
38from mic.plugin import pluginmgr
39
40disk_methods = {
41 "do_install_disk":None,
42}
43
44class DirectImageCreator(BaseImageCreator):
45 """
46 Installs a system into a file containing a partitioned disk image.
47
48 DirectImageCreator is an advanced ImageCreator subclass; an image
49 file is formatted with a partition table, each partition created
50 from a rootfs or other OpenEmbedded build artifact and dd'ed into
51 the virtual disk. The disk image can subsequently be dd'ed onto
52 media and used on actual hardware.
53 """
54
55 def __init__(self, oe_builddir, image_output_dir, rootfs_dir, bootimg_dir,
56 kernel_dir, native_sysroot, hdddir, staging_data_dir,
57 creatoropts=None, pkgmgr=None, compress_image=None,
58 generate_bmap=None, fstab_entry="uuid"):
59 """
60 Initialize a DirectImageCreator instance.
61
62 This method takes the same arguments as ImageCreator.__init__()
63 """
64 BaseImageCreator.__init__(self, creatoropts, pkgmgr)
65
66 self.__instimage = None
67 self.__imgdir = None
68 self.__disks = {}
69 self.__disk_format = "direct"
70 self._disk_names = []
71 self._ptable_format = self.ks.handler.bootloader.ptable
72 self.use_uuid = fstab_entry == "uuid"
73 self.compress_image = compress_image
74 self.bmap_needed = generate_bmap
75
76 self.oe_builddir = oe_builddir
77 if image_output_dir:
78 self.tmpdir = image_output_dir
79 self.cachedir = "%s/cache" % image_output_dir
80 self.rootfs_dir = rootfs_dir
81 self.bootimg_dir = bootimg_dir
82 self.kernel_dir = kernel_dir
83 self.native_sysroot = native_sysroot
84 self.hdddir = hdddir
85 self.staging_data_dir = staging_data_dir
86
87 def __write_fstab(self, image_rootfs):
88 """overriden to generate fstab (temporarily) in rootfs. This
89 is called from mount_instroot, make sure it doesn't get called
90 from BaseImage.mount()"""
91 if image_rootfs is None:
92 return None
93
94 fstab = image_rootfs + "/etc/fstab"
95 if not os.path.isfile(fstab):
96 return None
97
98 parts = self._get_parts()
99
100 self._save_fstab(fstab)
101 fstab_lines = self._get_fstab(fstab, parts)
102 self._update_fstab(fstab_lines, parts)
103 self._write_fstab(fstab, fstab_lines)
104
105 return fstab
106
107 def _update_fstab(self, fstab_lines, parts):
108 """Assume partition order same as in wks"""
109 for num, p in enumerate(parts, 1):
110 if not p.mountpoint or p.mountpoint == "/" or p.mountpoint == "/boot":
111 continue
112 if self._ptable_format == 'msdos' and num > 3:
113 device_name = "/dev/" + p.disk + str(num + 1)
114 else:
115 device_name = "/dev/" + p.disk + str(num)
116 fstab_entry = device_name + "\t" + p.mountpoint + "\t" + p.fstype + "\tdefaults\t0\t0\n"
117 fstab_lines.append(fstab_entry)
118
119 def _write_fstab(self, fstab, fstab_lines):
120 fstab = open(fstab, "w")
121 for line in fstab_lines:
122 fstab.write(line)
123 fstab.close()
124
125 def _save_fstab(self, fstab):
126 """Save the current fstab in rootfs"""
127 shutil.copyfile(fstab, fstab + ".orig")
128
129 def _restore_fstab(self, fstab):
130 """Restore the saved fstab in rootfs"""
131 if fstab is None:
132 return
133 shutil.move(fstab + ".orig", fstab)
134
135 def _get_fstab(self, fstab, parts):
136 """Return the desired contents of /etc/fstab."""
137 f = open(fstab, "r")
138 fstab_contents = f.readlines()
139 f.close()
140
141 return fstab_contents
142
143 def set_bootimg_dir(self, bootimg_dir):
144 """
145 Accessor for bootimg_dir, the actual location used for the source
146 of the bootimg. Should be set by source plugins (only if they
147 change the default bootimg source) so the correct info gets
148 displayed for print_outimage_info().
149 """
150 self.bootimg_dir = bootimg_dir
151
152 def _get_parts(self):
153 if not self.ks:
154 raise CreatorError("Failed to get partition info, "
155 "please check your kickstart setting.")
156
157 # Set a default partition if no partition is given out
158 if not self.ks.handler.partition.partitions:
159 partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
160 args = partstr.split()
161 pd = self.ks.handler.partition.parse(args[1:])
162 if pd not in self.ks.handler.partition.partitions:
163 self.ks.handler.partition.partitions.append(pd)
164
165 # partitions list from kickstart file
166 return kickstart.get_partitions(self.ks)
167
168 def get_disk_names(self):
169 """ Returns a list of physical target disk names (e.g., 'sdb') which
170 will be created. """
171
172 if self._disk_names:
173 return self._disk_names
174
175 #get partition info from ks handler
176 parts = self._get_parts()
177
178 for i in range(len(parts)):
179 if parts[i].disk:
180 disk_name = parts[i].disk
181 else:
182 raise CreatorError("Failed to create disks, no --ondisk "
183 "specified in partition line of ks file")
184
185 if parts[i].mountpoint and not parts[i].fstype:
186 raise CreatorError("Failed to create disks, no --fstype "
187 "specified for partition with mountpoint "
188 "'%s' in the ks file")
189
190 self._disk_names.append(disk_name)
191
192 return self._disk_names
193
194 def _full_name(self, name, extention):
195 """ Construct full file name for a file we generate. """
196 return "%s-%s.%s" % (self.name, name, extention)
197
198 def _full_path(self, path, name, extention):
199 """ Construct full file path to a file we generate. """
200 return os.path.join(path, self._full_name(name, extention))
201
202 def get_default_source_plugin(self):
203 """
204 The default source plugin i.e. the plugin that's consulted for
205 overall image generation tasks outside of any particular
206 partition. For convenience, we just hang it off the
207 bootloader handler since it's the one non-partition object in
208 any setup. By default the default plugin is set to the same
209 plugin as the /boot partition; since we hang it off the
210 bootloader object, the default can be explicitly set using the
211 --source bootloader param.
212 """
213 return self.ks.handler.bootloader.source
214
215 #
216 # Actual implemention
217 #
218 def _mount_instroot(self, base_on = None):
219 """
220 For 'wic', we already have our build artifacts and don't want
221 to loop mount anything to install into, we just create
222 filesystems from the artifacts directly and combine them into
223 a partitioned image.
224
225 We still want to reuse as much of the basic mic machinery
226 though; despite the fact that we don't actually do loop or any
227 other kind of mounting we still want to do many of the same
228 things to prepare images, so we basically just adapt to the
229 basic framework and reinterpret what 'mounting' means in our
230 context.
231
232 _instroot would normally be something like
233 /var/tmp/wic/build/imgcreate-s_9AKQ/install_root, for
234 installing packages, etc. We don't currently need to do that,
235 so we simplify life by just using /var/tmp/wic/build as our
236 workdir.
237 """
238 parts = self._get_parts()
239
240 self.__instimage = PartitionedMount(self._instroot)
241
242 for p in parts:
243 # as a convenience, set source to the boot partition source
244 # instead of forcing it to be set via bootloader --source
245 if not self.ks.handler.bootloader.source and p.mountpoint == "/boot":
246 self.ks.handler.bootloader.source = p.source
247
248 for p in parts:
249 # need to create the filesystems in order to get their
250 # sizes before we can add them and do the layout.
251 # PartitionedMount.mount() actually calls __format_disks()
252 # to create the disk images and carve out the partitions,
253 # then self.install() calls PartitionedMount.install()
254 # which calls __install_partitition() for each partition
255 # to dd the fs into the partitions. It would be nice to
256 # be able to use e.g. ExtDiskMount etc to create the
257 # filesystems, since that's where existing e.g. mkfs code
258 # is, but those are only created after __format_disks()
259 # which needs the partition sizes so needs them created
260 # before its called. Well, the existing setup is geared
261 # to installing packages into mounted filesystems - maybe
262 # when/if we need to actually do package selection we
263 # should modify things to use those objects, but for now
264 # we can avoid that.
265
266 p.install_pkgs(self, self.workdir, self.oe_builddir, self.rootfs_dir,
267 self.bootimg_dir, self.kernel_dir, self.native_sysroot)
268
269 p.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
270 self.bootimg_dir, self.kernel_dir, self.native_sysroot)
271
272 fstab = self.__write_fstab(p.get_rootfs())
273 self._restore_fstab(fstab)
274
275 self.__instimage.add_partition(int(p.size),
276 p.disk,
277 p.mountpoint,
278 p.source_file,
279 p.fstype,
280 p.label,
281 fsopts = p.fsopts,
282 boot = p.active,
283 align = p.align,
284 part_type = p.part_type)
285 self.__instimage.layout_partitions(self._ptable_format)
286
287 self.__imgdir = self.workdir
288 for disk_name, disk in self.__instimage.disks.items():
289 full_path = self._full_path(self.__imgdir, disk_name, "direct")
290 msger.debug("Adding disk %s as %s with size %s bytes" \
291 % (disk_name, full_path, disk['min_size']))
292 disk_obj = fs_related.DiskImage(full_path, disk['min_size'])
293 self.__disks[disk_name] = disk_obj
294 self.__instimage.add_disk(disk_name, disk_obj)
295
296 self.__instimage.mount()
297
298 def install(self, repo_urls=None):
299 """
300 Install fs images into partitions
301 """
302 for disk_name, disk in self.__instimage.disks.items():
303 full_path = self._full_path(self.__imgdir, disk_name, "direct")
304 msger.debug("Installing disk %s as %s with size %s bytes" \
305 % (disk_name, full_path, disk['min_size']))
306 self.__instimage.install(full_path)
307
308 def configure(self, repodata = None):
309 """
310 Configure the system image according to kickstart.
311
312 For now, it just prepares the image to be bootable by e.g.
313 creating and installing a bootloader configuration.
314 """
315 source_plugin = self.get_default_source_plugin()
316 if source_plugin:
317 self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
318 for disk_name, disk in self.__instimage.disks.items():
319 self._source_methods["do_install_disk"](disk, disk_name, self,
320 self.workdir,
321 self.oe_builddir,
322 self.bootimg_dir,
323 self.kernel_dir,
324 self.native_sysroot)
325
326 def print_outimage_info(self):
327 """
328 Print the image(s) and artifacts used, for the user.
329 """
330 msg = "The new image(s) can be found here:\n"
331
332 parts = self._get_parts()
333
334 for disk_name, disk in self.__instimage.disks.items():
335 full_path = self._full_path(self.__imgdir, disk_name, "direct")
336 msg += ' %s\n\n' % full_path
337
338 msg += 'The following build artifacts were used to create the image(s):\n'
339 for p in parts:
340 if p.get_rootfs() is None:
341 continue
342 if p.mountpoint == '/':
343 str = ':'
344 else:
345 str = '["%s"]:' % p.label
346 msg += ' ROOTFS_DIR%s%s\n' % (str.ljust(20), p.get_rootfs())
347
348 msg += ' BOOTIMG_DIR: %s\n' % self.bootimg_dir
349 msg += ' KERNEL_DIR: %s\n' % self.kernel_dir
350 msg += ' NATIVE_SYSROOT: %s\n' % self.native_sysroot
351
352 msger.info(msg)
353
354 def _get_boot_config(self):
355 """
356 Return the rootdev/root_part_uuid (if specified by
357 --part-type)
358
359 Assume partition order same as in wks
360 """
361 rootdev = None
362 root_part_uuid = None
363 parts = self._get_parts()
364 for num, p in enumerate(parts, 1):
365 if p.mountpoint == "/":
366 part = ''
367 if p.disk.startswith('mmcblk'):
368 part = 'p'
369
370 if self._ptable_format == 'msdos' and num > 3:
371 rootdev = "/dev/%s%s%-d" % (p.disk, part, num + 1)
372 else:
373 rootdev = "/dev/%s%s%-d" % (p.disk, part, num)
374 root_part_uuid = p.part_type
375
376 return (rootdev, root_part_uuid)
377
378 def _unmount_instroot(self):
379 if not self.__instimage is None:
380 try:
381 self.__instimage.cleanup()
382 except MountError, err:
383 msger.warning("%s" % err)
384
diff --git a/scripts/lib/mic/imager/fs.py b/scripts/lib/mic/imager/fs.py
new file mode 100644
index 0000000000..d53b29cb47
--- /dev/null
+++ b/scripts/lib/mic/imager/fs.py
@@ -0,0 +1,99 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19
20from mic import msger
21from mic.utils import runner, misc
22from mic.utils.errors import CreatorError
23from mic.utils.fs_related import find_binary_path
24from mic.imager.baseimager import BaseImageCreator
25
26class FsImageCreator(BaseImageCreator):
27 def __init__(self, cfgmgr = None, pkgmgr = None):
28 self.zips = {
29 "tar.bz2" : ""
30 }
31 BaseImageCreator.__init__(self, cfgmgr, pkgmgr)
32 self._fstype = None
33 self._fsopts = None
34 self._include_src = False
35
36 def package(self, destdir = "."):
37
38 ignores = ["/dev/fd",
39 "/dev/stdin",
40 "/dev/stdout",
41 "/dev/stderr",
42 "/etc/mtab"]
43
44 if not os.path.exists(destdir):
45 os.makedirs(destdir)
46
47 if self._recording_pkgs:
48 self._save_recording_pkgs(destdir)
49
50 if not self.pack_to:
51 fsdir = os.path.join(destdir, self.name)
52
53 misc.check_space_pre_cp(self._instroot, destdir)
54 msger.info("Copying %s to %s ..." % (self._instroot, fsdir))
55 runner.show(['cp', "-af", self._instroot, fsdir])
56
57 for exclude in ignores:
58 if os.path.exists(fsdir + exclude):
59 os.unlink(fsdir + exclude)
60
61 self.outimage.append(fsdir)
62
63 else:
64 (tar, comp) = os.path.splitext(self.pack_to)
65 try:
66 tarcreat = {'.tar': '-cf',
67 '.gz': '-czf',
68 '.bz2': '-cjf',
69 '.tgz': '-czf',
70 '.tbz': '-cjf'}[comp]
71 except KeyError:
72 raise CreatorError("Unsupported comression for this image type:"
73 " '%s', try '.tar', '.tar.gz', etc" % comp)
74
75 dst = os.path.join(destdir, self.pack_to)
76 msger.info("Pack rootfs to %s. Please wait..." % dst)
77
78 tar = find_binary_path('tar')
79 tar_cmdline = [tar, "--numeric-owner",
80 "--preserve-permissions",
81 "--preserve-order",
82 "--one-file-system",
83 "--directory",
84 self._instroot]
85 for ignore_entry in ignores:
86 if ignore_entry.startswith('/'):
87 ignore_entry = ignore_entry[1:]
88
89 tar_cmdline.append("--exclude=%s" % (ignore_entry))
90
91 tar_cmdline.extend([tarcreat, dst, "."])
92
93 rc = runner.show(tar_cmdline)
94 if rc:
95 raise CreatorError("Failed compress image with tar.bz2. "
96 "Cmdline: %s" % (" ".join(tar_cmdline)))
97
98 self.outimage.append(dst)
99
diff --git a/scripts/lib/mic/imager/livecd.py b/scripts/lib/mic/imager/livecd.py
new file mode 100644
index 0000000000..e36f4a76c6
--- /dev/null
+++ b/scripts/lib/mic/imager/livecd.py
@@ -0,0 +1,750 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys
19import glob
20import shutil
21
22from mic import kickstart, msger
23from mic.utils import fs_related, runner, misc
24from mic.utils.errors import CreatorError
25from mic.imager.loop import LoopImageCreator
26
27
28class LiveImageCreatorBase(LoopImageCreator):
29 """A base class for LiveCD image creators.
30
31 This class serves as a base class for the architecture-specific LiveCD
32 image creator subclass, LiveImageCreator.
33
34 LiveImageCreator creates a bootable ISO containing the system image,
35 bootloader, bootloader configuration, kernel and initramfs.
36 """
37
38 def __init__(self, creatoropts = None, pkgmgr = None):
39 """Initialise a LiveImageCreator instance.
40
41 This method takes the same arguments as ImageCreator.__init__().
42 """
43 LoopImageCreator.__init__(self, creatoropts, pkgmgr)
44
45 #Controls whether to use squashfs to compress the image.
46 self.skip_compression = False
47
48 #Controls whether an image minimizing snapshot should be created.
49 #
50 #This snapshot can be used when copying the system image from the ISO in
51 #order to minimize the amount of data that needs to be copied; simply,
52 #it makes it possible to create a version of the image's filesystem with
53 #no spare space.
54 self.skip_minimize = False
55
56 #A flag which indicates i act as a convertor default false
57 self.actasconvertor = False
58
59 #The bootloader timeout from kickstart.
60 if self.ks:
61 self._timeout = kickstart.get_timeout(self.ks, 10)
62 else:
63 self._timeout = 10
64
65 #The default kernel type from kickstart.
66 if self.ks:
67 self._default_kernel = kickstart.get_default_kernel(self.ks,
68 "kernel")
69 else:
70 self._default_kernel = None
71
72 if self.ks:
73 parts = kickstart.get_partitions(self.ks)
74 if len(parts) > 1:
75 raise CreatorError("Can't support multi partitions in ks file "
76 "for this image type")
77 # FIXME: rename rootfs img to self.name,
78 # else can't find files when create iso
79 self._instloops[0]['name'] = self.name + ".img"
80
81 self.__isodir = None
82
83 self.__modules = ["=ata",
84 "sym53c8xx",
85 "aic7xxx",
86 "=usb",
87 "=firewire",
88 "=mmc",
89 "=pcmcia",
90 "mptsas"]
91 if self.ks:
92 self.__modules.extend(kickstart.get_modules(self.ks))
93
94 self._dep_checks.extend(["isohybrid",
95 "unsquashfs",
96 "mksquashfs",
97 "dd",
98 "genisoimage"])
99
100 #
101 # Hooks for subclasses
102 #
103 def _configure_bootloader(self, isodir):
104 """Create the architecture specific booloader configuration.
105
106 This is the hook where subclasses must create the booloader
107 configuration in order to allow a bootable ISO to be built.
108
109 isodir -- the directory where the contents of the ISO are to
110 be staged
111 """
112 raise CreatorError("Bootloader configuration is arch-specific, "
113 "but not implemented for this arch!")
114 def _get_menu_options(self):
115 """Return a menu options string for syslinux configuration.
116 """
117 if self.ks is None:
118 return "liveinst autoinst"
119 r = kickstart.get_menu_args(self.ks)
120 return r
121
122 def _get_kernel_options(self):
123 """Return a kernel options string for bootloader configuration.
124
125 This is the hook where subclasses may specify a set of kernel
126 options which should be included in the images bootloader
127 configuration.
128
129 A sensible default implementation is provided.
130 """
131
132 if self.ks is None:
133 r = "ro rd.live.image"
134 else:
135 r = kickstart.get_kernel_args(self.ks)
136
137 return r
138
139 def _get_mkisofs_options(self, isodir):
140 """Return the architecture specific mkisosfs options.
141
142 This is the hook where subclasses may specify additional arguments
143 to mkisofs, e.g. to enable a bootable ISO to be built.
144
145 By default, an empty list is returned.
146 """
147 return []
148
149 #
150 # Helpers for subclasses
151 #
152 def _has_checkisomd5(self):
153 """Check whether checkisomd5 is available in the install root."""
154 def _exists(path):
155 return os.path.exists(self._instroot + path)
156
157 if _exists("/usr/bin/checkisomd5") and os.path.exists("/usr/bin/implantisomd5"):
158 return True
159
160 return False
161
162 def __restore_file(self,path):
163 try:
164 os.unlink(path)
165 except:
166 pass
167 if os.path.exists(path + '.rpmnew'):
168 os.rename(path + '.rpmnew', path)
169
170 def _mount_instroot(self, base_on = None):
171 LoopImageCreator._mount_instroot(self, base_on)
172 self.__write_initrd_conf(self._instroot + "/etc/sysconfig/mkinitrd")
173 self.__write_dracut_conf(self._instroot + "/etc/dracut.conf.d/02livecd.conf")
174
175 def _unmount_instroot(self):
176 self.__restore_file(self._instroot + "/etc/sysconfig/mkinitrd")
177 self.__restore_file(self._instroot + "/etc/dracut.conf.d/02livecd.conf")
178 LoopImageCreator._unmount_instroot(self)
179
180 def __ensure_isodir(self):
181 if self.__isodir is None:
182 self.__isodir = self._mkdtemp("iso-")
183 return self.__isodir
184
185 def _get_isodir(self):
186 return self.__ensure_isodir()
187
188 def _set_isodir(self, isodir = None):
189 self.__isodir = isodir
190
191 def _create_bootconfig(self):
192 """Configure the image so that it's bootable."""
193 self._configure_bootloader(self.__ensure_isodir())
194
195 def _get_post_scripts_env(self, in_chroot):
196 env = LoopImageCreator._get_post_scripts_env(self, in_chroot)
197
198 if not in_chroot:
199 env["LIVE_ROOT"] = self.__ensure_isodir()
200
201 return env
202 def __write_dracut_conf(self, path):
203 if not os.path.exists(os.path.dirname(path)):
204 fs_related.makedirs(os.path.dirname(path))
205 f = open(path, "a")
206 f.write('add_dracutmodules+=" dmsquash-live pollcdrom "')
207 f.close()
208
209 def __write_initrd_conf(self, path):
210 content = ""
211 if not os.path.exists(os.path.dirname(path)):
212 fs_related.makedirs(os.path.dirname(path))
213 f = open(path, "w")
214
215 content += 'LIVEOS="yes"\n'
216 content += 'PROBE="no"\n'
217 content += 'MODULES+="squashfs ext3 ext2 vfat msdos "\n'
218 content += 'MODULES+="sr_mod sd_mod ide-cd cdrom "\n'
219
220 for module in self.__modules:
221 if module == "=usb":
222 content += 'MODULES+="ehci_hcd uhci_hcd ohci_hcd "\n'
223 content += 'MODULES+="usb_storage usbhid "\n'
224 elif module == "=firewire":
225 content += 'MODULES+="firewire-sbp2 firewire-ohci "\n'
226 content += 'MODULES+="sbp2 ohci1394 ieee1394 "\n'
227 elif module == "=mmc":
228 content += 'MODULES+="mmc_block sdhci sdhci-pci "\n'
229 elif module == "=pcmcia":
230 content += 'MODULES+="pata_pcmcia "\n'
231 else:
232 content += 'MODULES+="' + module + ' "\n'
233 f.write(content)
234 f.close()
235
236 def __create_iso(self, isodir):
237 iso = self._outdir + "/" + self.name + ".iso"
238 genisoimage = fs_related.find_binary_path("genisoimage")
239 args = [genisoimage,
240 "-J", "-r",
241 "-hide-rr-moved", "-hide-joliet-trans-tbl",
242 "-V", self.fslabel,
243 "-o", iso]
244
245 args.extend(self._get_mkisofs_options(isodir))
246
247 args.append(isodir)
248
249 if runner.show(args) != 0:
250 raise CreatorError("ISO creation failed!")
251
252 """ It should be ok still even if you haven't isohybrid """
253 isohybrid = None
254 try:
255 isohybrid = fs_related.find_binary_path("isohybrid")
256 except:
257 pass
258
259 if isohybrid:
260 args = [isohybrid, "-partok", iso ]
261 if runner.show(args) != 0:
262 raise CreatorError("Hybrid ISO creation failed!")
263
264 self.__implant_md5sum(iso)
265
266 def __implant_md5sum(self, iso):
267 """Implant an isomd5sum."""
268 if os.path.exists("/usr/bin/implantisomd5"):
269 implantisomd5 = "/usr/bin/implantisomd5"
270 else:
271 msger.warning("isomd5sum not installed; not setting up mediacheck")
272 implantisomd5 = ""
273 return
274
275 runner.show([implantisomd5, iso])
276
277 def _stage_final_image(self):
278 try:
279 fs_related.makedirs(self.__ensure_isodir() + "/LiveOS")
280
281 minimal_size = self._resparse()
282
283 if not self.skip_minimize:
284 fs_related.create_image_minimizer(self.__isodir + \
285 "/LiveOS/osmin.img",
286 self._image,
287 minimal_size)
288
289 if self.skip_compression:
290 shutil.move(self._image, self.__isodir + "/LiveOS/ext3fs.img")
291 else:
292 fs_related.makedirs(os.path.join(
293 os.path.dirname(self._image),
294 "LiveOS"))
295 shutil.move(self._image,
296 os.path.join(os.path.dirname(self._image),
297 "LiveOS", "ext3fs.img"))
298 fs_related.mksquashfs(os.path.dirname(self._image),
299 self.__isodir + "/LiveOS/squashfs.img")
300
301 self.__create_iso(self.__isodir)
302
303 if self.pack_to:
304 isoimg = os.path.join(self._outdir, self.name + ".iso")
305 packimg = os.path.join(self._outdir, self.pack_to)
306 misc.packing(packimg, isoimg)
307 os.unlink(isoimg)
308
309 finally:
310 shutil.rmtree(self.__isodir, ignore_errors = True)
311 self.__isodir = None
312
313class x86LiveImageCreator(LiveImageCreatorBase):
314 """ImageCreator for x86 machines"""
315 def _get_mkisofs_options(self, isodir):
316 return [ "-b", "isolinux/isolinux.bin",
317 "-c", "isolinux/boot.cat",
318 "-no-emul-boot", "-boot-info-table",
319 "-boot-load-size", "4" ]
320
321 def _get_required_packages(self):
322 return ["syslinux", "syslinux-extlinux"] + \
323 LiveImageCreatorBase._get_required_packages(self)
324
325 def _get_isolinux_stanzas(self, isodir):
326 return ""
327
328 def __find_syslinux_menu(self):
329 for menu in ["vesamenu.c32", "menu.c32"]:
330 if os.path.isfile(self._instroot + "/usr/share/syslinux/" + menu):
331 return menu
332
333 raise CreatorError("syslinux not installed : "
334 "no suitable /usr/share/syslinux/*menu.c32 found")
335
336 def __find_syslinux_mboot(self):
337 #
338 # We only need the mboot module if we have any xen hypervisors
339 #
340 if not glob.glob(self._instroot + "/boot/xen.gz*"):
341 return None
342
343 return "mboot.c32"
344
345 def __copy_syslinux_files(self, isodir, menu, mboot = None):
346 files = ["isolinux.bin", menu]
347 if mboot:
348 files += [mboot]
349
350 for f in files:
351 path = self._instroot + "/usr/share/syslinux/" + f
352
353 if not os.path.isfile(path):
354 raise CreatorError("syslinux not installed : "
355 "%s not found" % path)
356
357 shutil.copy(path, isodir + "/isolinux/")
358
359 def __copy_syslinux_background(self, isodest):
360 background_path = self._instroot + \
361 "/usr/share/branding/default/syslinux/syslinux-vesa-splash.jpg"
362
363 if not os.path.exists(background_path):
364 return False
365
366 shutil.copyfile(background_path, isodest)
367
368 return True
369
370 def __copy_kernel_and_initramfs(self, isodir, version, index):
371 bootdir = self._instroot + "/boot"
372 isDracut = False
373
374 if self._alt_initrd_name:
375 src_initrd_path = os.path.join(bootdir, self._alt_initrd_name)
376 else:
377 if os.path.exists(bootdir + "/initramfs-" + version + ".img"):
378 src_initrd_path = os.path.join(bootdir, "initramfs-" +version+ ".img")
379 isDracut = True
380 else:
381 src_initrd_path = os.path.join(bootdir, "initrd-" +version+ ".img")
382
383 try:
384 msger.debug("copy %s to %s" % (bootdir + "/vmlinuz-" + version, isodir + "/isolinux/vmlinuz" + index))
385 shutil.copyfile(bootdir + "/vmlinuz-" + version,
386 isodir + "/isolinux/vmlinuz" + index)
387
388 msger.debug("copy %s to %s" % (src_initrd_path, isodir + "/isolinux/initrd" + index + ".img"))
389 shutil.copyfile(src_initrd_path,
390 isodir + "/isolinux/initrd" + index + ".img")
391 except:
392 raise CreatorError("Unable to copy valid kernels or initrds, "
393 "please check the repo.")
394
395 is_xen = False
396 if os.path.exists(bootdir + "/xen.gz-" + version[:-3]):
397 shutil.copyfile(bootdir + "/xen.gz-" + version[:-3],
398 isodir + "/isolinux/xen" + index + ".gz")
399 is_xen = True
400
401 return (is_xen,isDracut)
402
403 def __is_default_kernel(self, kernel, kernels):
404 if len(kernels) == 1:
405 return True
406
407 if kernel == self._default_kernel:
408 return True
409
410 if kernel.startswith("kernel-") and kernel[7:] == self._default_kernel:
411 return True
412
413 return False
414
415 def __get_basic_syslinux_config(self, **args):
416 return """
417default %(menu)s
418timeout %(timeout)d
419
420%(background)s
421menu title Welcome to %(distroname)s!
422menu color border 0 #ffffffff #00000000
423menu color sel 7 #ff000000 #ffffffff
424menu color title 0 #ffffffff #00000000
425menu color tabmsg 0 #ffffffff #00000000
426menu color unsel 0 #ffffffff #00000000
427menu color hotsel 0 #ff000000 #ffffffff
428menu color hotkey 7 #ffffffff #ff000000
429menu color timeout_msg 0 #ffffffff #00000000
430menu color timeout 0 #ffffffff #00000000
431menu color cmdline 0 #ffffffff #00000000
432menu hidden
433menu clear
434""" % args
435
436 def __get_image_stanza(self, is_xen, isDracut, **args):
437 if isDracut:
438 args["rootlabel"] = "live:CDLABEL=%(fslabel)s" % args
439 else:
440 args["rootlabel"] = "CDLABEL=%(fslabel)s" % args
441 if not is_xen:
442 template = """label %(short)s
443 menu label %(long)s
444 kernel vmlinuz%(index)s
445 append initrd=initrd%(index)s.img root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
446"""
447 else:
448 template = """label %(short)s
449 menu label %(long)s
450 kernel mboot.c32
451 append xen%(index)s.gz --- vmlinuz%(index)s root=%(rootlabel)s rootfstype=iso9660 %(liveargs)s %(extra)s --- initrd%(index)s.img
452"""
453 return template % args
454
455 def __get_image_stanzas(self, isodir):
456 versions = []
457 kernels = self._get_kernel_versions()
458 for kernel in kernels:
459 for version in kernels[kernel]:
460 versions.append(version)
461
462 if not versions:
463 raise CreatorError("Unable to find valid kernels, "
464 "please check the repo")
465
466 kernel_options = self._get_kernel_options()
467
468 """ menu can be customized highly, the format is:
469
470 short_name1:long_name1:extra_opts1;short_name2:long_name2:extra_opts2
471
472 e.g.: autoinst:InstallationOnly:systemd.unit=installer-graphical.service
473 but in order to keep compatible with old format, these are still ok:
474
475 liveinst autoinst
476 liveinst;autoinst
477 liveinst::;autoinst::
478 """
479 oldmenus = {"basic": {
480 "short": "basic",
481 "long": "Installation Only (Text based)",
482 "extra": "basic nosplash 4"
483 },
484 "liveinst": {
485 "short": "liveinst",
486 "long": "Installation Only",
487 "extra": "liveinst nosplash 4"
488 },
489 "autoinst": {
490 "short": "autoinst",
491 "long": "Autoinstall (Deletes all existing content)",
492 "extra": "autoinst nosplash 4"
493 },
494 "netinst": {
495 "short": "netinst",
496 "long": "Network Installation",
497 "extra": "netinst 4"
498 },
499 "verify": {
500 "short": "check",
501 "long": "Verify and",
502 "extra": "check"
503 }
504 }
505 menu_options = self._get_menu_options()
506 menus = menu_options.split(";")
507 for i in range(len(menus)):
508 menus[i] = menus[i].split(":")
509 if len(menus) == 1 and len(menus[0]) == 1:
510 """ Keep compatible with the old usage way """
511 menus = menu_options.split()
512 for i in range(len(menus)):
513 menus[i] = [menus[i]]
514
515 cfg = ""
516
517 default_version = None
518 default_index = None
519 index = "0"
520 netinst = None
521 for version in versions:
522 (is_xen, isDracut) = self.__copy_kernel_and_initramfs(isodir, version, index)
523 if index == "0":
524 self._isDracut = isDracut
525
526 default = self.__is_default_kernel(kernel, kernels)
527
528 if default:
529 long = "Boot %s" % self.distro_name
530 elif kernel.startswith("kernel-"):
531 long = "Boot %s(%s)" % (self.name, kernel[7:])
532 else:
533 long = "Boot %s(%s)" % (self.name, kernel)
534
535 oldmenus["verify"]["long"] = "%s %s" % (oldmenus["verify"]["long"],
536 long)
537 # tell dracut not to ask for LUKS passwords or activate mdraid sets
538 if isDracut:
539 kern_opts = kernel_options + " rd.luks=0 rd.md=0 rd.dm=0"
540 else:
541 kern_opts = kernel_options
542
543 cfg += self.__get_image_stanza(is_xen, isDracut,
544 fslabel = self.fslabel,
545 liveargs = kern_opts,
546 long = long,
547 short = "linux" + index,
548 extra = "",
549 index = index)
550
551 if default:
552 cfg += "menu default\n"
553 default_version = version
554 default_index = index
555
556 for menu in menus:
557 if not menu[0]:
558 continue
559 short = menu[0] + index
560
561 if len(menu) >= 2:
562 long = menu[1]
563 else:
564 if menu[0] in oldmenus.keys():
565 if menu[0] == "verify" and not self._has_checkisomd5():
566 continue
567 if menu[0] == "netinst":
568 netinst = oldmenus[menu[0]]
569 continue
570 long = oldmenus[menu[0]]["long"]
571 extra = oldmenus[menu[0]]["extra"]
572 else:
573 long = short.upper() + " X" + index
574 extra = ""
575
576 if len(menu) >= 3:
577 extra = menu[2]
578
579 cfg += self.__get_image_stanza(is_xen, isDracut,
580 fslabel = self.fslabel,
581 liveargs = kernel_options,
582 long = long,
583 short = short,
584 extra = extra,
585 index = index)
586
587 index = str(int(index) + 1)
588
589 if not default_version:
590 default_version = versions[0]
591 if not default_index:
592 default_index = "0"
593
594 if netinst:
595 cfg += self.__get_image_stanza(is_xen, isDracut,
596 fslabel = self.fslabel,
597 liveargs = kernel_options,
598 long = netinst["long"],
599 short = netinst["short"],
600 extra = netinst["extra"],
601 index = default_index)
602
603 return cfg
604
605 def __get_memtest_stanza(self, isodir):
606 memtest = glob.glob(self._instroot + "/boot/memtest86*")
607 if not memtest:
608 return ""
609
610 shutil.copyfile(memtest[0], isodir + "/isolinux/memtest")
611
612 return """label memtest
613 menu label Memory Test
614 kernel memtest
615"""
616
617 def __get_local_stanza(self, isodir):
618 return """label local
619 menu label Boot from local drive
620 localboot 0xffff
621"""
622
623 def _configure_syslinux_bootloader(self, isodir):
624 """configure the boot loader"""
625 fs_related.makedirs(isodir + "/isolinux")
626
627 menu = self.__find_syslinux_menu()
628
629 self.__copy_syslinux_files(isodir, menu,
630 self.__find_syslinux_mboot())
631
632 background = ""
633 if self.__copy_syslinux_background(isodir + "/isolinux/splash.jpg"):
634 background = "menu background splash.jpg"
635
636 cfg = self.__get_basic_syslinux_config(menu = menu,
637 background = background,
638 name = self.name,
639 timeout = self._timeout * 10,
640 distroname = self.distro_name)
641
642 cfg += self.__get_image_stanzas(isodir)
643 cfg += self.__get_memtest_stanza(isodir)
644 cfg += self.__get_local_stanza(isodir)
645 cfg += self._get_isolinux_stanzas(isodir)
646
647 cfgf = open(isodir + "/isolinux/isolinux.cfg", "w")
648 cfgf.write(cfg)
649 cfgf.close()
650
651 def __copy_efi_files(self, isodir):
652 if not os.path.exists(self._instroot + "/boot/efi/EFI/redhat/grub.efi"):
653 return False
654 shutil.copy(self._instroot + "/boot/efi/EFI/redhat/grub.efi",
655 isodir + "/EFI/boot/grub.efi")
656 shutil.copy(self._instroot + "/boot/grub/splash.xpm.gz",
657 isodir + "/EFI/boot/splash.xpm.gz")
658
659 return True
660
661 def __get_basic_efi_config(self, **args):
662 return """
663default=0
664splashimage=/EFI/boot/splash.xpm.gz
665timeout %(timeout)d
666hiddenmenu
667
668""" %args
669
670 def __get_efi_image_stanza(self, **args):
671 return """title %(long)s
672 kernel /EFI/boot/vmlinuz%(index)s root=CDLABEL=%(fslabel)s rootfstype=iso9660 %(liveargs)s %(extra)s
673 initrd /EFI/boot/initrd%(index)s.img
674""" %args
675
676 def __get_efi_image_stanzas(self, isodir, name):
677 # FIXME: this only supports one kernel right now...
678
679 kernel_options = self._get_kernel_options()
680 checkisomd5 = self._has_checkisomd5()
681
682 cfg = ""
683
684 for index in range(0, 9):
685 # we don't support xen kernels
686 if os.path.exists("%s/EFI/boot/xen%d.gz" %(isodir, index)):
687 continue
688 cfg += self.__get_efi_image_stanza(fslabel = self.fslabel,
689 liveargs = kernel_options,
690 long = name,
691 extra = "", index = index)
692 if checkisomd5:
693 cfg += self.__get_efi_image_stanza(
694 fslabel = self.fslabel,
695 liveargs = kernel_options,
696 long = "Verify and Boot " + name,
697 extra = "check",
698 index = index)
699 break
700
701 return cfg
702
703 def _configure_efi_bootloader(self, isodir):
704 """Set up the configuration for an EFI bootloader"""
705 fs_related.makedirs(isodir + "/EFI/boot")
706
707 if not self.__copy_efi_files(isodir):
708 shutil.rmtree(isodir + "/EFI")
709 return
710
711 for f in os.listdir(isodir + "/isolinux"):
712 os.link("%s/isolinux/%s" %(isodir, f),
713 "%s/EFI/boot/%s" %(isodir, f))
714
715
716 cfg = self.__get_basic_efi_config(name = self.name,
717 timeout = self._timeout)
718 cfg += self.__get_efi_image_stanzas(isodir, self.name)
719
720 cfgf = open(isodir + "/EFI/boot/grub.conf", "w")
721 cfgf.write(cfg)
722 cfgf.close()
723
724 # first gen mactel machines get the bootloader name wrong apparently
725 if rpmmisc.getBaseArch() == "i386":
726 os.link(isodir + "/EFI/boot/grub.efi",
727 isodir + "/EFI/boot/boot.efi")
728 os.link(isodir + "/EFI/boot/grub.conf",
729 isodir + "/EFI/boot/boot.conf")
730
731 # for most things, we want them named boot$efiarch
732 efiarch = {"i386": "ia32", "x86_64": "x64"}
733 efiname = efiarch[rpmmisc.getBaseArch()]
734 os.rename(isodir + "/EFI/boot/grub.efi",
735 isodir + "/EFI/boot/boot%s.efi" %(efiname,))
736 os.link(isodir + "/EFI/boot/grub.conf",
737 isodir + "/EFI/boot/boot%s.conf" %(efiname,))
738
739
740 def _configure_bootloader(self, isodir):
741 self._configure_syslinux_bootloader(isodir)
742 self._configure_efi_bootloader(isodir)
743
744arch = "i386"
745if arch in ("i386", "x86_64"):
746 LiveCDImageCreator = x86LiveImageCreator
747elif arch.startswith("arm"):
748 LiveCDImageCreator = LiveImageCreatorBase
749else:
750 raise CreatorError("Architecture not supported!")
diff --git a/scripts/lib/mic/imager/liveusb.py b/scripts/lib/mic/imager/liveusb.py
new file mode 100644
index 0000000000..a909928a4c
--- /dev/null
+++ b/scripts/lib/mic/imager/liveusb.py
@@ -0,0 +1,308 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import re
21
22from mic import msger
23from mic.utils import misc, fs_related, runner
24from mic.utils.errors import CreatorError, MountError
25from mic.utils.partitionedfs import PartitionedMount
26from mic.imager.livecd import LiveCDImageCreator
27
28
29class LiveUSBImageCreator(LiveCDImageCreator):
30 def __init__(self, *args):
31 LiveCDImageCreator.__init__(self, *args)
32
33 self._dep_checks.extend(["kpartx", "parted"])
34
35 # remove dependency of genisoimage in parent class
36 if "genisoimage" in self._dep_checks:
37 self._dep_checks.remove("genisoimage")
38
39 def _create_usbimg(self, isodir):
40 overlaysizemb = 64 #default
41 #skipcompress = self.skip_compression?
42 fstype = "vfat"
43 homesizemb=0
44 swapsizemb=0
45 homefile="home.img"
46 plussize=128
47 kernelargs=None
48
49 if fstype == 'vfat':
50 if overlaysizemb > 2047:
51 raise CreatorError("Can't have an overlay of 2048MB or "
52 "greater on VFAT")
53
54 if homesizemb > 2047:
55 raise CreatorError("Can't have an home overlay of 2048MB or "
56 "greater on VFAT")
57
58 if swapsizemb > 2047:
59 raise CreatorError("Can't have an swap overlay of 2048MB or "
60 "greater on VFAT")
61
62 livesize = misc.get_file_size(isodir + "/LiveOS")
63
64 usbimgsize = (overlaysizemb + \
65 homesizemb + \
66 swapsizemb + \
67 livesize + \
68 plussize) * 1024L * 1024L
69
70 disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \
71 % (self._outdir, self.name),
72 usbimgsize)
73 usbmnt = self._mkdtemp("usb-mnt")
74 usbloop = PartitionedMount(usbmnt)
75 usbloop.add_disk('/dev/sdb', disk)
76
77 usbloop.add_partition(usbimgsize/1024/1024,
78 "/dev/sdb",
79 "/",
80 fstype,
81 boot=True)
82
83 usbloop.mount()
84
85 try:
86 fs_related.makedirs(usbmnt + "/LiveOS")
87
88 if os.path.exists(isodir + "/LiveOS/squashfs.img"):
89 shutil.copyfile(isodir + "/LiveOS/squashfs.img",
90 usbmnt + "/LiveOS/squashfs.img")
91 else:
92 fs_related.mksquashfs(os.path.dirname(self._image),
93 usbmnt + "/LiveOS/squashfs.img")
94
95 if os.path.exists(isodir + "/LiveOS/osmin.img"):
96 shutil.copyfile(isodir + "/LiveOS/osmin.img",
97 usbmnt + "/LiveOS/osmin.img")
98
99 if fstype == "vfat" or fstype == "msdos":
100 uuid = usbloop.partitions[0]['mount'].uuid
101 label = usbloop.partitions[0]['mount'].fslabel
102 usblabel = "UUID=%s-%s" % (uuid[0:4], uuid[4:8])
103 overlaysuffix = "-%s-%s-%s" % (label, uuid[0:4], uuid[4:8])
104 else:
105 diskmount = usbloop.partitions[0]['mount']
106 usblabel = "UUID=%s" % diskmount.uuid
107 overlaysuffix = "-%s-%s" % (diskmount.fslabel, diskmount.uuid)
108
109 args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"]
110 rc = runner.show(args)
111 if rc:
112 raise CreatorError("Can't copy isolinux directory %s" \
113 % (isodir + "/isolinux/*"))
114
115 if os.path.isfile("/usr/share/syslinux/isolinux.bin"):
116 syslinux_path = "/usr/share/syslinux"
117 elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"):
118 syslinux_path = "/usr/lib/syslinux"
119 else:
120 raise CreatorError("syslinux not installed : "
121 "cannot find syslinux installation path")
122
123 for f in ("isolinux.bin", "vesamenu.c32"):
124 path = os.path.join(syslinux_path, f)
125 if os.path.isfile(path):
126 args = ['cp', path, usbmnt + "/syslinux/"]
127 rc = runner.show(args)
128 if rc:
129 raise CreatorError("Can't copy syslinux file " + path)
130 else:
131 raise CreatorError("syslinux not installed: "
132 "syslinux file %s not found" % path)
133
134 fd = open(isodir + "/isolinux/isolinux.cfg", "r")
135 text = fd.read()
136 fd.close()
137 pattern = re.compile('CDLABEL=[^ ]*')
138 text = pattern.sub(usblabel, text)
139 pattern = re.compile('rootfstype=[^ ]*')
140 text = pattern.sub("rootfstype=" + fstype, text)
141 if kernelargs:
142 text = text.replace("rd.live.image", "rd.live.image " + kernelargs)
143
144 if overlaysizemb > 0:
145 msger.info("Initializing persistent overlay file")
146 overfile = "overlay" + overlaysuffix
147 if fstype == "vfat":
148 args = ['dd',
149 "if=/dev/zero",
150 "of=" + usbmnt + "/LiveOS/" + overfile,
151 "count=%d" % overlaysizemb,
152 "bs=1M"]
153 else:
154 args = ['dd',
155 "if=/dev/null",
156 "of=" + usbmnt + "/LiveOS/" + overfile,
157 "count=1",
158 "bs=1M",
159 "seek=%d" % overlaysizemb]
160 rc = runner.show(args)
161 if rc:
162 raise CreatorError("Can't create overlay file")
163 text = text.replace("rd.live.image", "rd.live.image rd.live.overlay=" + usblabel)
164 text = text.replace(" ro ", " rw ")
165
166 if swapsizemb > 0:
167 msger.info("Initializing swap file")
168 swapfile = usbmnt + "/LiveOS/" + "swap.img"
169 args = ['dd',
170 "if=/dev/zero",
171 "of=" + swapfile,
172 "count=%d" % swapsizemb,
173 "bs=1M"]
174 rc = runner.show(args)
175 if rc:
176 raise CreatorError("Can't create swap file")
177 args = ["mkswap", "-f", swapfile]
178 rc = runner.show(args)
179 if rc:
180 raise CreatorError("Can't mkswap on swap file")
181
182 if homesizemb > 0:
183 msger.info("Initializing persistent /home")
184 homefile = usbmnt + "/LiveOS/" + homefile
185 if fstype == "vfat":
186 args = ['dd',
187 "if=/dev/zero",
188 "of=" + homefile,
189 "count=%d" % homesizemb,
190 "bs=1M"]
191 else:
192 args = ['dd',
193 "if=/dev/null",
194 "of=" + homefile,
195 "count=1",
196 "bs=1M",
197 "seek=%d" % homesizemb]
198 rc = runner.show(args)
199 if rc:
200 raise CreatorError("Can't create home file")
201
202 mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype)
203 if fstype == "ext2" or fstype == "ext3":
204 args = [mkfscmd, "-F", "-j", homefile]
205 else:
206 args = [mkfscmd, homefile]
207 rc = runner.show(args)
208 if rc:
209 raise CreatorError("Can't mke2fs home file")
210 if fstype == "ext2" or fstype == "ext3":
211 tune2fs = fs_related.find_binary_path("tune2fs")
212 args = [tune2fs,
213 "-c0",
214 "-i0",
215 "-ouser_xattr,acl",
216 homefile]
217 rc = runner.show(args)
218 if rc:
219 raise CreatorError("Can't tune2fs home file")
220
221 if fstype == "vfat" or fstype == "msdos":
222 syslinuxcmd = fs_related.find_binary_path("syslinux")
223 syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg"
224 args = [syslinuxcmd,
225 "-d",
226 "syslinux",
227 usbloop.partitions[0]["device"]]
228
229 elif fstype == "ext2" or fstype == "ext3":
230 extlinuxcmd = fs_related.find_binary_path("extlinux")
231 syslinuxcfg = usbmnt + "/syslinux/extlinux.conf"
232 args = [extlinuxcmd,
233 "-i",
234 usbmnt + "/syslinux"]
235
236 else:
237 raise CreatorError("Invalid file system type: %s" % (fstype))
238
239 os.unlink(usbmnt + "/syslinux/isolinux.cfg")
240 fd = open(syslinuxcfg, "w")
241 fd.write(text)
242 fd.close()
243 rc = runner.show(args)
244 if rc:
245 raise CreatorError("Can't install boot loader.")
246
247 finally:
248 usbloop.unmount()
249 usbloop.cleanup()
250
251 # Need to do this after image is unmounted and device mapper is closed
252 msger.info("set MBR")
253 mbrfile = "/usr/lib/syslinux/mbr.bin"
254 if not os.path.exists(mbrfile):
255 mbrfile = "/usr/share/syslinux/mbr.bin"
256 if not os.path.exists(mbrfile):
257 raise CreatorError("mbr.bin file didn't exist.")
258 mbrsize = os.path.getsize(mbrfile)
259 outimg = "%s/%s.usbimg" % (self._outdir, self.name)
260
261 args = ['dd',
262 "if=" + mbrfile,
263 "of=" + outimg,
264 "seek=0",
265 "conv=notrunc",
266 "bs=1",
267 "count=%d" % (mbrsize)]
268 rc = runner.show(args)
269 if rc:
270 raise CreatorError("Can't set MBR.")
271
272 def _stage_final_image(self):
273 try:
274 isodir = self._get_isodir()
275 fs_related.makedirs(isodir + "/LiveOS")
276
277 minimal_size = self._resparse()
278
279 if not self.skip_minimize:
280 fs_related.create_image_minimizer(isodir + "/LiveOS/osmin.img",
281 self._image,
282 minimal_size)
283
284 if self.skip_compression:
285 shutil.move(self._image,
286 isodir + "/LiveOS/ext3fs.img")
287 else:
288 fs_related.makedirs(os.path.join(
289 os.path.dirname(self._image),
290 "LiveOS"))
291 shutil.move(self._image,
292 os.path.join(os.path.dirname(self._image),
293 "LiveOS", "ext3fs.img"))
294 fs_related.mksquashfs(os.path.dirname(self._image),
295 isodir + "/LiveOS/squashfs.img")
296
297 self._create_usbimg(isodir)
298
299 if self.pack_to:
300 usbimg = os.path.join(self._outdir, self.name + ".usbimg")
301 packimg = os.path.join(self._outdir, self.pack_to)
302 misc.packing(packimg, usbimg)
303 os.unlink(usbimg)
304
305 finally:
306 shutil.rmtree(isodir, ignore_errors = True)
307 self._set_isodir(None)
308
diff --git a/scripts/lib/mic/imager/loop.py b/scripts/lib/mic/imager/loop.py
new file mode 100644
index 0000000000..4d05ef271d
--- /dev/null
+++ b/scripts/lib/mic/imager/loop.py
@@ -0,0 +1,418 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import glob
20import shutil
21
22from mic import kickstart, msger
23from mic.utils.errors import CreatorError, MountError
24from mic.utils import misc, runner, fs_related as fs
25from mic.imager.baseimager import BaseImageCreator
26
27
28# The maximum string length supported for LoopImageCreator.fslabel
29FSLABEL_MAXLEN = 32
30
31
32def save_mountpoints(fpath, loops, arch = None):
33 """Save mount points mapping to file
34
35 :fpath, the xml file to store partition info
36 :loops, dict of partition info
37 :arch, image arch
38 """
39
40 if not fpath or not loops:
41 return
42
43 from xml.dom import minidom
44 doc = minidom.Document()
45 imgroot = doc.createElement("image")
46 doc.appendChild(imgroot)
47 if arch:
48 imgroot.setAttribute('arch', arch)
49 for loop in loops:
50 part = doc.createElement("partition")
51 imgroot.appendChild(part)
52 for (key, val) in loop.items():
53 if isinstance(val, fs.Mount):
54 continue
55 part.setAttribute(key, str(val))
56
57 with open(fpath, 'w') as wf:
58 wf.write(doc.toprettyxml(indent=' '))
59
60 return
61
62def load_mountpoints(fpath):
63 """Load mount points mapping from file
64
65 :fpath, file path to load
66 """
67
68 if not fpath:
69 return
70
71 from xml.dom import minidom
72 mount_maps = []
73 with open(fpath, 'r') as rf:
74 dom = minidom.parse(rf)
75 imgroot = dom.documentElement
76 for part in imgroot.getElementsByTagName("partition"):
77 p = dict(part.attributes.items())
78
79 try:
80 mp = (p['mountpoint'], p['label'], p['name'],
81 int(p['size']), p['fstype'])
82 except KeyError:
83 msger.warning("Wrong format line in file: %s" % fpath)
84 except ValueError:
85 msger.warning("Invalid size '%s' in file: %s" % (p['size'], fpath))
86 else:
87 mount_maps.append(mp)
88
89 return mount_maps
90
91class LoopImageCreator(BaseImageCreator):
92 """Installs a system into a loopback-mountable filesystem image.
93
94 LoopImageCreator is a straightforward ImageCreator subclass; the system
95 is installed into an ext3 filesystem on a sparse file which can be
96 subsequently loopback-mounted.
97
98 When specifying multiple partitions in kickstart file, each partition
99 will be created as a separated loop image.
100 """
101
102 def __init__(self, creatoropts=None, pkgmgr=None,
103 compress_image=None,
104 shrink_image=False):
105 """Initialize a LoopImageCreator instance.
106
107 This method takes the same arguments as ImageCreator.__init__()
108 with the addition of:
109
110 fslabel -- A string used as a label for any filesystems created.
111 """
112
113 BaseImageCreator.__init__(self, creatoropts, pkgmgr)
114
115 self.compress_image = compress_image
116 self.shrink_image = shrink_image
117
118 self.__fslabel = None
119 self.fslabel = self.name
120
121 self.__blocksize = 4096
122 if self.ks:
123 self.__fstype = kickstart.get_image_fstype(self.ks,
124 "ext3")
125 self.__fsopts = kickstart.get_image_fsopts(self.ks,
126 "defaults,noatime")
127
128 allloops = []
129 for part in sorted(kickstart.get_partitions(self.ks),
130 key=lambda p: p.mountpoint):
131 if part.fstype == "swap":
132 continue
133
134 label = part.label
135 mp = part.mountpoint
136 if mp == '/':
137 # the base image
138 if not label:
139 label = self.name
140 else:
141 mp = mp.rstrip('/')
142 if not label:
143 msger.warning('no "label" specified for loop img at %s'
144 ', use the mountpoint as the name' % mp)
145 label = mp.split('/')[-1]
146
147 imgname = misc.strip_end(label, '.img') + '.img'
148 allloops.append({
149 'mountpoint': mp,
150 'label': label,
151 'name': imgname,
152 'size': part.size or 4096L * 1024 * 1024,
153 'fstype': part.fstype or 'ext3',
154 'extopts': part.extopts or None,
155 'loop': None, # to be created in _mount_instroot
156 })
157 self._instloops = allloops
158
159 else:
160 self.__fstype = None
161 self.__fsopts = None
162 self._instloops = []
163
164 self.__imgdir = None
165
166 if self.ks:
167 self.__image_size = kickstart.get_image_size(self.ks,
168 4096L * 1024 * 1024)
169 else:
170 self.__image_size = 0
171
172 self._img_name = self.name + ".img"
173
174 def get_image_names(self):
175 if not self._instloops:
176 return None
177
178 return [lo['name'] for lo in self._instloops]
179
180 def _set_fstype(self, fstype):
181 self.__fstype = fstype
182
183 def _set_image_size(self, imgsize):
184 self.__image_size = imgsize
185
186
187 #
188 # Properties
189 #
190 def __get_fslabel(self):
191 if self.__fslabel is None:
192 return self.name
193 else:
194 return self.__fslabel
195 def __set_fslabel(self, val):
196 if val is None:
197 self.__fslabel = None
198 else:
199 self.__fslabel = val[:FSLABEL_MAXLEN]
200 #A string used to label any filesystems created.
201 #
202 #Some filesystems impose a constraint on the maximum allowed size of the
203 #filesystem label. In the case of ext3 it's 16 characters, but in the case
204 #of ISO9660 it's 32 characters.
205 #
206 #mke2fs silently truncates the label, but mkisofs aborts if the label is
207 #too long. So, for convenience sake, any string assigned to this attribute
208 #is silently truncated to FSLABEL_MAXLEN (32) characters.
209 fslabel = property(__get_fslabel, __set_fslabel)
210
211 def __get_image(self):
212 if self.__imgdir is None:
213 raise CreatorError("_image is not valid before calling mount()")
214 return os.path.join(self.__imgdir, self._img_name)
215 #The location of the image file.
216 #
217 #This is the path to the filesystem image. Subclasses may use this path
218 #in order to package the image in _stage_final_image().
219 #
220 #Note, this directory does not exist before ImageCreator.mount() is called.
221 #
222 #Note also, this is a read-only attribute.
223 _image = property(__get_image)
224
225 def __get_blocksize(self):
226 return self.__blocksize
227 def __set_blocksize(self, val):
228 if self._instloops:
229 raise CreatorError("_blocksize must be set before calling mount()")
230 try:
231 self.__blocksize = int(val)
232 except ValueError:
233 raise CreatorError("'%s' is not a valid integer value "
234 "for _blocksize" % val)
235 #The block size used by the image's filesystem.
236 #
237 #This is the block size used when creating the filesystem image. Subclasses
238 #may change this if they wish to use something other than a 4k block size.
239 #
240 #Note, this attribute may only be set before calling mount().
241 _blocksize = property(__get_blocksize, __set_blocksize)
242
243 def __get_fstype(self):
244 return self.__fstype
245 def __set_fstype(self, val):
246 if val != "ext2" and val != "ext3":
247 raise CreatorError("Unknown _fstype '%s' supplied" % val)
248 self.__fstype = val
249 #The type of filesystem used for the image.
250 #
251 #This is the filesystem type used when creating the filesystem image.
252 #Subclasses may change this if they wish to use something other ext3.
253 #
254 #Note, only ext2 and ext3 are currently supported.
255 #
256 #Note also, this attribute may only be set before calling mount().
257 _fstype = property(__get_fstype, __set_fstype)
258
259 def __get_fsopts(self):
260 return self.__fsopts
261 def __set_fsopts(self, val):
262 self.__fsopts = val
263 #Mount options of filesystem used for the image.
264 #
265 #This can be specified by --fsoptions="xxx,yyy" in part command in
266 #kickstart file.
267 _fsopts = property(__get_fsopts, __set_fsopts)
268
269
270 #
271 # Helpers for subclasses
272 #
273 def _resparse(self, size=None):
274 """Rebuild the filesystem image to be as sparse as possible.
275
276 This method should be used by subclasses when staging the final image
277 in order to reduce the actual space taken up by the sparse image file
278 to be as little as possible.
279
280 This is done by resizing the filesystem to the minimal size (thereby
281 eliminating any space taken up by deleted files) and then resizing it
282 back to the supplied size.
283
284 size -- the size in, in bytes, which the filesystem image should be
285 resized to after it has been minimized; this defaults to None,
286 causing the original size specified by the kickstart file to
287 be used (or 4GiB if not specified in the kickstart).
288 """
289 minsize = 0
290 for item in self._instloops:
291 if item['name'] == self._img_name:
292 minsize = item['loop'].resparse(size)
293 else:
294 item['loop'].resparse(size)
295
296 return minsize
297
298 def _base_on(self, base_on=None):
299 if base_on and self._image != base_on:
300 shutil.copyfile(base_on, self._image)
301
302 def _check_imgdir(self):
303 if self.__imgdir is None:
304 self.__imgdir = self._mkdtemp()
305
306
307 #
308 # Actual implementation
309 #
310 def _mount_instroot(self, base_on=None):
311
312 if base_on and os.path.isfile(base_on):
313 self.__imgdir = os.path.dirname(base_on)
314 imgname = os.path.basename(base_on)
315 self._base_on(base_on)
316 self._set_image_size(misc.get_file_size(self._image))
317
318 # here, self._instloops must be []
319 self._instloops.append({
320 "mountpoint": "/",
321 "label": self.name,
322 "name": imgname,
323 "size": self.__image_size or 4096L,
324 "fstype": self.__fstype or "ext3",
325 "extopts": None,
326 "loop": None
327 })
328
329 self._check_imgdir()
330
331 for loop in self._instloops:
332 fstype = loop['fstype']
333 mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/'))
334 size = loop['size'] * 1024L * 1024L
335 imgname = loop['name']
336
337 if fstype in ("ext2", "ext3", "ext4"):
338 MyDiskMount = fs.ExtDiskMount
339 elif fstype == "btrfs":
340 MyDiskMount = fs.BtrfsDiskMount
341 elif fstype in ("vfat", "msdos"):
342 MyDiskMount = fs.VfatDiskMount
343 else:
344 msger.error('Cannot support fstype: %s' % fstype)
345
346 loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk(
347 os.path.join(self.__imgdir, imgname),
348 size),
349 mp,
350 fstype,
351 self._blocksize,
352 loop['label'])
353
354 if fstype in ("ext2", "ext3", "ext4"):
355 loop['loop'].extopts = loop['extopts']
356
357 try:
358 msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp))
359 fs.makedirs(mp)
360 loop['loop'].mount()
361 except MountError, e:
362 raise
363
364 def _unmount_instroot(self):
365 for item in reversed(self._instloops):
366 try:
367 item['loop'].cleanup()
368 except:
369 pass
370
371 def _stage_final_image(self):
372
373 if self.pack_to or self.shrink_image:
374 self._resparse(0)
375 else:
376 self._resparse()
377
378 for item in self._instloops:
379 imgfile = os.path.join(self.__imgdir, item['name'])
380 if item['fstype'] == "ext4":
381 runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s '
382 % imgfile)
383 if self.compress_image:
384 misc.compressing(imgfile, self.compress_image)
385
386 if not self.pack_to:
387 for item in os.listdir(self.__imgdir):
388 shutil.move(os.path.join(self.__imgdir, item),
389 os.path.join(self._outdir, item))
390 else:
391 msger.info("Pack all loop images together to %s" % self.pack_to)
392 dstfile = os.path.join(self._outdir, self.pack_to)
393 misc.packing(dstfile, self.__imgdir)
394
395 if self.pack_to:
396 mountfp_xml = os.path.splitext(self.pack_to)[0]
397 mountfp_xml = misc.strip_end(mountfp_xml, '.tar') + ".xml"
398 else:
399 mountfp_xml = self.name + ".xml"
400 # save mount points mapping file to xml
401 save_mountpoints(os.path.join(self._outdir, mountfp_xml),
402 self._instloops,
403 self.target_arch)
404
405 def copy_attachment(self):
406 if not hasattr(self, '_attachment') or not self._attachment:
407 return
408
409 self._check_imgdir()
410
411 msger.info("Copying attachment files...")
412 for item in self._attachment:
413 if not os.path.exists(item):
414 continue
415 dpath = os.path.join(self.__imgdir, os.path.basename(item))
416 msger.verbose("Copy attachment %s to %s" % (item, dpath))
417 shutil.copy(item, dpath)
418
diff --git a/scripts/lib/mic/imager/raw.py b/scripts/lib/mic/imager/raw.py
new file mode 100644
index 0000000000..838191a6f1
--- /dev/null
+++ b/scripts/lib/mic/imager/raw.py
@@ -0,0 +1,501 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import stat
20import shutil
21
22from mic import kickstart, msger
23from mic.utils import fs_related, runner, misc
24from mic.utils.partitionedfs import PartitionedMount
25from mic.utils.errors import CreatorError, MountError
26from mic.imager.baseimager import BaseImageCreator
27
28
29class RawImageCreator(BaseImageCreator):
30 """Installs a system into a file containing a partitioned disk image.
31
32 ApplianceImageCreator is an advanced ImageCreator subclass; a sparse file
33 is formatted with a partition table, each partition loopback mounted
34 and the system installed into an virtual disk. The disk image can
35 subsequently be booted in a virtual machine or accessed with kpartx
36 """
37
38 def __init__(self, creatoropts=None, pkgmgr=None, compress_image=None, generate_bmap=None, fstab_entry="uuid"):
39 """Initialize a ApplianceImageCreator instance.
40
41 This method takes the same arguments as ImageCreator.__init__()
42 """
43 BaseImageCreator.__init__(self, creatoropts, pkgmgr)
44
45 self.__instloop = None
46 self.__imgdir = None
47 self.__disks = {}
48 self.__disk_format = "raw"
49 self._disk_names = []
50 self._ptable_format = self.ks.handler.bootloader.ptable
51 self.vmem = 512
52 self.vcpu = 1
53 self.checksum = False
54 self.use_uuid = fstab_entry == "uuid"
55 self.appliance_version = None
56 self.appliance_release = None
57 self.compress_image = compress_image
58 self.bmap_needed = generate_bmap
59 self._need_extlinux = not kickstart.use_installerfw(self.ks, "extlinux")
60 #self.getsource = False
61 #self.listpkg = False
62
63 self._dep_checks.extend(["sync", "kpartx", "parted"])
64 if self._need_extlinux:
65 self._dep_checks.extend(["extlinux"])
66
67 def configure(self, repodata = None):
68 import subprocess
69 def chroot():
70 os.chroot(self._instroot)
71 os.chdir("/")
72
73 if os.path.exists(self._instroot + "/usr/bin/Xorg"):
74 subprocess.call(["/bin/chmod", "u+s", "/usr/bin/Xorg"],
75 preexec_fn = chroot)
76
77 BaseImageCreator.configure(self, repodata)
78
79 def _get_fstab(self):
80 if kickstart.use_installerfw(self.ks, "fstab"):
81 # The fstab file will be generated by installer framework scripts
82 # instead.
83 return None
84
85 s = ""
86 for mp in self.__instloop.mountOrder:
87 p = None
88 for p1 in self.__instloop.partitions:
89 if p1['mountpoint'] == mp:
90 p = p1
91 break
92
93 if self.use_uuid and p['uuid']:
94 device = "UUID=%s" % p['uuid']
95 else:
96 device = "/dev/%s%-d" % (p['disk_name'], p['num'])
97
98 s += "%(device)s %(mountpoint)s %(fstype)s %(fsopts)s 0 0\n" % {
99 'device': device,
100 'mountpoint': p['mountpoint'],
101 'fstype': p['fstype'],
102 'fsopts': "defaults,noatime" if not p['fsopts'] else p['fsopts']}
103
104 if p['mountpoint'] == "/":
105 for subvol in self.__instloop.subvolumes:
106 if subvol['mountpoint'] == "/":
107 continue
108 s += "%(device)s %(mountpoint)s %(fstype)s %(fsopts)s 0 0\n" % {
109 'device': "/dev/%s%-d" % (p['disk_name'], p['num']),
110 'mountpoint': subvol['mountpoint'],
111 'fstype': p['fstype'],
112 'fsopts': "defaults,noatime" if not subvol['fsopts'] else subvol['fsopts']}
113
114 s += "devpts /dev/pts devpts gid=5,mode=620 0 0\n"
115 s += "tmpfs /dev/shm tmpfs defaults 0 0\n"
116 s += "proc /proc proc defaults 0 0\n"
117 s += "sysfs /sys sysfs defaults 0 0\n"
118 return s
119
120 def _create_mkinitrd_config(self):
121 """write to tell which modules to be included in initrd"""
122
123 mkinitrd = ""
124 mkinitrd += "PROBE=\"no\"\n"
125 mkinitrd += "MODULES+=\"ext3 ata_piix sd_mod libata scsi_mod\"\n"
126 mkinitrd += "rootfs=\"ext3\"\n"
127 mkinitrd += "rootopts=\"defaults\"\n"
128
129 msger.debug("Writing mkinitrd config %s/etc/sysconfig/mkinitrd" \
130 % self._instroot)
131 os.makedirs(self._instroot + "/etc/sysconfig/",mode=644)
132 cfg = open(self._instroot + "/etc/sysconfig/mkinitrd", "w")
133 cfg.write(mkinitrd)
134 cfg.close()
135
136 def _get_parts(self):
137 if not self.ks:
138 raise CreatorError("Failed to get partition info, "
139 "please check your kickstart setting.")
140
141 # Set a default partition if no partition is given out
142 if not self.ks.handler.partition.partitions:
143 partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
144 args = partstr.split()
145 pd = self.ks.handler.partition.parse(args[1:])
146 if pd not in self.ks.handler.partition.partitions:
147 self.ks.handler.partition.partitions.append(pd)
148
149 # partitions list from kickstart file
150 return kickstart.get_partitions(self.ks)
151
152 def get_disk_names(self):
153 """ Returns a list of physical target disk names (e.g., 'sdb') which
154 will be created. """
155
156 if self._disk_names:
157 return self._disk_names
158
159 #get partition info from ks handler
160 parts = self._get_parts()
161
162 for i in range(len(parts)):
163 if parts[i].disk:
164 disk_name = parts[i].disk
165 else:
166 raise CreatorError("Failed to create disks, no --ondisk "
167 "specified in partition line of ks file")
168
169 if parts[i].mountpoint and not parts[i].fstype:
170 raise CreatorError("Failed to create disks, no --fstype "
171 "specified for partition with mountpoint "
172 "'%s' in the ks file")
173
174 self._disk_names.append(disk_name)
175
176 return self._disk_names
177
178 def _full_name(self, name, extention):
179 """ Construct full file name for a file we generate. """
180 return "%s-%s.%s" % (self.name, name, extention)
181
182 def _full_path(self, path, name, extention):
183 """ Construct full file path to a file we generate. """
184 return os.path.join(path, self._full_name(name, extention))
185
186 #
187 # Actual implemention
188 #
189 def _mount_instroot(self, base_on = None):
190 parts = self._get_parts()
191 self.__instloop = PartitionedMount(self._instroot)
192
193 for p in parts:
194 self.__instloop.add_partition(int(p.size),
195 p.disk,
196 p.mountpoint,
197 p.fstype,
198 p.label,
199 fsopts = p.fsopts,
200 boot = p.active,
201 align = p.align,
202 part_type = p.part_type)
203
204 self.__instloop.layout_partitions(self._ptable_format)
205
206 # Create the disks
207 self.__imgdir = self._mkdtemp()
208 for disk_name, disk in self.__instloop.disks.items():
209 full_path = self._full_path(self.__imgdir, disk_name, "raw")
210 msger.debug("Adding disk %s as %s with size %s bytes" \
211 % (disk_name, full_path, disk['min_size']))
212
213 disk_obj = fs_related.SparseLoopbackDisk(full_path,
214 disk['min_size'])
215 self.__disks[disk_name] = disk_obj
216 self.__instloop.add_disk(disk_name, disk_obj)
217
218 self.__instloop.mount()
219 self._create_mkinitrd_config()
220
221 def _get_required_packages(self):
222 required_packages = BaseImageCreator._get_required_packages(self)
223 if self._need_extlinux:
224 if not self.target_arch or not self.target_arch.startswith("arm"):
225 required_packages += ["syslinux", "syslinux-extlinux"]
226 return required_packages
227
228 def _get_excluded_packages(self):
229 return BaseImageCreator._get_excluded_packages(self)
230
231 def _get_syslinux_boot_config(self):
232 rootdev = None
233 root_part_uuid = None
234 for p in self.__instloop.partitions:
235 if p['mountpoint'] == "/":
236 rootdev = "/dev/%s%-d" % (p['disk_name'], p['num'])
237 root_part_uuid = p['partuuid']
238
239 return (rootdev, root_part_uuid)
240
241 def _create_syslinux_config(self):
242
243 splash = os.path.join(self._instroot, "boot/extlinux")
244 if os.path.exists(splash):
245 splashline = "menu background splash.jpg"
246 else:
247 splashline = ""
248
249 (rootdev, root_part_uuid) = self._get_syslinux_boot_config()
250 options = self.ks.handler.bootloader.appendLine
251
252 #XXX don't hardcode default kernel - see livecd code
253 syslinux_conf = ""
254 syslinux_conf += "prompt 0\n"
255 syslinux_conf += "timeout 1\n"
256 syslinux_conf += "\n"
257 syslinux_conf += "default vesamenu.c32\n"
258 syslinux_conf += "menu autoboot Starting %s...\n" % self.distro_name
259 syslinux_conf += "menu hidden\n"
260 syslinux_conf += "\n"
261 syslinux_conf += "%s\n" % splashline
262 syslinux_conf += "menu title Welcome to %s!\n" % self.distro_name
263 syslinux_conf += "menu color border 0 #ffffffff #00000000\n"
264 syslinux_conf += "menu color sel 7 #ffffffff #ff000000\n"
265 syslinux_conf += "menu color title 0 #ffffffff #00000000\n"
266 syslinux_conf += "menu color tabmsg 0 #ffffffff #00000000\n"
267 syslinux_conf += "menu color unsel 0 #ffffffff #00000000\n"
268 syslinux_conf += "menu color hotsel 0 #ff000000 #ffffffff\n"
269 syslinux_conf += "menu color hotkey 7 #ffffffff #ff000000\n"
270 syslinux_conf += "menu color timeout_msg 0 #ffffffff #00000000\n"
271 syslinux_conf += "menu color timeout 0 #ffffffff #00000000\n"
272 syslinux_conf += "menu color cmdline 0 #ffffffff #00000000\n"
273
274 versions = []
275 kernels = self._get_kernel_versions()
276 symkern = "%s/boot/vmlinuz" % self._instroot
277
278 if os.path.lexists(symkern):
279 v = os.path.realpath(symkern).replace('%s-' % symkern, "")
280 syslinux_conf += "label %s\n" % self.distro_name.lower()
281 syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
282 syslinux_conf += "\tlinux ../vmlinuz\n"
283 if self._ptable_format == 'msdos':
284 rootstr = rootdev
285 else:
286 if not root_part_uuid:
287 raise MountError("Cannot find the root GPT partition UUID")
288 rootstr = "PARTUUID=%s" % root_part_uuid
289 syslinux_conf += "\tappend ro root=%s %s\n" % (rootstr, options)
290 syslinux_conf += "\tmenu default\n"
291 else:
292 for kernel in kernels:
293 for version in kernels[kernel]:
294 versions.append(version)
295
296 footlabel = 0
297 for v in versions:
298 syslinux_conf += "label %s%d\n" \
299 % (self.distro_name.lower(), footlabel)
300 syslinux_conf += "\tmenu label %s (%s)\n" % (self.distro_name, v)
301 syslinux_conf += "\tlinux ../vmlinuz-%s\n" % v
302 syslinux_conf += "\tappend ro root=%s %s\n" \
303 % (rootdev, options)
304 if footlabel == 0:
305 syslinux_conf += "\tmenu default\n"
306 footlabel += 1;
307
308 msger.debug("Writing syslinux config %s/boot/extlinux/extlinux.conf" \
309 % self._instroot)
310 cfg = open(self._instroot + "/boot/extlinux/extlinux.conf", "w")
311 cfg.write(syslinux_conf)
312 cfg.close()
313
314 def _install_syslinux(self):
315 for name in self.__disks.keys():
316 loopdev = self.__disks[name].device
317
318 # Set MBR
319 mbrfile = "%s/usr/share/syslinux/" % self._instroot
320 if self._ptable_format == 'gpt':
321 mbrfile += "gptmbr.bin"
322 else:
323 mbrfile += "mbr.bin"
324
325 msger.debug("Installing syslinux bootloader '%s' to %s" % \
326 (mbrfile, loopdev))
327
328 mbrsize = os.stat(mbrfile)[stat.ST_SIZE]
329 rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev])
330 if rc != 0:
331 raise MountError("Unable to set MBR to %s" % loopdev)
332
333
334 # Ensure all data is flushed to disk before doing syslinux install
335 runner.quiet('sync')
336
337 fullpathsyslinux = fs_related.find_binary_path("extlinux")
338 rc = runner.show([fullpathsyslinux,
339 "-i",
340 "%s/boot/extlinux" % self._instroot])
341 if rc != 0:
342 raise MountError("Unable to install syslinux bootloader to %s" \
343 % loopdev)
344
345 def _create_bootconfig(self):
346 #If syslinux is available do the required configurations.
347 if self._need_extlinux \
348 and os.path.exists("%s/usr/share/syslinux/" % (self._instroot)) \
349 and os.path.exists("%s/boot/extlinux/" % (self._instroot)):
350 self._create_syslinux_config()
351 self._install_syslinux()
352
353 def _unmount_instroot(self):
354 if not self.__instloop is None:
355 try:
356 self.__instloop.cleanup()
357 except MountError, err:
358 msger.warning("%s" % err)
359
360 def _resparse(self, size = None):
361 return self.__instloop.resparse(size)
362
363 def _get_post_scripts_env(self, in_chroot):
364 env = BaseImageCreator._get_post_scripts_env(self, in_chroot)
365
366 # Export the file-system UUIDs and partition UUIDs (AKA PARTUUIDs)
367 for p in self.__instloop.partitions:
368 env.update(self._set_part_env(p['ks_pnum'], "UUID", p['uuid']))
369 env.update(self._set_part_env(p['ks_pnum'], "PARTUUID", p['partuuid']))
370
371 return env
372
373 def _stage_final_image(self):
374 """Stage the final system image in _outdir.
375 write meta data
376 """
377 self._resparse()
378
379 if self.compress_image:
380 for imgfile in os.listdir(self.__imgdir):
381 if imgfile.endswith('.raw') or imgfile.endswith('bin'):
382 imgpath = os.path.join(self.__imgdir, imgfile)
383 misc.compressing(imgpath, self.compress_image)
384
385 if self.pack_to:
386 dst = os.path.join(self._outdir, self.pack_to)
387 msger.info("Pack all raw images to %s" % dst)
388 misc.packing(dst, self.__imgdir)
389 else:
390 msger.debug("moving disks to stage location")
391 for imgfile in os.listdir(self.__imgdir):
392 src = os.path.join(self.__imgdir, imgfile)
393 dst = os.path.join(self._outdir, imgfile)
394 msger.debug("moving %s to %s" % (src,dst))
395 shutil.move(src,dst)
396 self._write_image_xml()
397
398 def _write_image_xml(self):
399 imgarch = "i686"
400 if self.target_arch and self.target_arch.startswith("arm"):
401 imgarch = "arm"
402 xml = "<image>\n"
403
404 name_attributes = ""
405 if self.appliance_version:
406 name_attributes += " version='%s'" % self.appliance_version
407 if self.appliance_release:
408 name_attributes += " release='%s'" % self.appliance_release
409 xml += " <name%s>%s</name>\n" % (name_attributes, self.name)
410 xml += " <domain>\n"
411 # XXX don't hardcode - determine based on the kernel we installed for
412 # grub baremetal vs xen
413 xml += " <boot type='hvm'>\n"
414 xml += " <guest>\n"
415 xml += " <arch>%s</arch>\n" % imgarch
416 xml += " </guest>\n"
417 xml += " <os>\n"
418 xml += " <loader dev='hd'/>\n"
419 xml += " </os>\n"
420
421 i = 0
422 for name in self.__disks.keys():
423 full_name = self._full_name(name, self.__disk_format)
424 xml += " <drive disk='%s' target='hd%s'/>\n" \
425 % (full_name, chr(ord('a') + i))
426 i = i + 1
427
428 xml += " </boot>\n"
429 xml += " <devices>\n"
430 xml += " <vcpu>%s</vcpu>\n" % self.vcpu
431 xml += " <memory>%d</memory>\n" %(self.vmem * 1024)
432 for network in self.ks.handler.network.network:
433 xml += " <interface/>\n"
434 xml += " <graphics/>\n"
435 xml += " </devices>\n"
436 xml += " </domain>\n"
437 xml += " <storage>\n"
438
439 if self.checksum is True:
440 for name in self.__disks.keys():
441 diskpath = self._full_path(self._outdir, name, \
442 self.__disk_format)
443 full_name = self._full_name(name, self.__disk_format)
444
445 msger.debug("Generating disk signature for %s" % full_name)
446
447 xml += " <disk file='%s' use='system' format='%s'>\n" \
448 % (full_name, self.__disk_format)
449
450 hashes = misc.calc_hashes(diskpath, ('sha1', 'sha256'))
451
452 xml += " <checksum type='sha1'>%s</checksum>\n" \
453 % hashes[0]
454 xml += " <checksum type='sha256'>%s</checksum>\n" \
455 % hashes[1]
456 xml += " </disk>\n"
457 else:
458 for name in self.__disks.keys():
459 full_name = self._full_name(name, self.__disk_format)
460 xml += " <disk file='%s' use='system' format='%s'/>\n" \
461 % (full_name, self.__disk_format)
462
463 xml += " </storage>\n"
464 xml += "</image>\n"
465
466 msger.debug("writing image XML to %s/%s.xml" %(self._outdir, self.name))
467 cfg = open("%s/%s.xml" % (self._outdir, self.name), "w")
468 cfg.write(xml)
469 cfg.close()
470
471 def generate_bmap(self):
472 """ Generate block map file for the image. The idea is that while disk
473 images we generate may be large (e.g., 4GiB), they may actually contain
474 only little real data, e.g., 512MiB. This data are files, directories,
475 file-system meta-data, partition table, etc. In other words, when
476 flashing the image to the target device, you do not have to copy all the
477 4GiB of data, you can copy only 512MiB of it, which is 4 times faster.
478
479 This function generates the block map file for an arbitrary image that
480 mic has generated. The block map file is basically an XML file which
481 contains a list of blocks which have to be copied to the target device.
482 The other blocks are not used and there is no need to copy them. """
483
484 if self.bmap_needed is None:
485 return
486
487 from mic.utils import BmapCreate
488 msger.info("Generating the map file(s)")
489
490 for name in self.__disks.keys():
491 image = self._full_path(self.__imgdir, name, self.__disk_format)
492 bmap_file = self._full_path(self._outdir, name, "bmap")
493
494 msger.debug("Generating block map file '%s'" % bmap_file)
495
496 try:
497 creator = BmapCreate.BmapCreate(image, bmap_file)
498 creator.generate()
499 del creator
500 except BmapCreate.Error as err:
501 raise CreatorError("Failed to create bmap file: %s" % str(err))
diff --git a/scripts/lib/mic/kickstart/__init__.py b/scripts/lib/mic/kickstart/__init__.py
new file mode 100644
index 0000000000..72f3ca6849
--- /dev/null
+++ b/scripts/lib/mic/kickstart/__init__.py
@@ -0,0 +1,892 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007 Red Hat, Inc.
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19import os, sys, re
20import shutil
21import subprocess
22import string
23
24import pykickstart.sections as kssections
25import pykickstart.commands as kscommands
26import pykickstart.constants as ksconstants
27import pykickstart.errors as kserrors
28import pykickstart.parser as ksparser
29import pykickstart.version as ksversion
30from pykickstart.handlers.control import commandMap
31from pykickstart.handlers.control import dataMap
32
33from mic import msger
34from mic.utils import errors, misc, runner, fs_related as fs
35from custom_commands import desktop, micrepo, wicboot, partition, installerfw
36
37
38AUTH_URL_PTN = r"(?P<scheme>.*)://(?P<username>.*)(:?P<password>.*)?@(?P<url>.*)"
39
40
41class PrepackageSection(kssections.Section):
42 sectionOpen = "%prepackages"
43
44 def handleLine(self, line):
45 if not self.handler:
46 return
47
48 (h, s, t) = line.partition('#')
49 line = h.rstrip()
50
51 self.handler.prepackages.add([line])
52
53 def handleHeader(self, lineno, args):
54 kssections.Section.handleHeader(self, lineno, args)
55
56class AttachmentSection(kssections.Section):
57 sectionOpen = "%attachment"
58
59 def handleLine(self, line):
60 if not self.handler:
61 return
62
63 (h, s, t) = line.partition('#')
64 line = h.rstrip()
65
66 self.handler.attachment.add([line])
67
68 def handleHeader(self, lineno, args):
69 kssections.Section.handleHeader(self, lineno, args)
70
71def apply_wrapper(func):
72 def wrapper(*kargs, **kwargs):
73 try:
74 func(*kargs, **kwargs)
75 except (OSError, IOError, errors.KsError), err:
76 cfgcls = kargs[0].__class__.__name__
77 if msger.ask("Failed to apply %s, skip and continue?" % cfgcls):
78 msger.warning("%s" % err)
79 pass
80 else:
81 # just throw out the exception
82 raise
83 return wrapper
84
85def read_kickstart(path):
86 """Parse a kickstart file and return a KickstartParser instance.
87
88 This is a simple utility function which takes a path to a kickstart file,
89 parses it and returns a pykickstart KickstartParser instance which can
90 be then passed to an ImageCreator constructor.
91
92 If an error occurs, a CreatorError exception is thrown.
93 """
94
95 #version = ksversion.makeVersion()
96 #ks = ksparser.KickstartParser(version)
97
98 using_version = ksversion.DEVEL
99 commandMap[using_version]["desktop"] = desktop.Mic_Desktop
100 commandMap[using_version]["repo"] = micrepo.Mic_Repo
101 commandMap[using_version]["bootloader"] = wicboot.Wic_Bootloader
102 commandMap[using_version]["part"] = partition.Wic_Partition
103 commandMap[using_version]["partition"] = partition.Wic_Partition
104 commandMap[using_version]["installerfw"] = installerfw.Mic_installerfw
105 dataMap[using_version]["RepoData"] = micrepo.Mic_RepoData
106 dataMap[using_version]["PartData"] = partition.Wic_PartData
107 superclass = ksversion.returnClassForVersion(version=using_version)
108
109 class KSHandlers(superclass):
110 def __init__(self):
111 superclass.__init__(self, mapping=commandMap[using_version])
112 self.prepackages = ksparser.Packages()
113 self.attachment = ksparser.Packages()
114
115 ks = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=False)
116 ks.registerSection(PrepackageSection(ks.handler))
117 ks.registerSection(AttachmentSection(ks.handler))
118
119 try:
120 ks.readKickstart(path)
121 except (kserrors.KickstartParseError, kserrors.KickstartError), err:
122 if msger.ask("Errors occured on kickstart file, skip and continue?"):
123 msger.warning("%s" % err)
124 pass
125 else:
126 raise errors.KsError("%s" % err)
127
128 return ks
129
130class KickstartConfig(object):
131 """A base class for applying kickstart configurations to a system."""
132 def __init__(self, instroot):
133 self.instroot = instroot
134
135 def path(self, subpath):
136 return self.instroot + subpath
137
138 def _check_sysconfig(self):
139 if not os.path.exists(self.path("/etc/sysconfig")):
140 fs.makedirs(self.path("/etc/sysconfig"))
141
142 def chroot(self):
143 os.chroot(self.instroot)
144 os.chdir("/")
145
146 def call(self, args):
147 if not os.path.exists("%s/%s" %(self.instroot, args[0])):
148 raise errors.KsError("Can't find %s in chroot" % args[0])
149 subprocess.call(args, preexec_fn = self.chroot)
150
151 def apply(self):
152 pass
153
154class LanguageConfig(KickstartConfig):
155 """A class to apply a kickstart language configuration to a system."""
156 @apply_wrapper
157 def apply(self, kslang):
158 self._check_sysconfig()
159 if kslang.lang:
160 f = open(self.path("/etc/sysconfig/i18n"), "w+")
161 f.write("LANG=\"" + kslang.lang + "\"\n")
162 f.close()
163
164class KeyboardConfig(KickstartConfig):
165 """A class to apply a kickstart keyboard configuration to a system."""
166 @apply_wrapper
167 def apply(self, kskeyboard):
168 #
169 # FIXME:
170 # should this impact the X keyboard config too?
171 # or do we want to make X be able to do this mapping?
172 #
173 #k = rhpl.keyboard.Keyboard()
174 #if kskeyboard.keyboard:
175 # k.set(kskeyboard.keyboard)
176 #k.write(self.instroot)
177 pass
178
179class TimezoneConfig(KickstartConfig):
180 """A class to apply a kickstart timezone configuration to a system."""
181 @apply_wrapper
182 def apply(self, kstimezone):
183 self._check_sysconfig()
184 tz = kstimezone.timezone or "America/New_York"
185 utc = str(kstimezone.isUtc)
186
187 f = open(self.path("/etc/sysconfig/clock"), "w+")
188 f.write("ZONE=\"" + tz + "\"\n")
189 f.write("UTC=" + utc + "\n")
190 f.close()
191 tz_source = "/usr/share/zoneinfo/%s" % (tz)
192 tz_dest = "/etc/localtime"
193 try:
194 cpcmd = fs.find_binary_inchroot('cp', self.instroot)
195 if cpcmd:
196 self.call([cpcmd, "-f", tz_source, tz_dest])
197 else:
198 cpcmd = fs.find_binary_path('cp')
199 subprocess.call([cpcmd, "-f",
200 self.path(tz_source),
201 self.path(tz_dest)])
202 except (IOError, OSError), (errno, msg):
203 raise errors.KsError("Timezone setting error: %s" % msg)
204
205class AuthConfig(KickstartConfig):
206 """A class to apply a kickstart authconfig configuration to a system."""
207 @apply_wrapper
208 def apply(self, ksauthconfig):
209 auth = ksauthconfig.authconfig or "--useshadow --enablemd5"
210 args = ["/usr/share/authconfig/authconfig.py", "--update", "--nostart"]
211 self.call(args + auth.split())
212
213class FirewallConfig(KickstartConfig):
214 """A class to apply a kickstart firewall configuration to a system."""
215 @apply_wrapper
216 def apply(self, ksfirewall):
217 #
218 # FIXME: should handle the rest of the options
219 #
220 if not os.path.exists(self.path("/usr/sbin/lokkit")):
221 return
222 if ksfirewall.enabled:
223 status = "--enabled"
224 else:
225 status = "--disabled"
226
227 self.call(["/usr/sbin/lokkit",
228 "-f", "--quiet", "--nostart", status])
229
230class RootPasswordConfig(KickstartConfig):
231 """A class to apply a kickstart root password configuration to a system."""
232 def unset(self):
233 self.call(["/usr/bin/passwd", "-d", "root"])
234
235 def set_encrypted(self, password):
236 self.call(["/usr/sbin/usermod", "-p", password, "root"])
237
238 def set_unencrypted(self, password):
239 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
240 if not os.path.exists("%s/%s" %(self.instroot, p)):
241 raise errors.KsError("Unable to set unencrypted password due "
242 "to lack of %s" % p)
243
244 p1 = subprocess.Popen(["/bin/echo", "root:%s" %password],
245 stdout = subprocess.PIPE,
246 preexec_fn = self.chroot)
247 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
248 stdin = p1.stdout,
249 stdout = subprocess.PIPE,
250 preexec_fn = self.chroot)
251 p2.communicate()
252
253 @apply_wrapper
254 def apply(self, ksrootpw):
255 if ksrootpw.isCrypted:
256 self.set_encrypted(ksrootpw.password)
257 elif ksrootpw.password != "":
258 self.set_unencrypted(ksrootpw.password)
259 else:
260 self.unset()
261
262class UserConfig(KickstartConfig):
263 def set_empty_passwd(self, user):
264 self.call(["/usr/bin/passwd", "-d", user])
265
266 def set_encrypted_passwd(self, user, password):
267 self.call(["/usr/sbin/usermod", "-p", "%s" % password, user])
268
269 def set_unencrypted_passwd(self, user, password):
270 for p in ("/bin/echo", "/usr/sbin/chpasswd"):
271 if not os.path.exists("%s/%s" %(self.instroot, p)):
272 raise errors.KsError("Unable to set unencrypted password due "
273 "to lack of %s" % p)
274
275 p1 = subprocess.Popen(["/bin/echo", "%s:%s" %(user, password)],
276 stdout = subprocess.PIPE,
277 preexec_fn = self.chroot)
278 p2 = subprocess.Popen(["/usr/sbin/chpasswd", "-m"],
279 stdin = p1.stdout,
280 stdout = subprocess.PIPE,
281 preexec_fn = self.chroot)
282 p2.communicate()
283
284 def addUser(self, userconfig):
285 args = [ "/usr/sbin/useradd" ]
286 if userconfig.groups:
287 args += [ "--groups", string.join(userconfig.groups, ",") ]
288 if userconfig.name:
289 args += [ "-m"]
290 args += [ "-d", "/home/%s" % userconfig.name ]
291 args.append(userconfig.name)
292 try:
293 dev_null = os.open("/dev/null", os.O_WRONLY)
294 msger.debug('adding user with %s' % args)
295 subprocess.call(args,
296 stdout = dev_null,
297 stderr = dev_null,
298 preexec_fn = self.chroot)
299 os.close(dev_null)
300 except:
301 msger.warning('Cannot add user using "useradd"')
302
303 if userconfig.password not in (None, ""):
304 if userconfig.isCrypted:
305 self.set_encrypted_passwd(userconfig.name,
306 userconfig.password)
307 else:
308 self.set_unencrypted_passwd(userconfig.name,
309 userconfig.password)
310 else:
311 self.set_empty_passwd(userconfig.name)
312 else:
313 raise errors.KsError("Invalid kickstart command: %s" \
314 % userconfig.__str__())
315
316 @apply_wrapper
317 def apply(self, user):
318 for userconfig in user.userList:
319 self.addUser(userconfig)
320
321class ServicesConfig(KickstartConfig):
322 """A class to apply a kickstart services configuration to a system."""
323 @apply_wrapper
324 def apply(self, ksservices):
325 if not os.path.exists(self.path("/sbin/chkconfig")):
326 return
327 for s in ksservices.enabled:
328 self.call(["/sbin/chkconfig", s, "on"])
329 for s in ksservices.disabled:
330 self.call(["/sbin/chkconfig", s, "off"])
331
332class XConfig(KickstartConfig):
333 """A class to apply a kickstart X configuration to a system."""
334 @apply_wrapper
335 def apply(self, ksxconfig):
336 if ksxconfig.startX and os.path.exists(self.path("/etc/inittab")):
337 f = open(self.path("/etc/inittab"), "rw+")
338 buf = f.read()
339 buf = buf.replace("id:3:initdefault", "id:5:initdefault")
340 f.seek(0)
341 f.write(buf)
342 f.close()
343 if ksxconfig.defaultdesktop:
344 self._check_sysconfig()
345 f = open(self.path("/etc/sysconfig/desktop"), "w")
346 f.write("DESKTOP="+ksxconfig.defaultdesktop+"\n")
347 f.close()
348
349class DesktopConfig(KickstartConfig):
350 """A class to apply a kickstart desktop configuration to a system."""
351 @apply_wrapper
352 def apply(self, ksdesktop):
353 if ksdesktop.defaultdesktop:
354 self._check_sysconfig()
355 f = open(self.path("/etc/sysconfig/desktop"), "w")
356 f.write("DESKTOP="+ksdesktop.defaultdesktop+"\n")
357 f.close()
358 if os.path.exists(self.path("/etc/gdm/custom.conf")):
359 f = open(self.path("/etc/skel/.dmrc"), "w")
360 f.write("[Desktop]\n")
361 f.write("Session="+ksdesktop.defaultdesktop.lower()+"\n")
362 f.close()
363 if ksdesktop.session:
364 if os.path.exists(self.path("/etc/sysconfig/uxlaunch")):
365 f = open(self.path("/etc/sysconfig/uxlaunch"), "a+")
366 f.write("session="+ksdesktop.session.lower()+"\n")
367 f.close()
368 if ksdesktop.autologinuser:
369 self._check_sysconfig()
370 f = open(self.path("/etc/sysconfig/desktop"), "a+")
371 f.write("AUTOLOGIN_USER=" + ksdesktop.autologinuser + "\n")
372 f.close()
373 if os.path.exists(self.path("/etc/gdm/custom.conf")):
374 f = open(self.path("/etc/gdm/custom.conf"), "w")
375 f.write("[daemon]\n")
376 f.write("AutomaticLoginEnable=true\n")
377 f.write("AutomaticLogin=" + ksdesktop.autologinuser + "\n")
378 f.close()
379
380class MoblinRepoConfig(KickstartConfig):
381 """A class to apply a kickstart desktop configuration to a system."""
382 def __create_repo_section(self, repo, type, fd):
383 baseurl = None
384 mirrorlist = None
385 reposuffix = {"base":"", "debuginfo":"-debuginfo", "source":"-source"}
386 reponame = repo.name + reposuffix[type]
387 if type == "base":
388 if repo.baseurl:
389 baseurl = repo.baseurl
390 if repo.mirrorlist:
391 mirrorlist = repo.mirrorlist
392
393 elif type == "debuginfo":
394 if repo.baseurl:
395 if repo.baseurl.endswith("/"):
396 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
397 else:
398 baseurl = os.path.dirname(repo.baseurl)
399 baseurl += "/debug"
400
401 if repo.mirrorlist:
402 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
403 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
404 mirrorlist += "debug" + "-" + variant
405
406 elif type == "source":
407 if repo.baseurl:
408 if repo.baseurl.endswith("/"):
409 baseurl = os.path.dirname(
410 os.path.dirname(
411 os.path.dirname(repo.baseurl)))
412 else:
413 baseurl = os.path.dirname(os.path.dirname(repo.baseurl))
414 baseurl += "/source"
415
416 if repo.mirrorlist:
417 variant = repo.mirrorlist[repo.mirrorlist.find("$"):]
418 mirrorlist = repo.mirrorlist[0:repo.mirrorlist.find("$")]
419 mirrorlist += "source" + "-" + variant
420
421 fd.write("[" + reponame + "]\n")
422 fd.write("name=" + reponame + "\n")
423 fd.write("failovermethod=priority\n")
424 if baseurl:
425 auth_url = re.compile(AUTH_URL_PTN)
426 m = auth_url.match(baseurl)
427 if m:
428 baseurl = "%s://%s" % (m.group('scheme'), m.group('url'))
429 fd.write("baseurl=" + baseurl + "\n")
430 if mirrorlist:
431 fd.write("mirrorlist=" + mirrorlist + "\n")
432 """ Skip saving proxy settings """
433 #if repo.proxy:
434 # fd.write("proxy=" + repo.proxy + "\n")
435 #if repo.proxy_username:
436 # fd.write("proxy_username=" + repo.proxy_username + "\n")
437 #if repo.proxy_password:
438 # fd.write("proxy_password=" + repo.proxy_password + "\n")
439 if repo.gpgkey:
440 fd.write("gpgkey=" + repo.gpgkey + "\n")
441 fd.write("gpgcheck=1\n")
442 else:
443 fd.write("gpgcheck=0\n")
444 if type == "source" or type == "debuginfo" or repo.disable:
445 fd.write("enabled=0\n")
446 else:
447 fd.write("enabled=1\n")
448 fd.write("\n")
449
450 def __create_repo_file(self, repo, repodir):
451 fs.makedirs(self.path(repodir))
452 f = open(self.path(repodir + "/" + repo.name + ".repo"), "w")
453 self.__create_repo_section(repo, "base", f)
454 if repo.debuginfo:
455 self.__create_repo_section(repo, "debuginfo", f)
456 if repo.source:
457 self.__create_repo_section(repo, "source", f)
458 f.close()
459
460 @apply_wrapper
461 def apply(self, ksrepo, repodata, repourl):
462 for repo in ksrepo.repoList:
463 if repo.name in repourl:
464 repo.baseurl = repourl[repo.name]
465 if repo.save:
466 #self.__create_repo_file(repo, "/etc/yum.repos.d")
467 self.__create_repo_file(repo, "/etc/zypp/repos.d")
468 """ Import repo gpg keys """
469 if repodata:
470 for repo in repodata:
471 if repo['repokey']:
472 runner.quiet(['rpm',
473 "--root=%s" % self.instroot,
474 "--import",
475 repo['repokey']])
476
477class RPMMacroConfig(KickstartConfig):
478 """A class to apply the specified rpm macros to the filesystem"""
479 @apply_wrapper
480 def apply(self, ks):
481 if not ks:
482 return
483 if not os.path.exists(self.path("/etc/rpm")):
484 os.mkdir(self.path("/etc/rpm"))
485 f = open(self.path("/etc/rpm/macros.imgcreate"), "w+")
486 if exclude_docs(ks):
487 f.write("%_excludedocs 1\n")
488 f.write("%__file_context_path %{nil}\n")
489 if inst_langs(ks) != None:
490 f.write("%_install_langs ")
491 f.write(inst_langs(ks))
492 f.write("\n")
493 f.close()
494
495class NetworkConfig(KickstartConfig):
496 """A class to apply a kickstart network configuration to a system."""
497 def write_ifcfg(self, network):
498 p = self.path("/etc/sysconfig/network-scripts/ifcfg-" + network.device)
499
500 f = file(p, "w+")
501 os.chmod(p, 0644)
502
503 f.write("DEVICE=%s\n" % network.device)
504 f.write("BOOTPROTO=%s\n" % network.bootProto)
505
506 if network.bootProto.lower() == "static":
507 if network.ip:
508 f.write("IPADDR=%s\n" % network.ip)
509 if network.netmask:
510 f.write("NETMASK=%s\n" % network.netmask)
511
512 if network.onboot:
513 f.write("ONBOOT=on\n")
514 else:
515 f.write("ONBOOT=off\n")
516
517 if network.essid:
518 f.write("ESSID=%s\n" % network.essid)
519
520 if network.ethtool:
521 if network.ethtool.find("autoneg") == -1:
522 network.ethtool = "autoneg off " + network.ethtool
523 f.write("ETHTOOL_OPTS=%s\n" % network.ethtool)
524
525 if network.bootProto.lower() == "dhcp":
526 if network.hostname:
527 f.write("DHCP_HOSTNAME=%s\n" % network.hostname)
528 if network.dhcpclass:
529 f.write("DHCP_CLASSID=%s\n" % network.dhcpclass)
530
531 if network.mtu:
532 f.write("MTU=%s\n" % network.mtu)
533
534 f.close()
535
536 def write_wepkey(self, network):
537 if not network.wepkey:
538 return
539
540 p = self.path("/etc/sysconfig/network-scripts/keys-" + network.device)
541 f = file(p, "w+")
542 os.chmod(p, 0600)
543 f.write("KEY=%s\n" % network.wepkey)
544 f.close()
545
546 def write_sysconfig(self, useipv6, hostname, gateway):
547 path = self.path("/etc/sysconfig/network")
548 f = file(path, "w+")
549 os.chmod(path, 0644)
550
551 f.write("NETWORKING=yes\n")
552
553 if useipv6:
554 f.write("NETWORKING_IPV6=yes\n")
555 else:
556 f.write("NETWORKING_IPV6=no\n")
557
558 if hostname:
559 f.write("HOSTNAME=%s\n" % hostname)
560 else:
561 f.write("HOSTNAME=localhost.localdomain\n")
562
563 if gateway:
564 f.write("GATEWAY=%s\n" % gateway)
565
566 f.close()
567
568 def write_hosts(self, hostname):
569 localline = ""
570 if hostname and hostname != "localhost.localdomain":
571 localline += hostname + " "
572 l = hostname.split(".")
573 if len(l) > 1:
574 localline += l[0] + " "
575 localline += "localhost.localdomain localhost"
576
577 path = self.path("/etc/hosts")
578 f = file(path, "w+")
579 os.chmod(path, 0644)
580 f.write("127.0.0.1\t\t%s\n" % localline)
581 f.write("::1\t\tlocalhost6.localdomain6 localhost6\n")
582 f.close()
583
584 def write_resolv(self, nodns, nameservers):
585 if nodns or not nameservers:
586 return
587
588 path = self.path("/etc/resolv.conf")
589 f = file(path, "w+")
590 os.chmod(path, 0644)
591
592 for ns in (nameservers):
593 if ns:
594 f.write("nameserver %s\n" % ns)
595
596 f.close()
597
598 @apply_wrapper
599 def apply(self, ksnet):
600 fs.makedirs(self.path("/etc/sysconfig/network-scripts"))
601
602 useipv6 = False
603 nodns = False
604 hostname = None
605 gateway = None
606 nameservers = None
607
608 for network in ksnet.network:
609 if not network.device:
610 raise errors.KsError("No --device specified with "
611 "network kickstart command")
612
613 if (network.onboot and network.bootProto.lower() != "dhcp" and
614 not (network.ip and network.netmask)):
615 raise errors.KsError("No IP address and/or netmask "
616 "specified with static "
617 "configuration for '%s'" %
618 network.device)
619
620 self.write_ifcfg(network)
621 self.write_wepkey(network)
622
623 if network.ipv6:
624 useipv6 = True
625 if network.nodns:
626 nodns = True
627
628 if network.hostname:
629 hostname = network.hostname
630 if network.gateway:
631 gateway = network.gateway
632
633 if network.nameserver:
634 nameservers = network.nameserver.split(",")
635
636 self.write_sysconfig(useipv6, hostname, gateway)
637 self.write_hosts(hostname)
638 self.write_resolv(nodns, nameservers)
639
640def use_installerfw(ks, feature):
641 """ Check if the installer framework has to be used for a feature
642 "feature". """
643
644 features = ks.handler.installerfw.features
645 if features:
646 if feature in features or "all" in features:
647 return True
648 return False
649
650def get_image_size(ks, default = None):
651 __size = 0
652 for p in ks.handler.partition.partitions:
653 if p.mountpoint == "/" and p.size:
654 __size = p.size
655 if __size > 0:
656 return int(__size) * 1024L * 1024L
657 else:
658 return default
659
660def get_image_fstype(ks, default = None):
661 for p in ks.handler.partition.partitions:
662 if p.mountpoint == "/" and p.fstype:
663 return p.fstype
664 return default
665
666def get_image_fsopts(ks, default = None):
667 for p in ks.handler.partition.partitions:
668 if p.mountpoint == "/" and p.fsopts:
669 return p.fsopts
670 return default
671
672def get_modules(ks):
673 devices = []
674 if isinstance(ks.handler.device, kscommands.device.FC3_Device):
675 devices.append(ks.handler.device)
676 else:
677 devices.extend(ks.handler.device.deviceList)
678
679 modules = []
680 for device in devices:
681 if not device.moduleName:
682 continue
683 modules.extend(device.moduleName.split(":"))
684
685 return modules
686
687def get_timeout(ks, default = None):
688 if not hasattr(ks.handler.bootloader, "timeout"):
689 return default
690 if ks.handler.bootloader.timeout is None:
691 return default
692 return int(ks.handler.bootloader.timeout)
693
694def get_kernel_args(ks, default = "ro rd.live.image"):
695 if not hasattr(ks.handler.bootloader, "appendLine"):
696 return default
697 if ks.handler.bootloader.appendLine is None:
698 return default
699 return "%s %s" %(default, ks.handler.bootloader.appendLine)
700
701def get_menu_args(ks, default = ""):
702 if not hasattr(ks.handler.bootloader, "menus"):
703 return default
704 if ks.handler.bootloader.menus in (None, ""):
705 return default
706 return "%s" % ks.handler.bootloader.menus
707
708def get_default_kernel(ks, default = None):
709 if not hasattr(ks.handler.bootloader, "default"):
710 return default
711 if not ks.handler.bootloader.default:
712 return default
713 return ks.handler.bootloader.default
714
715def get_repos(ks, repo_urls=None):
716 repos = {}
717 for repo in ks.handler.repo.repoList:
718 inc = []
719 if hasattr(repo, "includepkgs"):
720 inc.extend(repo.includepkgs)
721
722 exc = []
723 if hasattr(repo, "excludepkgs"):
724 exc.extend(repo.excludepkgs)
725
726 baseurl = repo.baseurl
727 mirrorlist = repo.mirrorlist
728
729 if repo_urls and repo.name in repo_urls:
730 baseurl = repo_urls[repo.name]
731 mirrorlist = None
732
733 if repos.has_key(repo.name):
734 msger.warning("Overriding already specified repo %s" %(repo.name,))
735
736 proxy = None
737 if hasattr(repo, "proxy"):
738 proxy = repo.proxy
739 proxy_username = None
740 if hasattr(repo, "proxy_username"):
741 proxy_username = repo.proxy_username
742 proxy_password = None
743 if hasattr(repo, "proxy_password"):
744 proxy_password = repo.proxy_password
745 if hasattr(repo, "debuginfo"):
746 debuginfo = repo.debuginfo
747 if hasattr(repo, "source"):
748 source = repo.source
749 if hasattr(repo, "gpgkey"):
750 gpgkey = repo.gpgkey
751 if hasattr(repo, "disable"):
752 disable = repo.disable
753 ssl_verify = True
754 if hasattr(repo, "ssl_verify"):
755 ssl_verify = repo.ssl_verify == "yes"
756 nocache = False
757 if hasattr(repo, "nocache"):
758 nocache = repo.nocache
759 cost = None
760 if hasattr(repo, "cost"):
761 cost = repo.cost
762 priority = None
763 if hasattr(repo, "priority"):
764 priority = repo.priority
765
766 repos[repo.name] = (repo.name, baseurl, mirrorlist, inc, exc,
767 proxy, proxy_username, proxy_password, debuginfo,
768 source, gpgkey, disable, ssl_verify, nocache,
769 cost, priority)
770
771 return repos.values()
772
773def convert_method_to_repo(ks):
774 try:
775 ks.handler.repo.methodToRepo()
776 except (AttributeError, kserrors.KickstartError):
777 pass
778
779def get_attachment(ks, required=()):
780 return ks.handler.attachment.packageList + list(required)
781
782def get_pre_packages(ks, required=()):
783 return ks.handler.prepackages.packageList + list(required)
784
785def get_packages(ks, required=()):
786 return ks.handler.packages.packageList + list(required)
787
788def get_groups(ks, required=()):
789 return ks.handler.packages.groupList + list(required)
790
791def get_excluded(ks, required=()):
792 return ks.handler.packages.excludedList + list(required)
793
794def get_partitions(ks):
795 return ks.handler.partition.partitions
796
797def ignore_missing(ks):
798 return ks.handler.packages.handleMissing == ksconstants.KS_MISSING_IGNORE
799
800def exclude_docs(ks):
801 return ks.handler.packages.excludeDocs
802
803def inst_langs(ks):
804 if hasattr(ks.handler.packages, "instLange"):
805 return ks.handler.packages.instLange
806 elif hasattr(ks.handler.packages, "instLangs"):
807 return ks.handler.packages.instLangs
808 return ""
809
810def get_post_scripts(ks):
811 scripts = []
812 for s in ks.handler.scripts:
813 if s.type != ksparser.KS_SCRIPT_POST:
814 continue
815 scripts.append(s)
816 return scripts
817
818def add_repo(ks, repostr):
819 args = repostr.split()
820 repoobj = ks.handler.repo.parse(args[1:])
821 if repoobj and repoobj not in ks.handler.repo.repoList:
822 ks.handler.repo.repoList.append(repoobj)
823
824def remove_all_repos(ks):
825 while len(ks.handler.repo.repoList) != 0:
826 del ks.handler.repo.repoList[0]
827
828def remove_duplicate_repos(ks):
829 i = 0
830 j = i + 1
831 while True:
832 if len(ks.handler.repo.repoList) < 2:
833 break
834 if i >= len(ks.handler.repo.repoList) - 1:
835 break
836 name = ks.handler.repo.repoList[i].name
837 baseurl = ks.handler.repo.repoList[i].baseurl
838 if j < len(ks.handler.repo.repoList):
839 if (ks.handler.repo.repoList[j].name == name or \
840 ks.handler.repo.repoList[j].baseurl == baseurl):
841 del ks.handler.repo.repoList[j]
842 else:
843 j += 1
844 if j >= len(ks.handler.repo.repoList):
845 i += 1
846 j = i + 1
847 else:
848 i += 1
849 j = i + 1
850
851def resolve_groups(creatoropts, repometadata):
852 iszypp = False
853 if 'zypp' == creatoropts['pkgmgr']:
854 iszypp = True
855 ks = creatoropts['ks']
856
857 for repo in repometadata:
858 """ Mustn't replace group with package list if repo is ready for the
859 corresponding package manager.
860 """
861
862 if iszypp and repo["patterns"]:
863 continue
864 if not iszypp and repo["comps"]:
865 continue
866
867 # But we also must handle such cases, use zypp but repo only has comps,
868 # use yum but repo only has patterns, use zypp but use_comps is true,
869 # use yum but use_comps is false.
870 groupfile = None
871 if iszypp and repo["comps"]:
872 groupfile = repo["comps"]
873 get_pkglist_handler = misc.get_pkglist_in_comps
874 if not iszypp and repo["patterns"]:
875 groupfile = repo["patterns"]
876 get_pkglist_handler = misc.get_pkglist_in_patterns
877
878 if groupfile:
879 i = 0
880 while True:
881 if i >= len(ks.handler.packages.groupList):
882 break
883 pkglist = get_pkglist_handler(
884 ks.handler.packages.groupList[i].name,
885 groupfile)
886 if pkglist:
887 del ks.handler.packages.groupList[i]
888 for pkg in pkglist:
889 if pkg not in ks.handler.packages.packageList:
890 ks.handler.packages.packageList.append(pkg)
891 else:
892 i = i + 1
diff --git a/scripts/lib/mic/kickstart/custom_commands/__init__.py b/scripts/lib/mic/kickstart/custom_commands/__init__.py
new file mode 100644
index 0000000000..6aed0ff6fa
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/__init__.py
@@ -0,0 +1,17 @@
1from desktop import Mic_Desktop
2from micrepo import Mic_Repo, Mic_RepoData
3from micpartition import Mic_Partition
4from micpartition import Mic_PartData
5from installerfw import Mic_installerfw
6from partition import Wic_Partition
7
8__all__ = (
9 "Mic_Desktop",
10 "Mic_Repo",
11 "Mic_RepoData",
12 "Mic_Partition",
13 "Mic_PartData",
14 "Mic_installerfw",
15 "Wic_Partition",
16 "Wic_PartData",
17)
diff --git a/scripts/lib/mic/kickstart/custom_commands/desktop.py b/scripts/lib/mic/kickstart/custom_commands/desktop.py
new file mode 100644
index 0000000000..c8bd647ae3
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/desktop.py
@@ -0,0 +1,95 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2008, 2009, 2010 Intel, Inc.
4#
5# Yi Yang <yi.y.yang@intel.com>
6#
7# This program is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the Free
9# Software Foundation; version 2 of the License
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc., 59
18# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23
24class Mic_Desktop(KickstartCommand):
25 def __init__(self, writePriority=0,
26 defaultdesktop=None,
27 defaultdm=None,
28 autologinuser=None,
29 session=None):
30
31 KickstartCommand.__init__(self, writePriority)
32
33 self.__new_version = False
34 self.op = self._getParser()
35
36 self.defaultdesktop = defaultdesktop
37 self.autologinuser = autologinuser
38 self.defaultdm = defaultdm
39 self.session = session
40
41 def __str__(self):
42 retval = ""
43
44 if self.defaultdesktop != None:
45 retval += " --defaultdesktop=%s" % self.defaultdesktop
46 if self.session != None:
47 retval += " --session=\"%s\"" % self.session
48 if self.autologinuser != None:
49 retval += " --autologinuser=%s" % self.autologinuser
50 if self.defaultdm != None:
51 retval += " --defaultdm=%s" % self.defaultdm
52
53 if retval != "":
54 retval = "# Default Desktop Settings\ndesktop %s\n" % retval
55
56 return retval
57
58 def _getParser(self):
59 try:
60 op = KSOptionParser(lineno=self.lineno)
61 except TypeError:
62 # the latest version has not lineno argument
63 op = KSOptionParser()
64 self.__new_version = True
65
66 op.add_option("--defaultdesktop", dest="defaultdesktop",
67 action="store",
68 type="string",
69 nargs=1)
70 op.add_option("--autologinuser", dest="autologinuser",
71 action="store",
72 type="string",
73 nargs=1)
74 op.add_option("--defaultdm", dest="defaultdm",
75 action="store",
76 type="string",
77 nargs=1)
78 op.add_option("--session", dest="session",
79 action="store",
80 type="string",
81 nargs=1)
82 return op
83
84 def parse(self, args):
85 if self.__new_version:
86 (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
87 else:
88 (opts, extra) = self.op.parse_args(args=args)
89
90 if extra:
91 m = _("Unexpected arguments to %(command)s command: %(options)s") \
92 % {"command": "desktop", "options": extra}
93 raise KickstartValueError, formatErrorMsg(self.lineno, msg=m)
94
95 self._setToSelf(self.op, opts)
diff --git a/scripts/lib/mic/kickstart/custom_commands/installerfw.py b/scripts/lib/mic/kickstart/custom_commands/installerfw.py
new file mode 100644
index 0000000000..2466f1dc07
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/installerfw.py
@@ -0,0 +1,63 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2013 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from pykickstart.base import *
19from pykickstart.options import *
20
21class Mic_installerfw(KickstartCommand):
22 """ This class implements the "installerfw" KS option. The argument
23 of the option is a comman-separated list of MIC features which have to be
24 disabled and instead, will be done in the installer. For example,
25 "installerfw=extlinux" disables all the MIC code which installs extlinux to
26 the target images, and instead, the extlinux or whatever boot-loader will
27 be installed by the installer instead.
28
29 The installer is a tool which is external to MIC, it comes from the
30 installation repositories and can be executed by MIC in order to perform
31 various configuration actions. The main point here is to make sure MIC has
32 no hard-wired knoledge about the target OS configuration. """
33
34 removedKeywords = KickstartCommand.removedKeywords
35 removedAttrs = KickstartCommand.removedAttrs
36
37 def __init__(self, *args, **kwargs):
38 KickstartCommand.__init__(self, *args, **kwargs)
39 self.op = self._getParser()
40 self.features = kwargs.get("installerfw", None)
41
42 def __str__(self):
43 retval = KickstartCommand.__str__(self)
44
45 if self.features:
46 retval += "# Enable installer framework features\ninstallerfw\n"
47
48 return retval
49
50 def _getParser(self):
51 op = KSOptionParser()
52 return op
53
54 def parse(self, args):
55 (_, extra) = self.op.parse_args(args=args, lineno=self.lineno)
56
57 if len(extra) != 1:
58 msg = "Kickstart command \"installerfw\" requires one " \
59 "argumet - a list of legacy features to disable"
60 raise KickstartValueError, formatErrorMsg(self.lineno, msg = msg)
61
62 self.features = extra[0].split(",")
63 return self
diff --git a/scripts/lib/mic/kickstart/custom_commands/micboot.py b/scripts/lib/mic/kickstart/custom_commands/micboot.py
new file mode 100644
index 0000000000..66d1678aa7
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/micboot.py
@@ -0,0 +1,49 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2008, 2009, 2010 Intel, Inc.
4#
5# Anas Nashif
6#
7# This program is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the Free
9# Software Foundation; version 2 of the License
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc., 59
18# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23from pykickstart.commands.bootloader import *
24
25class Mic_Bootloader(F8_Bootloader):
26 def __init__(self, writePriority=10, appendLine="", driveorder=None,
27 forceLBA=False, location="", md5pass="", password="",
28 upgrade=False, menus=""):
29 F8_Bootloader.__init__(self, writePriority, appendLine, driveorder,
30 forceLBA, location, md5pass, password, upgrade)
31
32 self.menus = ""
33 self.ptable = "msdos"
34
35 def _getArgsAsStr(self):
36 ret = F8_Bootloader._getArgsAsStr(self)
37
38 if self.menus == "":
39 ret += " --menus=%s" %(self.menus,)
40 if self.ptable:
41 ret += " --ptable=\"%s\"" %(self.ptable,)
42 return ret
43
44 def _getParser(self):
45 op = F8_Bootloader._getParser(self)
46 op.add_option("--menus", dest="menus")
47 op.add_option("--ptable", dest="ptable", type="string")
48 return op
49
diff --git a/scripts/lib/mic/kickstart/custom_commands/micpartition.py b/scripts/lib/mic/kickstart/custom_commands/micpartition.py
new file mode 100644
index 0000000000..59a87fb486
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/micpartition.py
@@ -0,0 +1,57 @@
1#!/usr/bin/python -tt
2#
3# Marko Saukko <marko.saukko@cybercom.com>
4#
5# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
6#
7# This copyrighted material is made available to anyone wishing to use, modify,
8# copy, or redistribute it subject to the terms and conditions of the GNU
9# General Public License v.2. This program is distributed in the hope that it
10# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
11# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18from pykickstart.commands.partition import *
19
20class Mic_PartData(FC4_PartData):
21 removedKeywords = FC4_PartData.removedKeywords
22 removedAttrs = FC4_PartData.removedAttrs
23
24 def __init__(self, *args, **kwargs):
25 FC4_PartData.__init__(self, *args, **kwargs)
26 self.deleteRemovedAttrs()
27 self.align = kwargs.get("align", None)
28 self.extopts = kwargs.get("extopts", None)
29 self.part_type = kwargs.get("part_type", None)
30
31 def _getArgsAsStr(self):
32 retval = FC4_PartData._getArgsAsStr(self)
33
34 if self.align:
35 retval += " --align"
36 if self.extopts:
37 retval += " --extoptions=%s" % self.extopts
38 if self.part_type:
39 retval += " --part-type=%s" % self.part_type
40
41 return retval
42
43class Mic_Partition(FC4_Partition):
44 removedKeywords = FC4_Partition.removedKeywords
45 removedAttrs = FC4_Partition.removedAttrs
46
47 def _getParser(self):
48 op = FC4_Partition._getParser(self)
49 # The alignment value is given in kBytes. e.g., value 8 means that
50 # the partition is aligned to start from 8096 byte boundary.
51 op.add_option("--align", type="int", action="store", dest="align",
52 default=None)
53 op.add_option("--extoptions", type="string", action="store", dest="extopts",
54 default=None)
55 op.add_option("--part-type", type="string", action="store", dest="part_type",
56 default=None)
57 return op
diff --git a/scripts/lib/mic/kickstart/custom_commands/micrepo.py b/scripts/lib/mic/kickstart/custom_commands/micrepo.py
new file mode 100644
index 0000000000..b31576e400
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/micrepo.py
@@ -0,0 +1,127 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2008, 2009, 2010 Intel, Inc.
4#
5# Yi Yang <yi.y.yang@intel.com>
6#
7# This program is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the Free
9# Software Foundation; version 2 of the License
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14# for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc., 59
18# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20from pykickstart.base import *
21from pykickstart.errors import *
22from pykickstart.options import *
23from pykickstart.commands.repo import *
24
25class Mic_RepoData(F8_RepoData):
26
27 def __init__(self, baseurl="", mirrorlist=None, name="", priority=None,
28 includepkgs=(), excludepkgs=(), save=False, proxy=None,
29 proxy_username=None, proxy_password=None, debuginfo=False,
30 source=False, gpgkey=None, disable=False, ssl_verify="yes",
31 nocache=False):
32 kw = {}
33 # F8_RepoData keywords
34 if includepkgs:
35 kw['includepkgs'] = includepkgs
36 if excludepkgs:
37 kw['excludepkgs'] = excludepkgs
38
39 #FC6_RepoData keywords
40 if baseurl:
41 kw['baseurl'] = baseurl
42 if mirrorlist:
43 kw['mirrorlist'] = mirrorlist
44 if name:
45 kw['name'] = name
46
47 F8_RepoData.__init__(self, **kw)
48 self.save = save
49 self.proxy = proxy
50 self.proxy_username = proxy_username
51 self.proxy_password = proxy_password
52 self.debuginfo = debuginfo
53 self.disable = disable
54 self.source = source
55 self.gpgkey = gpgkey
56 self.ssl_verify = ssl_verify.lower()
57 self.priority = priority
58 self.nocache = nocache
59
60 def _getArgsAsStr(self):
61 retval = F8_RepoData._getArgsAsStr(self)
62
63 if self.save:
64 retval += " --save"
65 if self.proxy:
66 retval += " --proxy=%s" % self.proxy
67 if self.proxy_username:
68 retval += " --proxyuser=%s" % self.proxy_username
69 if self.proxy_password:
70 retval += " --proxypasswd=%s" % self.proxy_password
71 if self.debuginfo:
72 retval += " --debuginfo"
73 if self.source:
74 retval += " --source"
75 if self.gpgkey:
76 retval += " --gpgkey=%s" % self.gpgkey
77 if self.disable:
78 retval += " --disable"
79 if self.ssl_verify:
80 retval += " --ssl_verify=%s" % self.ssl_verify
81 if self.priority:
82 retval += " --priority=%s" % self.priority
83 if self.nocache:
84 retval += " --nocache"
85
86 return retval
87
88class Mic_Repo(F8_Repo):
89 def __init__(self, writePriority=0, repoList=None):
90 F8_Repo.__init__(self, writePriority, repoList)
91
92 def __str__(self):
93 retval = ""
94 for repo in self.repoList:
95 retval += repo.__str__()
96
97 return retval
98
99 def _getParser(self):
100 def list_cb (option, opt_str, value, parser):
101 for d in value.split(','):
102 parser.values.ensure_value(option.dest, []).append(d)
103
104 op = F8_Repo._getParser(self)
105 op.add_option("--save", action="store_true", dest="save",
106 default=False)
107 op.add_option("--proxy", type="string", action="store", dest="proxy",
108 default=None, nargs=1)
109 op.add_option("--proxyuser", type="string", action="store",
110 dest="proxy_username", default=None, nargs=1)
111 op.add_option("--proxypasswd", type="string", action="store",
112 dest="proxy_password", default=None, nargs=1)
113 op.add_option("--debuginfo", action="store_true", dest="debuginfo",
114 default=False)
115 op.add_option("--source", action="store_true", dest="source",
116 default=False)
117 op.add_option("--disable", action="store_true", dest="disable",
118 default=False)
119 op.add_option("--gpgkey", type="string", action="store", dest="gpgkey",
120 default=None, nargs=1)
121 op.add_option("--ssl_verify", type="string", action="store",
122 dest="ssl_verify", default="yes")
123 op.add_option("--priority", type="int", action="store", dest="priority",
124 default=None)
125 op.add_option("--nocache", action="store_true", dest="nocache",
126 default=False)
127 return op
diff --git a/scripts/lib/mic/kickstart/custom_commands/partition.py b/scripts/lib/mic/kickstart/custom_commands/partition.py
new file mode 100644
index 0000000000..450d2d492d
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/partition.py
@@ -0,0 +1,482 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module provides the OpenEmbedded partition object definitions.
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27import shutil
28
29from pykickstart.commands.partition import *
30from mic.utils.oe.misc import *
31from mic.kickstart.custom_commands import *
32from mic.plugin import pluginmgr
33
34import os
35from mic.utils.oe.package_manager import *
36
37partition_methods = {
38 "do_install_pkgs":None,
39 "do_stage_partition":None,
40 "do_prepare_partition":None,
41 "do_configure_partition":None,
42}
43
44class Wic_PartData(Mic_PartData):
45 removedKeywords = Mic_PartData.removedKeywords
46 removedAttrs = Mic_PartData.removedAttrs
47
48 def __init__(self, *args, **kwargs):
49 Mic_PartData.__init__(self, *args, **kwargs)
50 self.deleteRemovedAttrs()
51 self.source = kwargs.get("source", None)
52 self.rootfs = kwargs.get("rootfs-dir", None)
53 self.source_file = ""
54 self.size = 0
55
56 def _getArgsAsStr(self):
57 retval = Mic_PartData._getArgsAsStr(self)
58
59 if self.source:
60 retval += " --source=%s" % self.source
61 if self.rootfs:
62 retval += " --rootfs-dir=%s" % self.rootfs
63
64 return retval
65
66 def get_rootfs(self):
67 """
68 Acessor for rootfs dir
69 """
70 return self.rootfs
71
72 def set_rootfs(self, rootfs):
73 """
74 Acessor for actual rootfs dir, which must be set by source
75 plugins.
76 """
77 self.rootfs = rootfs
78
79 def get_size(self):
80 """
81 Accessor for partition size, 0 or --size before set_size().
82 """
83 return self.size
84
85 def set_size(self, size):
86 """
87 Accessor for actual partition size, which must be set by source
88 plugins.
89 """
90 self.size = size
91
92 def set_source_file(self, source_file):
93 """
94 Accessor for source_file, the location of the generated partition
95 image, which must be set by source plugins.
96 """
97 self.source_file = source_file
98
99 def get_extra_block_count(self, current_blocks):
100 """
101 The --size param is reflected in self.size (in MB), and we already
102 have current_blocks (1k) blocks, calculate and return the
103 number of (1k) blocks we need to add to get to --size, 0 if
104 we're already there or beyond.
105 """
106 msger.debug("Requested partition size for %s: %d" % \
107 (self.mountpoint, self.size))
108
109 if not self.size:
110 return 0
111
112 requested_blocks = self.size * 1024
113
114 msger.debug("Requested blocks %d, current_blocks %d" % \
115 (requested_blocks, current_blocks))
116
117 if requested_blocks > current_blocks:
118 return requested_blocks - current_blocks
119 else:
120 return 0
121
122 def install_pkgs(self, creator, cr_workdir, oe_builddir, rootfs_dir,
123 bootimg_dir, kernel_dir, native_sysroot):
124 """
125 Prepare content for individual partitions, installing packages.
126 """
127
128 if not self.source:
129 return
130
131 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
132 self._source_methods["do_install_pkgs"](self, creator,
133 cr_workdir,
134 oe_builddir,
135 rootfs_dir,
136 bootimg_dir,
137 kernel_dir,
138 native_sysroot)
139
140 def install_pkgs_ipk(self, cr_workdir, oe_builddir, rootfs_dir,
141 native_sysroot, packages, repourl):
142 """
143 Install packages specified into wks file using opkg package manager.
144 This method is dependend on bb module.
145 """
146
147 gVar = {}
148 gVar["DEPLOY_DIR_IPK"] = os.path.join(oe_builddir, "tmp/deploy/ipk")
149
150 # Run postinstall scripts even in offline mode
151 # Use the arch priority package rather than higher version one if more than one candidate is found.
152 #d.setVar("OPKG_ARGS", "--force_postinstall --prefer-arch-to-version")
153 gVar["OPKG_ARGS"] = "--force_postinstall"
154
155 # OPKG path relative to /output_path
156 gVar["OPKGLIBDIR"] = "var/lib"
157
158 source_url = repourl.split()
159
160 # Generate feed uri's names, it doesn't seem to matter what name they have
161 feed_uris = ""
162 cnt = 0
163 archs = ""
164 for url in source_url:
165 feed_uris += "cl_def_feed%d##%s\n" % (cnt, url)
166 cnt += 1
167 head, tail = os.path.split(url)
168 archs += " " + tail
169
170 # IPK_FEED_URIS with special formating defines the URI's used as source for packages
171 gVar['IPK_FEED_URIS'] = feed_uris
172
173 gVar['BUILD_IMAGES_FROM_FEEDS'] = "1"
174
175 # We need to provide sysroot for utilities
176 gVar['STAGING_DIR_NATIVE'] = native_sysroot
177
178 # Set WORKDIR for output
179 gVar['WORKDIR'] = cr_workdir
180
181 # Set TMPDIR for output
182 gVar['TMPDIR'] = os.path.join(cr_workdir, "tmp")
183
184 if 'ROOTFS_DIR' in rootfs_dir:
185 target_dir = rootfs_dir['ROOTFS_DIR']
186 elif os.path.isdir(rootfs_dir):
187 target_dir = rootfs_dir
188 else:
189 msg = "Couldn't find --rootfs-dir=%s connection"
190 msg += " or it is not a valid path, exiting"
191 msger.error(msg % rootfs_dir)
192
193 # Need native sysroot /usr/bin/ for opkg-cl
194 # chnage PATH var to avoid issues with host tools
195 defpath = os.environ['PATH']
196 os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
197
198 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
199 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % target_dir
200 pseudo += "export PSEUDO_PASSWD=%s;" % target_dir
201 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
202 pseudo += "%s/usr/bin/pseudo " % native_sysroot
203
204 pm = WicOpkgPM(gVar,
205 target_dir,
206 'opkg.conf',
207 archs,
208 pseudo,
209 native_sysroot)
210
211 pm.update()
212
213 pm.install(packages)
214
215 os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
216
217
218 def prepare(self, cr, cr_workdir, oe_builddir, rootfs_dir, bootimg_dir,
219 kernel_dir, native_sysroot):
220 """
221 Prepare content for individual partitions, depending on
222 partition command parameters.
223 """
224 if not self.source:
225 if self.fstype and self.fstype == "swap":
226 self.prepare_swap_partition(cr_workdir, oe_builddir,
227 native_sysroot)
228 elif self.fstype:
229 self.prepare_empty_partition(cr_workdir, oe_builddir,
230 native_sysroot)
231 return
232
233 self._source_methods = pluginmgr.get_source_plugin_methods(self.source, partition_methods)
234 self._source_methods["do_configure_partition"](self, cr, cr_workdir,
235 oe_builddir,
236 bootimg_dir,
237 kernel_dir,
238 native_sysroot)
239 self._source_methods["do_stage_partition"](self, cr, cr_workdir,
240 oe_builddir,
241 bootimg_dir, kernel_dir,
242 native_sysroot)
243 self._source_methods["do_prepare_partition"](self, cr, cr_workdir,
244 oe_builddir,
245 bootimg_dir, kernel_dir, rootfs_dir,
246 native_sysroot)
247
248 def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
249 rootfs_dir):
250 """
251 Handle an already-created partition e.g. xxx.ext3
252 """
253 rootfs = oe_builddir
254 du_cmd = "du -Lbms %s" % rootfs
255 rc, out = exec_cmd(du_cmd)
256 rootfs_size = out.split()[0]
257
258 self.size = rootfs_size
259 self.source_file = rootfs
260
261 def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
262 native_sysroot):
263 """
264 Prepare content for a rootfs partition i.e. create a partition
265 and fill it from a /rootfs dir.
266
267 Currently handles ext2/3/4 and btrfs.
268 """
269 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
270 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
271 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
272 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
273 pseudo += "%s/usr/bin/pseudo " % native_sysroot
274
275 if self.fstype.startswith("ext"):
276 return self.prepare_rootfs_ext(cr_workdir, oe_builddir,
277 rootfs_dir, native_sysroot,
278 pseudo)
279 elif self.fstype.startswith("btrfs"):
280 return self.prepare_rootfs_btrfs(cr_workdir, oe_builddir,
281 rootfs_dir, native_sysroot,
282 pseudo)
283
284 def prepare_rootfs_ext(self, cr_workdir, oe_builddir, rootfs_dir,
285 native_sysroot, pseudo):
286 """
287 Prepare content for an ext2/3/4 rootfs partition.
288 """
289
290 image_rootfs = rootfs_dir
291 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label ,self.fstype)
292
293 du_cmd = "du -ks %s" % image_rootfs
294 rc, out = exec_cmd(du_cmd)
295 actual_rootfs_size = int(out.split()[0])
296
297 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
298
299 if extra_blocks < IMAGE_EXTRA_SPACE:
300 extra_blocks = IMAGE_EXTRA_SPACE
301
302 rootfs_size = actual_rootfs_size + extra_blocks
303
304 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
305 (extra_blocks, self.mountpoint, rootfs_size))
306
307 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
308 (rootfs, rootfs_size)
309 rc, out = exec_cmd(dd_cmd)
310
311 extra_imagecmd = "-i 8192"
312
313 mkfs_cmd = "mkfs.%s -F %s %s -d %s" % \
314 (self.fstype, extra_imagecmd, rootfs, image_rootfs)
315 rc, out = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
316
317
318 # get the rootfs size in the right units for kickstart (Mb)
319 du_cmd = "du -Lbms %s" % rootfs
320 rc, out = exec_cmd(du_cmd)
321 rootfs_size = out.split()[0]
322
323 self.size = rootfs_size
324 self.source_file = rootfs
325
326 return 0
327
328 def prepare_for_uboot(self, arch, cr_workdir, oe_builddir, rootfs_dir,
329 native_sysroot):
330 """
331 Generates u-boot image from source_file( ext2/3/4 )
332
333 """
334 pseudo = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
335 pseudo += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
336 pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
337 pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
338 pseudo += "%s/usr/bin/pseudo " % native_sysroot
339
340 # 1) compress image
341 rootfs = self.source_file
342 rootfs_gzip = "%s.gz" % rootfs
343 gzip_cmd = "gzip -f -9 -c %s > %s" % (rootfs, rootfs_gzip)
344 rc, out = exec_native_cmd(pseudo + gzip_cmd, native_sysroot)
345
346 # 2) image for U-Boot
347 rootfs_uboot = "%s.u-boot" % rootfs_gzip
348 mkimage_cmd = "mkimage -A %s -O linux -T ramdisk -C gzip -n %s -d %s %s" % \
349 (arch, self.label, rootfs_gzip, rootfs_uboot)
350 rc, out = exec_native_cmd(pseudo + mkimage_cmd, native_sysroot)
351
352 msger.info("\n\n\tThe new U-Boot ramdisk image can be found here:\n\t\t%s\n\n" % rootfs_uboot)
353
354 return 0
355
356 def prepare_rootfs_btrfs(self, cr_workdir, oe_builddir, rootfs_dir,
357 native_sysroot, pseudo):
358 """
359 Prepare content for a btrfs rootfs partition.
360
361 Currently handles ext2/3/4 and btrfs.
362 """
363 image_rootfs = rootfs_dir
364 rootfs = "%s/rootfs_%s.%s" % (cr_workdir, self.label, self.fstype)
365
366 du_cmd = "du -ks %s" % image_rootfs
367 rc, out = exec_cmd(du_cmd)
368 actual_rootfs_size = int(out.split()[0])
369
370 extra_blocks = self.get_extra_block_count(actual_rootfs_size)
371
372 if extra_blocks < IMAGE_EXTRA_SPACE:
373 extra_blocks = IMAGE_EXTRA_SPACE
374
375 rootfs_size = actual_rootfs_size + extra_blocks
376
377 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
378 (extra_blocks, self.mountpoint, rootfs_size))
379
380 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
381 (rootfs, rootfs_size)
382 rc, out = exec_cmd(dd_cmd)
383
384 mkfs_cmd = "mkfs.%s -b %d -r %s %s" % \
385 (self.fstype, rootfs_size * 1024, image_rootfs, rootfs)
386 rc, out = exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
387
388 # get the rootfs size in the right units for kickstart (Mb)
389 du_cmd = "du -Lbms %s" % rootfs
390 rc, out = exec_cmd(du_cmd)
391 rootfs_size = out.split()[0]
392
393 self.size = rootfs_size
394 self.source_file = rootfs
395
396 def prepare_empty_partition(self, cr_workdir, oe_builddir, native_sysroot):
397 """
398 Prepare an empty partition.
399 """
400 if self.fstype.startswith("ext"):
401 return self.prepare_empty_partition_ext(cr_workdir, oe_builddir,
402 native_sysroot)
403 elif self.fstype.startswith("btrfs"):
404 return self.prepare_empty_partition_btrfs(cr_workdir, oe_builddir,
405 native_sysroot)
406
407 def prepare_empty_partition_ext(self, cr_workdir, oe_builddir,
408 native_sysroot):
409 """
410 Prepare an empty ext2/3/4 partition.
411 """
412 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
413
414 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
415 (fs, self.size)
416 rc, out = exec_cmd(dd_cmd)
417
418 extra_imagecmd = "-i 8192"
419
420 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
421 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
422
423 self.source_file = fs
424
425 return 0
426
427 def prepare_empty_partition_btrfs(self, cr_workdir, oe_builddir,
428 native_sysroot):
429 """
430 Prepare an empty btrfs partition.
431 """
432 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
433
434 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
435 (fs, self.size)
436 rc, out = exec_cmd(dd_cmd)
437
438 mkfs_cmd = "mkfs.%s -b %d %s" % (self.fstype, self.size * 1024, rootfs)
439 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
440
441 mkfs_cmd = "mkfs.%s -F %s %s" % (self.fstype, extra_imagecmd, fs)
442 rc, out = exec_native_cmd(mkfs_cmd, native_sysroot)
443
444 self.source_file = fs
445
446 return 0
447
448 def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot):
449 """
450 Prepare a swap partition.
451 """
452 fs = "%s/fs.%s" % (cr_workdir, self.fstype)
453
454 dd_cmd = "dd if=/dev/zero of=%s bs=1M seek=%d count=0" % \
455 (fs, self.size)
456 rc, out = exec_cmd(dd_cmd)
457
458 import uuid
459 label_str = ""
460 if self.label:
461 label_str = "-L %s" % self.label
462 mkswap_cmd = "mkswap %s -U %s %s" % (label_str, str(uuid.uuid1()), fs)
463 rc, out = exec_native_cmd(mkswap_cmd, native_sysroot)
464
465 self.source_file = fs
466
467 return 0
468
469class Wic_Partition(Mic_Partition):
470 removedKeywords = Mic_Partition.removedKeywords
471 removedAttrs = Mic_Partition.removedAttrs
472
473 def _getParser(self):
474 op = Mic_Partition._getParser(self)
475 # use specified source file to fill the partition
476 # and calculate partition size
477 op.add_option("--source", type="string", action="store",
478 dest="source", default=None)
479 # use specified rootfs path to fill the partition
480 op.add_option("--rootfs-dir", type="string", action="store",
481 dest="rootfs", default=None)
482 return op
diff --git a/scripts/lib/mic/kickstart/custom_commands/wicboot.py b/scripts/lib/mic/kickstart/custom_commands/wicboot.py
new file mode 100644
index 0000000000..ab8871de4e
--- /dev/null
+++ b/scripts/lib/mic/kickstart/custom_commands/wicboot.py
@@ -0,0 +1,57 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module provides the OpenEmbedded bootloader object definitions.
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27from pykickstart.base import *
28from pykickstart.errors import *
29from pykickstart.options import *
30from pykickstart.commands.bootloader import *
31
32from mic.kickstart.custom_commands.micboot import *
33
34class Wic_Bootloader(Mic_Bootloader):
35 def __init__(self, writePriority=10, appendLine="", driveorder=None,
36 forceLBA=False, location="", md5pass="", password="",
37 upgrade=False, menus=""):
38 Mic_Bootloader.__init__(self, writePriority, appendLine, driveorder,
39 forceLBA, location, md5pass, password, upgrade)
40
41 self.source = ""
42
43 def _getArgsAsStr(self):
44 retval = Mic_Bootloader._getArgsAsStr(self)
45
46 if self.source:
47 retval += " --source=%s" % self.source
48
49 return retval
50
51 def _getParser(self):
52 op = Mic_Bootloader._getParser(self)
53 # use specified source plugin to implement bootloader-specific methods
54 op.add_option("--source", type="string", action="store",
55 dest="source", default=None)
56 return op
57
diff --git a/scripts/lib/mic/msger.py b/scripts/lib/mic/msger.py
new file mode 100644
index 0000000000..9afc85be93
--- /dev/null
+++ b/scripts/lib/mic/msger.py
@@ -0,0 +1,309 @@
1#!/usr/bin/python -tt
2# vim: ai ts=4 sts=4 et sw=4
3#
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19import os,sys
20import re
21import time
22
23__ALL__ = ['set_mode',
24 'get_loglevel',
25 'set_loglevel',
26 'set_logfile',
27 'raw',
28 'debug',
29 'verbose',
30 'info',
31 'warning',
32 'error',
33 'ask',
34 'pause',
35 ]
36
37# COLORs in ANSI
38INFO_COLOR = 32 # green
39WARN_COLOR = 33 # yellow
40ERR_COLOR = 31 # red
41ASK_COLOR = 34 # blue
42NO_COLOR = 0
43
44PREFIX_RE = re.compile('^<(.*?)>\s*(.*)', re.S)
45
46INTERACTIVE = True
47
48LOG_LEVEL = 1
49LOG_LEVELS = {
50 'quiet': 0,
51 'normal': 1,
52 'verbose': 2,
53 'debug': 3,
54 'never': 4,
55 }
56
57LOG_FILE_FP = None
58LOG_CONTENT = ''
59CATCHERR_BUFFILE_FD = -1
60CATCHERR_BUFFILE_PATH = None
61CATCHERR_SAVED_2 = -1
62
63def _general_print(head, color, msg = None, stream = None, level = 'normal'):
64 global LOG_CONTENT
65 if not stream:
66 stream = sys.stdout
67
68 if LOG_LEVELS[level] > LOG_LEVEL:
69 # skip
70 return
71
72 # encode raw 'unicode' str to utf8 encoded str
73 if msg and isinstance(msg, unicode):
74 msg = msg.encode('utf-8', 'ignore')
75
76 errormsg = ''
77 if CATCHERR_BUFFILE_FD > 0:
78 size = os.lseek(CATCHERR_BUFFILE_FD , 0, os.SEEK_END)
79 os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_SET)
80 errormsg = os.read(CATCHERR_BUFFILE_FD, size)
81 os.ftruncate(CATCHERR_BUFFILE_FD, 0)
82
83 # append error msg to LOG
84 if errormsg:
85 LOG_CONTENT += errormsg
86
87 # append normal msg to LOG
88 save_msg = msg.strip() if msg else None
89 if save_msg:
90 timestr = time.strftime("[%m/%d %H:%M:%S %Z] ", time.localtime())
91 LOG_CONTENT += timestr + save_msg + '\n'
92
93 if errormsg:
94 _color_print('', NO_COLOR, errormsg, stream, level)
95
96 _color_print(head, color, msg, stream, level)
97
98def _color_print(head, color, msg, stream, level):
99 colored = True
100 if color == NO_COLOR or \
101 not stream.isatty() or \
102 os.getenv('ANSI_COLORS_DISABLED') is not None:
103 colored = False
104
105 if head.startswith('\r'):
106 # need not \n at last
107 newline = False
108 else:
109 newline = True
110
111 if colored:
112 head = '\033[%dm%s:\033[0m ' %(color, head)
113 if not newline:
114 # ESC cmd to clear line
115 head = '\033[2K' + head
116 else:
117 if head:
118 head += ': '
119 if head.startswith('\r'):
120 head = head.lstrip()
121 newline = True
122
123 if msg is not None:
124 if isinstance(msg, unicode):
125 msg = msg.encode('utf8', 'ignore')
126
127 stream.write('%s%s' % (head, msg))
128 if newline:
129 stream.write('\n')
130
131 stream.flush()
132
133def _color_perror(head, color, msg, level = 'normal'):
134 if CATCHERR_BUFFILE_FD > 0:
135 _general_print(head, color, msg, sys.stdout, level)
136 else:
137 _general_print(head, color, msg, sys.stderr, level)
138
139def _split_msg(head, msg):
140 if isinstance(msg, list):
141 msg = '\n'.join(map(str, msg))
142
143 if msg.startswith('\n'):
144 # means print \n at first
145 msg = msg.lstrip()
146 head = '\n' + head
147
148 elif msg.startswith('\r'):
149 # means print \r at first
150 msg = msg.lstrip()
151 head = '\r' + head
152
153 m = PREFIX_RE.match(msg)
154 if m:
155 head += ' <%s>' % m.group(1)
156 msg = m.group(2)
157
158 return head, msg
159
160def get_loglevel():
161 return (k for k,v in LOG_LEVELS.items() if v==LOG_LEVEL).next()
162
163def set_loglevel(level):
164 global LOG_LEVEL
165 if level not in LOG_LEVELS:
166 # no effect
167 return
168
169 LOG_LEVEL = LOG_LEVELS[level]
170
171def set_interactive(mode=True):
172 global INTERACTIVE
173 if mode:
174 INTERACTIVE = True
175 else:
176 INTERACTIVE = False
177
178def log(msg=''):
179 # log msg to LOG_CONTENT then save to logfile
180 global LOG_CONTENT
181 if msg:
182 LOG_CONTENT += msg
183
184def raw(msg=''):
185 _general_print('', NO_COLOR, msg)
186
187def info(msg):
188 head, msg = _split_msg('Info', msg)
189 _general_print(head, INFO_COLOR, msg)
190
191def verbose(msg):
192 head, msg = _split_msg('Verbose', msg)
193 _general_print(head, INFO_COLOR, msg, level = 'verbose')
194
195def warning(msg):
196 head, msg = _split_msg('Warning', msg)
197 _color_perror(head, WARN_COLOR, msg)
198
199def debug(msg):
200 head, msg = _split_msg('Debug', msg)
201 _color_perror(head, ERR_COLOR, msg, level = 'debug')
202
203def error(msg):
204 head, msg = _split_msg('Error', msg)
205 _color_perror(head, ERR_COLOR, msg)
206 sys.exit(1)
207
208def ask(msg, default=True):
209 _general_print('\rQ', ASK_COLOR, '')
210 try:
211 if default:
212 msg += '(Y/n) '
213 else:
214 msg += '(y/N) '
215 if INTERACTIVE:
216 while True:
217 repl = raw_input(msg)
218 if repl.lower() == 'y':
219 return True
220 elif repl.lower() == 'n':
221 return False
222 elif not repl.strip():
223 # <Enter>
224 return default
225
226 # else loop
227 else:
228 if default:
229 msg += ' Y'
230 else:
231 msg += ' N'
232 _general_print('', NO_COLOR, msg)
233
234 return default
235 except KeyboardInterrupt:
236 sys.stdout.write('\n')
237 sys.exit(2)
238
239def choice(msg, choices, default=0):
240 if default >= len(choices):
241 return None
242 _general_print('\rQ', ASK_COLOR, '')
243 try:
244 msg += " [%s] " % '/'.join(choices)
245 if INTERACTIVE:
246 while True:
247 repl = raw_input(msg)
248 if repl in choices:
249 return repl
250 elif not repl.strip():
251 return choices[default]
252 else:
253 msg += choices[default]
254 _general_print('', NO_COLOR, msg)
255
256 return choices[default]
257 except KeyboardInterrupt:
258 sys.stdout.write('\n')
259 sys.exit(2)
260
261def pause(msg=None):
262 if INTERACTIVE:
263 _general_print('\rQ', ASK_COLOR, '')
264 if msg is None:
265 msg = 'press <ENTER> to continue ...'
266 raw_input(msg)
267
268def set_logfile(fpath):
269 global LOG_FILE_FP
270
271 def _savelogf():
272 if LOG_FILE_FP:
273 fp = open(LOG_FILE_FP, 'w')
274 fp.write(LOG_CONTENT)
275 fp.close()
276
277 if LOG_FILE_FP is not None:
278 warning('duplicate log file configuration')
279
280 LOG_FILE_FP = fpath
281
282 import atexit
283 atexit.register(_savelogf)
284
285def enable_logstderr(fpath):
286 global CATCHERR_BUFFILE_FD
287 global CATCHERR_BUFFILE_PATH
288 global CATCHERR_SAVED_2
289
290 if os.path.exists(fpath):
291 os.remove(fpath)
292 CATCHERR_BUFFILE_PATH = fpath
293 CATCHERR_BUFFILE_FD = os.open(CATCHERR_BUFFILE_PATH, os.O_RDWR|os.O_CREAT)
294 CATCHERR_SAVED_2 = os.dup(2)
295 os.dup2(CATCHERR_BUFFILE_FD, 2)
296
297def disable_logstderr():
298 global CATCHERR_BUFFILE_FD
299 global CATCHERR_BUFFILE_PATH
300 global CATCHERR_SAVED_2
301
302 raw(msg = None) # flush message buffer and print it.
303 os.dup2(CATCHERR_SAVED_2, 2)
304 os.close(CATCHERR_SAVED_2)
305 os.close(CATCHERR_BUFFILE_FD)
306 os.unlink(CATCHERR_BUFFILE_PATH)
307 CATCHERR_BUFFILE_FD = -1
308 CATCHERR_BUFFILE_PATH = None
309 CATCHERR_SAVED_2 = -1
diff --git a/scripts/lib/mic/plugin.py b/scripts/lib/mic/plugin.py
new file mode 100644
index 0000000000..df03c15081
--- /dev/null
+++ b/scripts/lib/mic/plugin.py
@@ -0,0 +1,121 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os, sys
19
20from mic import msger
21from mic import pluginbase
22from mic.utils import errors
23
24
25__ALL__ = ['PluginMgr', 'pluginmgr']
26
27PLUGIN_TYPES = ["imager", "source"] # TODO "hook"
28
29
30class PluginMgr(object):
31 plugin_dirs = {}
32
33 # make the manager class as singleton
34 _instance = None
35 def __new__(cls, *args, **kwargs):
36 if not cls._instance:
37 cls._instance = super(PluginMgr, cls).__new__(cls, *args, **kwargs)
38
39 return cls._instance
40
41 def __init__(self):
42 mic_path = os.path.dirname(__file__)
43 eos = mic_path.find('scripts') + len('scripts')
44 scripts_path = mic_path[:eos]
45
46 self.plugin_dir = scripts_path + "/lib/mic/plugins"
47
48 def append_dirs(self, dirs):
49 for path in dirs:
50 self._add_plugindir(path)
51
52 # load all the plugins AGAIN
53 self._load_all()
54
55 def _add_plugindir(self, path):
56 path = os.path.abspath(os.path.expanduser(path))
57
58 if not os.path.isdir(path):
59 msger.warning("Plugin dir is not a directory or does not exist: %s"\
60 % path)
61 return
62
63 if path not in self.plugin_dirs:
64 self.plugin_dirs[path] = False
65 # the value True/False means "loaded"
66
67 def _load_all(self):
68 for (pdir, loaded) in self.plugin_dirs.iteritems():
69 if loaded: continue
70
71 sys.path.insert(0, pdir)
72 for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]:
73 if mod and mod != '__init__':
74 if mod in sys.modules:
75 #self.plugin_dirs[pdir] = True
76 msger.warning("Module %s already exists, skip" % mod)
77 else:
78 try:
79 pymod = __import__(mod)
80 self.plugin_dirs[pdir] = True
81 msger.debug("Plugin module %s:%s imported"\
82 % (mod, pymod.__file__))
83 except ImportError, err:
84 msg = 'Failed to load plugin %s/%s: %s' \
85 % (os.path.basename(pdir), mod, err)
86 msger.warning(msg)
87
88 del(sys.path[0])
89
90 def get_plugins(self, ptype):
91 """ the return value is dict of name:class pairs """
92
93 if ptype not in PLUGIN_TYPES:
94 raise errors.CreatorError('%s is not valid plugin type' % ptype)
95
96 self._add_plugindir(os.path.join(self.plugin_dir, ptype))
97 self._load_all()
98
99 return pluginbase.get_plugins(ptype)
100
101 def get_source_plugin_methods(self, source_name, methods):
102 """
103 The methods param is a dict with the method names to find. On
104 return, the dict values will be filled in with pointers to the
105 corresponding methods. If one or more methods are not found,
106 None is returned.
107 """
108 return_methods = None
109 for _source_name, klass in self.get_plugins('source').iteritems():
110 if _source_name == source_name:
111 for _method_name in methods.keys():
112 if not hasattr(klass, _method_name):
113 msger.warning("Unimplemented %s source interface for: %s"\
114 % (_method_name, _source_name))
115 return None
116 func = getattr(klass, _method_name)
117 methods[_method_name] = func
118 return_methods = methods
119 return return_methods
120
121pluginmgr = PluginMgr()
diff --git a/scripts/lib/mic/pluginbase.py b/scripts/lib/mic/pluginbase.py
new file mode 100644
index 0000000000..881d9969c6
--- /dev/null
+++ b/scripts/lib/mic/pluginbase.py
@@ -0,0 +1,158 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20from mic import msger
21from mic.utils import errors
22
23class _Plugin(object):
24 class __metaclass__(type):
25 def __init__(cls, name, bases, attrs):
26 if not hasattr(cls, 'plugins'):
27 cls.plugins = {}
28
29 elif 'mic_plugin_type' in attrs:
30 if attrs['mic_plugin_type'] not in cls.plugins:
31 cls.plugins[attrs['mic_plugin_type']] = {}
32
33 elif hasattr(cls, 'mic_plugin_type') and 'name' in attrs:
34 cls.plugins[cls.mic_plugin_type][attrs['name']] = cls
35
36 def show_plugins(cls):
37 for cls in cls.plugins[cls.mic_plugin_type]:
38 print cls
39
40 def get_plugins(cls):
41 return cls.plugins
42
43class ImagerPlugin(_Plugin):
44 mic_plugin_type = "imager"
45
46 @classmethod
47 def check_image_exists(self, destdir, apacking=None,
48 images=(),
49 release=None):
50
51 # if it's a packing file, reset images
52 if apacking:
53 images = [apacking]
54
55 # release option will override images
56 if release is not None:
57 images = [os.path.basename(destdir.rstrip('/'))]
58 destdir = os.path.dirname(destdir.rstrip('/'))
59
60 for name in images:
61 if not name:
62 continue
63
64 image = os.path.join(destdir, name)
65 if not os.path.exists(image):
66 continue
67
68 if msger.ask("Target image/dir: %s already exists, "
69 "clean up and continue?" % image):
70 if os.path.isdir(image):
71 shutil.rmtree(image)
72 else:
73 os.unlink(image)
74 else:
75 raise errors.Abort("Cancled")
76
77 def do_create(self):
78 pass
79
80 def do_chroot(self):
81 pass
82
83class SourcePlugin(_Plugin):
84 mic_plugin_type = "source"
85 """
86 The methods that can be implemented by --source plugins.
87
88 Any methods not implemented in a subclass inherit these.
89 """
90
91 @classmethod
92 def do_install_pkgs(self, part, creator, cr_workdir, oe_builddir, rootfs_dir,
93 bootimg_dir, kernel_dir, native_sysroot):
94 """
95 Called before partitions have been prepared and assembled into a
96 disk image. Install packages into rootfs
97 """
98 msger.debug("SourcePlugin: do_install_pkgs: part %s" % part)
99
100 @classmethod
101 def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir,
102 bootimg_dir, kernel_dir, native_sysroot):
103 """
104 Called after all partitions have been prepared and assembled into a
105 disk image. This provides a hook to allow finalization of a
106 disk image e.g. to write an MBR to it.
107 """
108 msger.debug("SourcePlugin: do_install_disk: disk: %s" % disk_name)
109
110 @classmethod
111 def do_stage_partition(self, part, cr, workdir, oe_builddir, bootimg_dir,
112 kernel_dir, native_sysroot):
113 """
114 Special content staging hook called before do_prepare_partition(),
115 normally empty.
116
117 Typically, a partition will just use the passed-in parame e.g
118 straight bootimg_dir, etc, but in some cases, things need to
119 be more tailored e.g. to use a deploy dir + /boot, etc. This
120 hook allows those files to be staged in a customized fashion.
121 Not that get_bitbake_var() allows you to acces non-standard
122 variables that you might want to use for this.
123 """
124 msger.debug("SourcePlugin: do_stage_partition: part: %s" % part)
125
126 @classmethod
127 def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
128 bootimg_dir, kernel_dir, native_sysroot):
129 """
130 Called before do_prepare_partition(), typically used to create
131 custom configuration files for a partition, for example
132 syslinux or grub config files.
133 """
134 msger.debug("SourcePlugin: do_configure_partition: part: %s" % part)
135
136 @classmethod
137 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
138 kernel_dir, rootfs_dir, native_sysroot):
139 """
140 Called to do the actual content population for a partition i.e. it
141 'prepares' the partition to be incorporated into the image.
142 """
143 msger.debug("SourcePlugin: do_prepare_partition: part: %s" % part)
144
145class BackendPlugin(_Plugin):
146 mic_plugin_type="backend"
147
148 def addRepository(self):
149 pass
150
151def get_plugins(typen):
152 ps = ImagerPlugin.get_plugins()
153 if typen in ps:
154 return ps[typen]
155 else:
156 return None
157
158__all__ = ['ImagerPlugin', 'BackendPlugin', 'SourcePlugin', 'get_plugins']
diff --git a/scripts/lib/mic/plugins/backend/yumpkgmgr.py b/scripts/lib/mic/plugins/backend/yumpkgmgr.py
new file mode 100644
index 0000000000..955f813109
--- /dev/null
+++ b/scripts/lib/mic/plugins/backend/yumpkgmgr.py
@@ -0,0 +1,490 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007 Red Hat Inc.
4# Copyright (c) 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19import os, sys
20import re
21import tempfile
22import glob
23from string import Template
24
25import rpmUtils
26import yum
27
28from mic import msger
29from mic.kickstart import ksparser
30from mic.utils import misc, rpmmisc
31from mic.utils.grabber import TextProgress
32from mic.utils.proxy import get_proxy_for
33from mic.utils.errors import CreatorError
34from mic.imager.baseimager import BaseImageCreator
35
36YUMCONF_TEMP = """[main]
37installroot=$installroot
38cachedir=/var/cache/yum
39persistdir=/var/lib/yum
40plugins=0
41reposdir=
42failovermethod=priority
43http_caching=packages
44sslverify=1
45"""
46
47class MyYumRepository(yum.yumRepo.YumRepository):
48 def __del__(self):
49 pass
50
51 def dirSetup(self):
52 super(MyYumRepository, self).dirSetup()
53 # relocate package dir
54 pkgdir = os.path.join(self.basecachedir, 'packages', self.id)
55 self.setAttribute('_dir_setup_pkgdir', pkgdir)
56 self._dirSetupMkdir_p(self.pkgdir)
57
58 def _getFile(self, url=None,
59 relative=None,
60 local=None,
61 start=None,
62 end=None,
63 copy_local=None,
64 checkfunc=None,
65 text=None,
66 reget='simple',
67 cache=True,
68 size=None):
69
70 m2c_connection = None
71 if not self.sslverify:
72 try:
73 import M2Crypto
74 m2c_connection = M2Crypto.SSL.Connection.clientPostConnectionCheck
75 M2Crypto.SSL.Connection.clientPostConnectionCheck = None
76 except ImportError, err:
77 raise CreatorError("%s, please try to install python-m2crypto" % str(err))
78
79 proxy = None
80 if url:
81 proxy = get_proxy_for(url)
82 else:
83 proxy = get_proxy_for(self.urls[0])
84
85 if proxy:
86 self.proxy = str(proxy)
87
88 size = int(size) if size else None
89 rvalue = super(MyYumRepository, self)._getFile(url,
90 relative,
91 local,
92 start,
93 end,
94 copy_local,
95 checkfunc,
96 text,
97 reget,
98 cache,
99 size)
100
101 if m2c_connection and \
102 not M2Crypto.SSL.Connection.clientPostConnectionCheck:
103 M2Crypto.SSL.Connection.clientPostConnectionCheck = m2c_connection
104
105 return rvalue
106
107from mic.pluginbase import BackendPlugin
108class Yum(BackendPlugin, yum.YumBase):
109 name = 'yum'
110
111 def __init__(self, target_arch, instroot, cachedir):
112 yum.YumBase.__init__(self)
113
114 self.cachedir = cachedir
115 self.instroot = instroot
116 self.target_arch = target_arch
117
118 if self.target_arch:
119 if not rpmUtils.arch.arches.has_key(self.target_arch):
120 rpmUtils.arch.arches["armv7hl"] = "noarch"
121 rpmUtils.arch.arches["armv7tnhl"] = "armv7nhl"
122 rpmUtils.arch.arches["armv7tnhl"] = "armv7thl"
123 rpmUtils.arch.arches["armv7thl"] = "armv7hl"
124 rpmUtils.arch.arches["armv7nhl"] = "armv7hl"
125 self.arch.setup_arch(self.target_arch)
126
127 self.__pkgs_license = {}
128 self.__pkgs_content = {}
129 self.__pkgs_vcsinfo = {}
130
131 self.install_debuginfo = False
132
133 def doFileLogSetup(self, uid, logfile):
134 # don't do the file log for the livecd as it can lead to open fds
135 # being left and an inability to clean up after ourself
136 pass
137
138 def close(self):
139 try:
140 os.unlink(self.confpath)
141 os.unlink(self.conf.installroot + "/yum.conf")
142 except:
143 pass
144
145 if self.ts:
146 self.ts.close()
147 self._delRepos()
148 self._delSacks()
149 yum.YumBase.close(self)
150 self.closeRpmDB()
151
152 if not os.path.exists("/etc/fedora-release") and \
153 not os.path.exists("/etc/meego-release"):
154 for i in range(3, os.sysconf("SC_OPEN_MAX")):
155 try:
156 os.close(i)
157 except:
158 pass
159
160 def __del__(self):
161 pass
162
163 def _writeConf(self, confpath, installroot):
164 conf = Template(YUMCONF_TEMP).safe_substitute(installroot=installroot)
165
166 f = file(confpath, "w+")
167 f.write(conf)
168 f.close()
169
170 os.chmod(confpath, 0644)
171
172 def _cleanupRpmdbLocks(self, installroot):
173 # cleans up temporary files left by bdb so that differing
174 # versions of rpm don't cause problems
175 for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
176 os.unlink(f)
177
178 def setup(self):
179 # create yum.conf
180 (fn, self.confpath) = tempfile.mkstemp(dir=self.cachedir,
181 prefix='yum.conf-')
182 os.close(fn)
183 self._writeConf(self.confpath, self.instroot)
184 self._cleanupRpmdbLocks(self.instroot)
185 # do setup
186 self.doConfigSetup(fn = self.confpath, root = self.instroot)
187 self.conf.cache = 0
188 self.doTsSetup()
189 self.doRpmDBSetup()
190 self.doRepoSetup()
191 self.doSackSetup()
192
193 def preInstall(self, pkg):
194 # FIXME: handle pre-install package
195 return None
196
197 def selectPackage(self, pkg):
198 """Select a given package.
199 Can be specified with name.arch or name*
200 """
201
202 try:
203 self.install(pattern = pkg)
204 return None
205 except yum.Errors.InstallError:
206 return "No package(s) available to install"
207 except yum.Errors.RepoError, e:
208 raise CreatorError("Unable to download from repo : %s" % (e,))
209 except yum.Errors.YumBaseError, e:
210 raise CreatorError("Unable to install: %s" % (e,))
211
212 def deselectPackage(self, pkg):
213 """Deselect package. Can be specified as name.arch or name*
214 """
215
216 sp = pkg.rsplit(".", 2)
217 txmbrs = []
218 if len(sp) == 2:
219 txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
220
221 if len(txmbrs) == 0:
222 exact, match, unmatch = yum.packages.parsePackages(
223 self.pkgSack.returnPackages(),
224 [pkg],
225 casematch=1)
226 for p in exact + match:
227 txmbrs.append(p)
228
229 if len(txmbrs) > 0:
230 for x in txmbrs:
231 self.tsInfo.remove(x.pkgtup)
232 # we also need to remove from the conditionals
233 # dict so that things don't get pulled back in as a result
234 # of them. yes, this is ugly. conditionals should die.
235 for req, pkgs in self.tsInfo.conditionals.iteritems():
236 if x in pkgs:
237 pkgs.remove(x)
238 self.tsInfo.conditionals[req] = pkgs
239 else:
240 msger.warning("No such package %s to remove" %(pkg,))
241
242 def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
243 try:
244 yum.YumBase.selectGroup(self, grp)
245 if include == ksparser.GROUP_REQUIRED:
246 for p in grp.default_packages.keys():
247 self.deselectPackage(p)
248
249 elif include == ksparser.GROUP_ALL:
250 for p in grp.optional_packages.keys():
251 self.selectPackage(p)
252
253 return None
254 except (yum.Errors.InstallError, yum.Errors.GroupsError), e:
255 return e
256 except yum.Errors.RepoError, e:
257 raise CreatorError("Unable to download from repo : %s" % (e,))
258 except yum.Errors.YumBaseError, e:
259 raise CreatorError("Unable to install: %s" % (e,))
260
261 def addRepository(self, name, url = None, mirrorlist = None, proxy = None,
262 proxy_username = None, proxy_password = None,
263 inc = None, exc = None, ssl_verify=True, nocache=False,
264 cost = None, priority=None):
265 # TODO: Handle priority attribute for repos
266 def _varSubstitute(option):
267 # takes a variable and substitutes like yum configs do
268 option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
269 option = option.replace("$arch", rpmUtils.arch.getCanonArch())
270 return option
271
272 repo = MyYumRepository(name)
273
274 # Set proxy
275 repo.proxy = proxy
276 repo.proxy_username = proxy_username
277 repo.proxy_password = proxy_password
278
279 if url:
280 repo.baseurl.append(_varSubstitute(url))
281
282 # check LICENSE files
283 if not rpmmisc.checkRepositoryEULA(name, repo):
284 msger.warning('skip repo:%s for failed EULA confirmation' % name)
285 return None
286
287 if mirrorlist:
288 repo.mirrorlist = _varSubstitute(mirrorlist)
289
290 conf = yum.config.RepoConf()
291 for k, v in conf.iteritems():
292 if v or not hasattr(repo, k):
293 repo.setAttribute(k, v)
294
295 repo.sslverify = ssl_verify
296 repo.cache = not nocache
297
298 repo.basecachedir = self.cachedir
299 repo.base_persistdir = self.conf.persistdir
300 repo.failovermethod = "priority"
301 repo.metadata_expire = 0
302 # Enable gpg check for verifying corrupt packages
303 repo.gpgcheck = 1
304 repo.enable()
305 repo.setup(0)
306 self.repos.add(repo)
307 if cost:
308 repo.cost = cost
309
310 msger.verbose('repo: %s was added' % name)
311 return repo
312
313 def installLocal(self, pkg, po=None, updateonly=False):
314 ts = rpmUtils.transaction.initReadOnlyTransaction()
315 try:
316 hdr = rpmUtils.miscutils.hdrFromPackage(ts, pkg)
317 except rpmUtils.RpmUtilsError, e:
318 raise yum.Errors.MiscError, \
319 'Could not open local rpm file: %s: %s' % (pkg, e)
320
321 self.deselectPackage(hdr['name'])
322 yum.YumBase.installLocal(self, pkg, po, updateonly)
323
324 def installHasFile(self, file):
325 provides_pkg = self.whatProvides(file, None, None)
326 dlpkgs = map(
327 lambda x: x.po,
328 filter(
329 lambda txmbr: txmbr.ts_state in ("i", "u"),
330 self.tsInfo.getMembers()))
331
332 for p in dlpkgs:
333 for q in provides_pkg:
334 if (p == q):
335 return True
336
337 return False
338
339 def runInstall(self, checksize = 0):
340 os.environ["HOME"] = "/"
341 os.environ["LD_PRELOAD"] = ""
342 try:
343 (res, resmsg) = self.buildTransaction()
344 except yum.Errors.RepoError, e:
345 raise CreatorError("Unable to download from repo : %s" %(e,))
346
347 if res != 2:
348 raise CreatorError("Failed to build transaction : %s" \
349 % str.join("\n", resmsg))
350
351 dlpkgs = map(
352 lambda x: x.po,
353 filter(
354 lambda txmbr: txmbr.ts_state in ("i", "u"),
355 self.tsInfo.getMembers()))
356
357 # record all pkg and the content
358 for pkg in dlpkgs:
359 pkg_long_name = misc.RPM_FMT % {
360 'name': pkg.name,
361 'arch': pkg.arch,
362 'version': pkg.version,
363 'release': pkg.release
364 }
365 self.__pkgs_content[pkg_long_name] = pkg.files
366 license = pkg.license
367 if license in self.__pkgs_license.keys():
368 self.__pkgs_license[license].append(pkg_long_name)
369 else:
370 self.__pkgs_license[license] = [pkg_long_name]
371
372 total_count = len(dlpkgs)
373 cached_count = 0
374 download_total_size = sum(map(lambda x: int(x.packagesize), dlpkgs))
375
376 msger.info("\nChecking packages cached ...")
377 for po in dlpkgs:
378 local = po.localPkg()
379 repo = filter(lambda r: r.id == po.repoid, self.repos.listEnabled())[0]
380 if not repo.cache and os.path.exists(local):
381 os.unlink(local)
382 if not os.path.exists(local):
383 continue
384 if not self.verifyPkg(local, po, False):
385 msger.warning("Package %s is damaged: %s" \
386 % (os.path.basename(local), local))
387 else:
388 download_total_size -= int(po.packagesize)
389 cached_count +=1
390
391 cache_avail_size = misc.get_filesystem_avail(self.cachedir)
392 if cache_avail_size < download_total_size:
393 raise CreatorError("No enough space used for downloading.")
394
395 # record the total size of installed pkgs
396 pkgs_total_size = 0L
397 for x in dlpkgs:
398 if hasattr(x, 'installedsize'):
399 pkgs_total_size += int(x.installedsize)
400 else:
401 pkgs_total_size += int(x.size)
402
403 # check needed size before actually download and install
404 if checksize and pkgs_total_size > checksize:
405 raise CreatorError("No enough space used for installing, "
406 "please resize partition size in ks file")
407
408 msger.info("Packages: %d Total, %d Cached, %d Missed" \
409 % (total_count, cached_count, total_count - cached_count))
410
411 try:
412 repos = self.repos.listEnabled()
413 for repo in repos:
414 repo.setCallback(TextProgress(total_count - cached_count))
415
416 self.downloadPkgs(dlpkgs)
417 # FIXME: sigcheck?
418
419 self.initActionTs()
420 self.populateTs(keepold=0)
421
422 deps = self.ts.check()
423 if len(deps) != 0:
424 # This isn't fatal, Ubuntu has this issue but it is ok.
425 msger.debug(deps)
426 msger.warning("Dependency check failed!")
427
428 rc = self.ts.order()
429 if rc != 0:
430 raise CreatorError("ordering packages for installation failed")
431
432 # FIXME: callback should be refactored a little in yum
433 cb = rpmmisc.RPMInstallCallback(self.ts)
434 cb.tsInfo = self.tsInfo
435 cb.filelog = False
436
437 msger.warning('\nCaution, do NOT interrupt the installation, '
438 'else mic cannot finish the cleanup.')
439
440 installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
441 msger.enable_logstderr(installlogfile)
442 self.runTransaction(cb)
443 self._cleanupRpmdbLocks(self.conf.installroot)
444
445 except rpmUtils.RpmUtilsError, e:
446 raise CreatorError("mic does NOT support delta rpm: %s" % e)
447 except yum.Errors.RepoError, e:
448 raise CreatorError("Unable to download from repo : %s" % e)
449 except yum.Errors.YumBaseError, e:
450 raise CreatorError("Unable to install: %s" % e)
451 finally:
452 msger.disable_logstderr()
453
454 def getVcsInfo(self):
455 return self.__pkgs_vcsinfo
456
457 def getAllContent(self):
458 return self.__pkgs_content
459
460 def getPkgsLicense(self):
461 return self.__pkgs_license
462
463 def getFilelist(self, pkgname):
464 if not pkgname:
465 return None
466
467 pkg = filter(lambda txmbr: txmbr.po.name == pkgname, self.tsInfo.getMembers())
468 if not pkg:
469 return None
470 return pkg[0].po.filelist
471
472 def package_url(self, pkgname):
473 pkgs = self.pkgSack.searchNevra(name=pkgname)
474 if pkgs:
475 proxy = None
476 proxies = None
477 url = pkgs[0].remote_url
478 repoid = pkgs[0].repoid
479 repos = filter(lambda r: r.id == repoid, self.repos.listEnabled())
480
481 if repos:
482 proxy = repos[0].proxy
483 if not proxy:
484 proxy = get_proxy_for(url)
485 if proxy:
486 proxies = {str(url.split(':')[0]): str(proxy)}
487
488 return (url, proxies)
489
490 return (None, None)
diff --git a/scripts/lib/mic/plugins/backend/zypppkgmgr.py b/scripts/lib/mic/plugins/backend/zypppkgmgr.py
new file mode 100755
index 0000000000..c760859832
--- /dev/null
+++ b/scripts/lib/mic/plugins/backend/zypppkgmgr.py
@@ -0,0 +1,973 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import urlparse
21import rpm
22
23import zypp
24if not hasattr(zypp, 'PoolQuery') or \
25 not hasattr(zypp.RepoManager, 'loadSolvFile'):
26 raise ImportError("python-zypp in host system cannot support PoolQuery or "
27 "loadSolvFile interface, please update it to enhanced "
28 "version which can be found in download.tizen.org/tools")
29
30from mic import msger
31from mic.kickstart import ksparser
32from mic.utils import misc, rpmmisc, runner, fs_related
33from mic.utils.grabber import myurlgrab, TextProgress
34from mic.utils.proxy import get_proxy_for
35from mic.utils.errors import CreatorError, RepoError, RpmError
36from mic.imager.baseimager import BaseImageCreator
37
38class RepositoryStub:
39 def __init__(self):
40 self.name = None
41 self.baseurl = []
42 self.mirrorlist = None
43 self.proxy = None
44 self.proxy_username = None
45 self.proxy_password = None
46 self.nocache = False
47
48 self.enabled = True
49 self.autorefresh = True
50 self.keeppackages = True
51 self.priority = None
52
53from mic.pluginbase import BackendPlugin
54class Zypp(BackendPlugin):
55 name = 'zypp'
56
57 def __init__(self, target_arch, instroot, cachedir):
58 self.cachedir = cachedir
59 self.instroot = instroot
60 self.target_arch = target_arch
61
62 self.__pkgs_license = {}
63 self.__pkgs_content = {}
64 self.__pkgs_vcsinfo = {}
65 self.repos = []
66 self.to_deselect = []
67 self.localpkgs = {}
68 self.repo_manager = None
69 self.repo_manager_options = None
70 self.Z = None
71 self.ts = None
72 self.ts_pre = None
73 self.incpkgs = {}
74 self.excpkgs = {}
75 self.pre_pkgs = []
76 self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE,
77 rpm.RPMPROB_FILTER_REPLACEPKG ]
78
79 self.has_prov_query = True
80 self.install_debuginfo = False
81
82 def doFileLogSetup(self, uid, logfile):
83 # don't do the file log for the livecd as it can lead to open fds
84 # being left and an inability to clean up after ourself
85 pass
86
87 def closeRpmDB(self):
88 pass
89
90 def close(self):
91 if self.ts:
92 self.ts.closeDB()
93 self.ts = None
94
95 if self.ts_pre:
96 self.ts_pre.closeDB()
97 self.ts = None
98
99 self.closeRpmDB()
100
101 if not os.path.exists("/etc/fedora-release") and \
102 not os.path.exists("/etc/meego-release"):
103 for i in range(3, os.sysconf("SC_OPEN_MAX")):
104 try:
105 os.close(i)
106 except:
107 pass
108
109 def __del__(self):
110 self.close()
111
112 def _cleanupRpmdbLocks(self, installroot):
113 # cleans up temporary files left by bdb so that differing
114 # versions of rpm don't cause problems
115 import glob
116 for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
117 os.unlink(f)
118
119 def _cleanupZyppJunk(self, installroot):
120 try:
121 shutil.rmtree(os.path.join(installroot, '.zypp'))
122 except:
123 pass
124
125 def setup(self):
126 self._cleanupRpmdbLocks(self.instroot)
127
128 def whatObsolete(self, pkg):
129 query = zypp.PoolQuery()
130 query.addKind(zypp.ResKind.package)
131 query.addAttribute(zypp.SolvAttr.obsoletes, pkg)
132 query.setMatchExact()
133 for pi in query.queryResults(self.Z.pool()):
134 return pi
135 return None
136
137 def _zyppQueryPackage(self, pkg):
138 query = zypp.PoolQuery()
139 query.addKind(zypp.ResKind.package)
140 query.addAttribute(zypp.SolvAttr.name,pkg)
141 query.setMatchExact()
142 for pi in query.queryResults(self.Z.pool()):
143 return pi
144 return None
145
146 def _splitPkgString(self, pkg):
147 sp = pkg.rsplit(".",1)
148 name = sp[0]
149 arch = None
150 if len(sp) == 2:
151 arch = sp[1]
152 sysarch = zypp.Arch(self.target_arch)
153 if not zypp.Arch(arch).compatible_with (sysarch):
154 arch = None
155 name = ".".join(sp)
156 return name, arch
157
158 def selectPackage(self, pkg):
159 """Select a given package or package pattern, can be specified
160 with name.arch or name* or *name
161 """
162
163 if not self.Z:
164 self.__initialize_zypp()
165
166 def markPoolItem(obs, pi):
167 if obs == None:
168 pi.status().setToBeInstalled (zypp.ResStatus.USER)
169 else:
170 obs.status().setToBeInstalled (zypp.ResStatus.USER)
171
172 def cmpEVR(p1, p2):
173 # compare criterion: arch compatibility first, then repo
174 # priority, and version last
175 a1 = p1.arch()
176 a2 = p2.arch()
177 if str(a1) != str(a2):
178 if a1.compatible_with(a2):
179 return -1
180 else:
181 return 1
182 # Priority of a repository is an integer value between 0 (the
183 # highest priority) and 99 (the lowest priority)
184 pr1 = int(p1.repoInfo().priority())
185 pr2 = int(p2.repoInfo().priority())
186 if pr1 > pr2:
187 return -1
188 elif pr1 < pr2:
189 return 1
190
191 ed1 = p1.edition()
192 ed2 = p2.edition()
193 (e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
194 (e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
195 return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
196
197 found = False
198 startx = pkg.startswith("*")
199 endx = pkg.endswith("*")
200 ispattern = startx or endx
201 name, arch = self._splitPkgString(pkg)
202
203 q = zypp.PoolQuery()
204 q.addKind(zypp.ResKind.package)
205
206 if ispattern:
207 if startx and not endx:
208 pattern = '%s$' % (pkg[1:])
209 if endx and not startx:
210 pattern = '^%s' % (pkg[0:-1])
211 if endx and startx:
212 pattern = '%s' % (pkg[1:-1])
213 q.setMatchRegex()
214 q.addAttribute(zypp.SolvAttr.name,pattern)
215
216 elif arch:
217 q.setMatchExact()
218 q.addAttribute(zypp.SolvAttr.name,name)
219
220 else:
221 q.setMatchExact()
222 q.addAttribute(zypp.SolvAttr.name,pkg)
223
224 for pitem in sorted(
225 q.queryResults(self.Z.pool()),
226 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
227 reverse=True):
228 item = zypp.asKindPackage(pitem)
229 if item.name() in self.excpkgs.keys() and \
230 self.excpkgs[item.name()] == item.repoInfo().name():
231 continue
232 if item.name() in self.incpkgs.keys() and \
233 self.incpkgs[item.name()] != item.repoInfo().name():
234 continue
235
236 found = True
237 obspkg = self.whatObsolete(item.name())
238 if arch:
239 if arch == str(item.arch()):
240 item.status().setToBeInstalled (zypp.ResStatus.USER)
241 else:
242 markPoolItem(obspkg, pitem)
243 if not ispattern:
244 break
245
246 # Can't match using package name, then search from packge
247 # provides infomation
248 if found == False and not ispattern:
249 q.addAttribute(zypp.SolvAttr.provides, pkg)
250 q.addAttribute(zypp.SolvAttr.name,'')
251
252 for pitem in sorted(
253 q.queryResults(self.Z.pool()),
254 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
255 reverse=True):
256 item = zypp.asKindPackage(pitem)
257 if item.name() in self.excpkgs.keys() and \
258 self.excpkgs[item.name()] == item.repoInfo().name():
259 continue
260 if item.name() in self.incpkgs.keys() and \
261 self.incpkgs[item.name()] != item.repoInfo().name():
262 continue
263
264 found = True
265 obspkg = self.whatObsolete(item.name())
266 markPoolItem(obspkg, pitem)
267 break
268
269 if found:
270 return None
271 else:
272 raise CreatorError("Unable to find package: %s" % (pkg,))
273
274 def inDeselectPackages(self, pitem):
275 """check if specified pacakges are in the list of inDeselectPackages
276 """
277 item = zypp.asKindPackage(pitem)
278 name = item.name()
279 for pkg in self.to_deselect:
280 startx = pkg.startswith("*")
281 endx = pkg.endswith("*")
282 ispattern = startx or endx
283 pkgname, pkgarch = self._splitPkgString(pkg)
284 if not ispattern:
285 if pkgarch:
286 if name == pkgname and str(item.arch()) == pkgarch:
287 return True;
288 else:
289 if name == pkgname:
290 return True;
291 else:
292 if startx and name.endswith(pkg[1:]):
293 return True;
294 if endx and name.startswith(pkg[:-1]):
295 return True;
296
297 return False;
298
299 def deselectPackage(self, pkg):
300 """collect packages should not be installed"""
301 self.to_deselect.append(pkg)
302
303 def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
304 if not self.Z:
305 self.__initialize_zypp()
306 found = False
307 q=zypp.PoolQuery()
308 q.addKind(zypp.ResKind.pattern)
309 for pitem in q.queryResults(self.Z.pool()):
310 item = zypp.asKindPattern(pitem)
311 summary = "%s" % item.summary()
312 name = "%s" % item.name()
313 if name == grp or summary == grp:
314 found = True
315 pitem.status().setToBeInstalled (zypp.ResStatus.USER)
316 break
317
318 if found:
319 if include == ksparser.GROUP_REQUIRED:
320 map(
321 lambda p: self.deselectPackage(p),
322 grp.default_packages.keys())
323
324 return None
325 else:
326 raise CreatorError("Unable to find pattern: %s" % (grp,))
327
328 def addRepository(self, name,
329 url = None,
330 mirrorlist = None,
331 proxy = None,
332 proxy_username = None,
333 proxy_password = None,
334 inc = None,
335 exc = None,
336 ssl_verify = True,
337 nocache = False,
338 cost=None,
339 priority=None):
340 # TODO: Handle cost attribute for repos
341
342 if not self.repo_manager:
343 self.__initialize_repo_manager()
344
345 if not proxy and url:
346 proxy = get_proxy_for(url)
347
348 repo = RepositoryStub()
349 repo.name = name
350 repo.id = name
351 repo.proxy = proxy
352 repo.proxy_username = proxy_username
353 repo.proxy_password = proxy_password
354 repo.ssl_verify = ssl_verify
355 repo.nocache = nocache
356 repo.baseurl.append(url)
357 if inc:
358 for pkg in inc:
359 self.incpkgs[pkg] = name
360 if exc:
361 for pkg in exc:
362 self.excpkgs[pkg] = name
363
364 # check LICENSE files
365 if not rpmmisc.checkRepositoryEULA(name, repo):
366 msger.warning('skip repo:%s for failed EULA confirmation' % name)
367 return None
368
369 if mirrorlist:
370 repo.mirrorlist = mirrorlist
371
372 # Enable gpg check for verifying corrupt packages
373 repo.gpgcheck = 1
374 if priority is not None:
375 # priority 0 has issue in RepoInfo.setPriority
376 repo.priority = priority + 1
377
378 try:
379 repo_info = zypp.RepoInfo()
380 repo_info.setAlias(repo.name)
381 repo_info.setName(repo.name)
382 repo_info.setEnabled(repo.enabled)
383 repo_info.setAutorefresh(repo.autorefresh)
384 repo_info.setKeepPackages(repo.keeppackages)
385 baseurl = zypp.Url(repo.baseurl[0])
386 if not ssl_verify:
387 baseurl.setQueryParam("ssl_verify", "no")
388 if proxy:
389 scheme, host, path, parm, query, frag = urlparse.urlparse(proxy)
390
391 proxyinfo = host.split(":")
392 host = proxyinfo[0]
393
394 port = "80"
395 if len(proxyinfo) > 1:
396 port = proxyinfo[1]
397
398 if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2:
399 host = proxy.rsplit(':', 1)[0]
400 port = proxy.rsplit(':', 1)[1]
401
402 baseurl.setQueryParam ("proxy", host)
403 baseurl.setQueryParam ("proxyport", port)
404
405 repo.baseurl[0] = baseurl.asCompleteString()
406 self.repos.append(repo)
407
408 repo_info.addBaseUrl(baseurl)
409
410 if repo.priority is not None:
411 repo_info.setPriority(repo.priority)
412
413 # this hack is used to change zypp credential file location
414 # the default one is $HOME/.zypp, which cause conflicts when
415 # installing some basic packages, and the location doesn't
416 # have any interface actually, so use a tricky way anyway
417 homedir = None
418 if 'HOME' in os.environ:
419 homedir = os.environ['HOME']
420 os.environ['HOME'] = '/'
421 else:
422 os.environ['HOME'] = '/'
423
424 self.repo_manager.addRepository(repo_info)
425
426 # save back the $HOME env
427 if homedir:
428 os.environ['HOME'] = homedir
429 else:
430 del os.environ['HOME']
431
432 self.__build_repo_cache(name)
433
434 except RuntimeError, e:
435 raise CreatorError(str(e))
436
437 msger.verbose('repo: %s was added' % name)
438 return repo
439
440 def installHasFile(self, file):
441 return False
442
443 def preInstall(self, pkg):
444 self.pre_pkgs.append(pkg)
445
446 def runInstall(self, checksize = 0):
447 os.environ["HOME"] = "/"
448 os.environ["LD_PRELOAD"] = ""
449 self.buildTransaction()
450
451 todo = zypp.GetResolvablesToInsDel(self.Z.pool())
452 installed_pkgs = todo._toInstall
453 dlpkgs = []
454 for pitem in installed_pkgs:
455 if not zypp.isKindPattern(pitem) and \
456 not self.inDeselectPackages(pitem):
457 item = zypp.asKindPackage(pitem)
458 dlpkgs.append(item)
459
460 if not self.install_debuginfo or str(item.arch()) == "noarch":
461 continue
462
463 dipkg = self._zyppQueryPackage("%s-debuginfo" % item.name())
464 if dipkg:
465 ditem = zypp.asKindPackage(dipkg)
466 dlpkgs.append(ditem)
467 else:
468 msger.warning("No debuginfo rpm found for: %s" \
469 % item.name())
470
471 # record all pkg and the content
472 localpkgs = self.localpkgs.keys()
473 for pkg in dlpkgs:
474 license = ''
475 if pkg.name() in localpkgs:
476 hdr = rpmmisc.readRpmHeader(self.ts, self.localpkgs[pkg.name()])
477 pkg_long_name = misc.RPM_FMT % {
478 'name': hdr['name'],
479 'arch': hdr['arch'],
480 'version': hdr['version'],
481 'release': hdr['release']
482 }
483 license = hdr['license']
484
485 else:
486 pkg_long_name = misc.RPM_FMT % {
487 'name': pkg.name(),
488 'arch': pkg.arch(),
489 'version': pkg.edition().version(),
490 'release': pkg.edition().release()
491 }
492
493 license = pkg.license()
494
495 if license in self.__pkgs_license.keys():
496 self.__pkgs_license[license].append(pkg_long_name)
497 else:
498 self.__pkgs_license[license] = [pkg_long_name]
499
500 total_count = len(dlpkgs)
501 cached_count = 0
502 download_total_size = sum(map(lambda x: int(x.downloadSize()), dlpkgs))
503 localpkgs = self.localpkgs.keys()
504
505 msger.info("Checking packages cached ...")
506 for po in dlpkgs:
507 # Check if it is cached locally
508 if po.name() in localpkgs:
509 cached_count += 1
510 else:
511 local = self.getLocalPkgPath(po)
512 name = str(po.repoInfo().name())
513 try:
514 repo = filter(lambda r: r.name == name, self.repos)[0]
515 except IndexError:
516 repo = None
517 nocache = repo.nocache if repo else False
518
519 if os.path.exists(local):
520 if nocache or self.checkPkg(local) !=0:
521 os.unlink(local)
522 else:
523 download_total_size -= int(po.downloadSize())
524 cached_count += 1
525 cache_avail_size = misc.get_filesystem_avail(self.cachedir)
526 if cache_avail_size < download_total_size:
527 raise CreatorError("No enough space used for downloading.")
528
529 # record the total size of installed pkgs
530 install_total_size = sum(map(lambda x: int(x.installSize()), dlpkgs))
531 # check needed size before actually download and install
532
533 # FIXME: for multiple partitions for loop type, check fails
534 # skip the check temporarily
535 #if checksize and install_total_size > checksize:
536 # raise CreatorError("No enough space used for installing, "
537 # "please resize partition size in ks file")
538
539 download_count = total_count - cached_count
540 msger.info("Packages: %d Total, %d Cached, %d Missed" \
541 % (total_count, cached_count, download_count))
542
543 try:
544 if download_count > 0:
545 msger.info("Downloading packages ...")
546 self.downloadPkgs(dlpkgs, download_count)
547
548 self.installPkgs(dlpkgs)
549
550 except (RepoError, RpmError):
551 raise
552 except Exception, e:
553 raise CreatorError("Package installation failed: %s" % (e,))
554
555 def getVcsInfo(self):
556 if self.__pkgs_vcsinfo:
557 return
558
559 if not self.ts:
560 self.__initialize_transaction()
561
562 mi = self.ts.dbMatch()
563 for hdr in mi:
564 lname = misc.RPM_FMT % {
565 'name': hdr['name'],
566 'arch': hdr['arch'],
567 'version': hdr['version'],
568 'release': hdr['release']
569 }
570 self.__pkgs_vcsinfo[lname] = hdr['VCS']
571
572 return self.__pkgs_vcsinfo
573
574 def getAllContent(self):
575 if self.__pkgs_content:
576 return self.__pkgs_content
577
578 if not self.ts:
579 self.__initialize_transaction()
580
581 mi = self.ts.dbMatch()
582 for hdr in mi:
583 lname = misc.RPM_FMT % {
584 'name': hdr['name'],
585 'arch': hdr['arch'],
586 'version': hdr['version'],
587 'release': hdr['release']
588 }
589 self.__pkgs_content[lname] = hdr['FILENAMES']
590
591 return self.__pkgs_content
592
593 def getPkgsLicense(self):
594 return self.__pkgs_license
595
596 def getFilelist(self, pkgname):
597 if not pkgname:
598 return None
599
600 if not self.ts:
601 self.__initialize_transaction()
602
603 mi = self.ts.dbMatch('name', pkgname)
604 for header in mi:
605 return header['FILENAMES']
606
607 def __initialize_repo_manager(self):
608 if self.repo_manager:
609 return
610
611 # Clean up repo metadata
612 shutil.rmtree(self.cachedir + "/etc", ignore_errors = True)
613 shutil.rmtree(self.cachedir + "/solv", ignore_errors = True)
614 shutil.rmtree(self.cachedir + "/raw", ignore_errors = True)
615
616 zypp.KeyRing.setDefaultAccept( zypp.KeyRing.ACCEPT_UNSIGNED_FILE
617 | zypp.KeyRing.ACCEPT_VERIFICATION_FAILED
618 | zypp.KeyRing.ACCEPT_UNKNOWNKEY
619 | zypp.KeyRing.TRUST_KEY_TEMPORARILY
620 )
621
622 self.repo_manager_options = \
623 zypp.RepoManagerOptions(zypp.Pathname(self.instroot))
624
625 self.repo_manager_options.knownReposPath = \
626 zypp.Pathname(self.cachedir + "/etc/zypp/repos.d")
627
628 self.repo_manager_options.repoCachePath = \
629 zypp.Pathname(self.cachedir)
630
631 self.repo_manager_options.repoRawCachePath = \
632 zypp.Pathname(self.cachedir + "/raw")
633
634 self.repo_manager_options.repoSolvCachePath = \
635 zypp.Pathname(self.cachedir + "/solv")
636
637 self.repo_manager_options.repoPackagesCachePath = \
638 zypp.Pathname(self.cachedir + "/packages")
639
640 self.repo_manager = zypp.RepoManager(self.repo_manager_options)
641
642 def __build_repo_cache(self, name):
643 repo = self.repo_manager.getRepositoryInfo(name)
644 if self.repo_manager.isCached(repo) or not repo.enabled():
645 return
646
647 msger.info('Refreshing repository: %s ...' % name)
648 self.repo_manager.buildCache(repo, zypp.RepoManager.BuildIfNeeded)
649
650 def __initialize_zypp(self):
651 if self.Z:
652 return
653
654 zconfig = zypp.ZConfig_instance()
655
656 # Set system architecture
657 if self.target_arch:
658 zconfig.setSystemArchitecture(zypp.Arch(self.target_arch))
659
660 msger.info("zypp architecture is <%s>" % zconfig.systemArchitecture())
661
662 # repoPackagesCachePath is corrected by this
663 self.repo_manager = zypp.RepoManager(self.repo_manager_options)
664 repos = self.repo_manager.knownRepositories()
665 for repo in repos:
666 if not repo.enabled():
667 continue
668 self.repo_manager.loadFromCache(repo)
669
670 self.Z = zypp.ZYppFactory_instance().getZYpp()
671 self.Z.initializeTarget(zypp.Pathname(self.instroot))
672 self.Z.target().load()
673
674 def buildTransaction(self):
675 if not self.Z.resolver().resolvePool():
676 probs = self.Z.resolver().problems()
677
678 for problem in probs:
679 msger.warning("repo problem: %s, %s" \
680 % (problem.description().decode("utf-8"),
681 problem.details().decode("utf-8")))
682
683 raise RepoError("found %d resolver problem, abort!" \
684 % len(probs))
685
686 def getLocalPkgPath(self, po):
687 repoinfo = po.repoInfo()
688 cacheroot = repoinfo.packagesPath()
689 location= po.location()
690 rpmpath = str(location.filename())
691 pkgpath = "%s/%s" % (cacheroot, os.path.basename(rpmpath))
692 return pkgpath
693
694 def installLocal(self, pkg, po=None, updateonly=False):
695 if not self.ts:
696 self.__initialize_transaction()
697
698 solvfile = "%s/.solv" % (self.cachedir)
699
700 rc, out = runner.runtool([fs_related.find_binary_path("rpms2solv"),
701 pkg])
702 if rc == 0:
703 f = open(solvfile, "w+")
704 f.write(out)
705 f.close()
706
707 warnmsg = self.repo_manager.loadSolvFile(solvfile,
708 os.path.basename(pkg))
709 if warnmsg:
710 msger.warning(warnmsg)
711
712 os.unlink(solvfile)
713 else:
714 msger.warning('Can not get %s solv data.' % pkg)
715
716 hdr = rpmmisc.readRpmHeader(self.ts, pkg)
717 arch = zypp.Arch(hdr['arch'])
718 sysarch = zypp.Arch(self.target_arch)
719
720 if arch.compatible_with (sysarch):
721 pkgname = hdr['name']
722 self.localpkgs[pkgname] = pkg
723 self.selectPackage(pkgname)
724 msger.info("Marking %s to be installed" % (pkg))
725
726 else:
727 msger.warning("Cannot add package %s to transaction. "
728 "Not a compatible architecture: %s" \
729 % (pkg, hdr['arch']))
730
731 def downloadPkgs(self, package_objects, count):
732 localpkgs = self.localpkgs.keys()
733 progress_obj = TextProgress(count)
734
735 for po in package_objects:
736 if po.name() in localpkgs:
737 continue
738
739 filename = self.getLocalPkgPath(po)
740 if os.path.exists(filename):
741 if self.checkPkg(filename) == 0:
742 continue
743
744 dirn = os.path.dirname(filename)
745 if not os.path.exists(dirn):
746 os.makedirs(dirn)
747
748 url = self.get_url(po)
749 proxies = self.get_proxies(po)
750
751 try:
752 filename = myurlgrab(url, filename, proxies, progress_obj)
753 except CreatorError:
754 self.close()
755 raise
756
757 def preinstallPkgs(self):
758 if not self.ts_pre:
759 self.__initialize_transaction()
760
761 self.ts_pre.order()
762 cb = rpmmisc.RPMInstallCallback(self.ts_pre)
763 cb.headmsg = "Preinstall"
764 installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
765
766 # start to catch stderr output from librpm
767 msger.enable_logstderr(installlogfile)
768
769 errors = self.ts_pre.run(cb.callback, '')
770 # stop catch
771 msger.disable_logstderr()
772 self.ts_pre.closeDB()
773 self.ts_pre = None
774
775 if errors is not None:
776 if len(errors) == 0:
777 msger.warning('scriptlet or other non-fatal errors occurred '
778 'during transaction.')
779
780 else:
781 for e in errors:
782 msger.warning(e[0])
783 raise RepoError('Could not run transaction.')
784
785 def installPkgs(self, package_objects):
786 if not self.ts:
787 self.__initialize_transaction()
788
789 # clean rpm lock
790 self._cleanupRpmdbLocks(self.instroot)
791 self._cleanupZyppJunk(self.instroot)
792 # Set filters
793 probfilter = 0
794 for flag in self.probFilterFlags:
795 probfilter |= flag
796 self.ts.setProbFilter(probfilter)
797 self.ts_pre.setProbFilter(probfilter)
798
799 localpkgs = self.localpkgs.keys()
800
801 for po in package_objects:
802 pkgname = po.name()
803 if pkgname in localpkgs:
804 rpmpath = self.localpkgs[pkgname]
805 else:
806 rpmpath = self.getLocalPkgPath(po)
807
808 if not os.path.exists(rpmpath):
809 # Maybe it is a local repo
810 rpmuri = self.get_url(po)
811 if rpmuri.startswith("file:/"):
812 rpmpath = rpmuri[5:]
813
814 if not os.path.exists(rpmpath):
815 raise RpmError("Error: %s doesn't exist" % rpmpath)
816
817 h = rpmmisc.readRpmHeader(self.ts, rpmpath)
818
819 if pkgname in self.pre_pkgs:
820 msger.verbose("pre-install package added: %s" % pkgname)
821 self.ts_pre.addInstall(h, rpmpath, 'u')
822
823 self.ts.addInstall(h, rpmpath, 'u')
824
825 unresolved_dependencies = self.ts.check()
826 if not unresolved_dependencies:
827 if self.pre_pkgs:
828 self.preinstallPkgs()
829
830 self.ts.order()
831 cb = rpmmisc.RPMInstallCallback(self.ts)
832 installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
833
834 # start to catch stderr output from librpm
835 msger.enable_logstderr(installlogfile)
836
837 errors = self.ts.run(cb.callback, '')
838 # stop catch
839 msger.disable_logstderr()
840 self.ts.closeDB()
841 self.ts = None
842
843 if errors is not None:
844 if len(errors) == 0:
845 msger.warning('scriptlet or other non-fatal errors occurred '
846 'during transaction.')
847
848 else:
849 for e in errors:
850 msger.warning(e[0])
851 raise RepoError('Could not run transaction.')
852
853 else:
854 for pkg, need, needflags, sense, key in unresolved_dependencies:
855 package = '-'.join(pkg)
856
857 if needflags == rpm.RPMSENSE_LESS:
858 deppkg = ' < '.join(need)
859 elif needflags == rpm.RPMSENSE_EQUAL:
860 deppkg = ' = '.join(need)
861 elif needflags == rpm.RPMSENSE_GREATER:
862 deppkg = ' > '.join(need)
863 else:
864 deppkg = '-'.join(need)
865
866 if sense == rpm.RPMDEP_SENSE_REQUIRES:
867 msger.warning("[%s] Requires [%s], which is not provided" \
868 % (package, deppkg))
869
870 elif sense == rpm.RPMDEP_SENSE_CONFLICTS:
871 msger.warning("[%s] Conflicts with [%s]" %(package,deppkg))
872
873 raise RepoError("Unresolved dependencies, transaction failed.")
874
875 def __initialize_transaction(self):
876 if not self.ts:
877 self.ts = rpm.TransactionSet(self.instroot)
878 # Set to not verify DSA signatures.
879 self.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
880
881 if not self.ts_pre:
882 self.ts_pre = rpm.TransactionSet(self.instroot)
883 # Just unpack the files, don't run scripts
884 self.ts_pre.setFlags(rpm.RPMTRANS_FLAG_ALLFILES | rpm.RPMTRANS_FLAG_NOSCRIPTS)
885 # Set to not verify DSA signatures.
886 self.ts_pre.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
887
888 def checkPkg(self, pkg):
889 ret = 1
890 if not os.path.exists(pkg):
891 return ret
892 ret = rpmmisc.checkRpmIntegrity('rpm', pkg)
893 if ret != 0:
894 msger.warning("package %s is damaged: %s" \
895 % (os.path.basename(pkg), pkg))
896
897 return ret
898
899 def _add_prob_flags(self, *flags):
900 for flag in flags:
901 if flag not in self.probFilterFlags:
902 self.probFilterFlags.append(flag)
903
904 def get_proxies(self, pobj):
905 if not pobj:
906 return None
907
908 proxy = None
909 proxies = None
910 repoinfo = pobj.repoInfo()
911 reponame = "%s" % repoinfo.name()
912 repos = filter(lambda r: r.name == reponame, self.repos)
913 repourl = str(repoinfo.baseUrls()[0])
914
915 if repos:
916 proxy = repos[0].proxy
917 if not proxy:
918 proxy = get_proxy_for(repourl)
919 if proxy:
920 proxies = {str(repourl.split(':')[0]): str(proxy)}
921
922 return proxies
923
924 def get_url(self, pobj):
925 if not pobj:
926 return None
927
928 name = str(pobj.repoInfo().name())
929 try:
930 repo = filter(lambda r: r.name == name, self.repos)[0]
931 except IndexError:
932 return None
933
934 baseurl = repo.baseurl[0]
935
936 index = baseurl.find("?")
937 if index > -1:
938 baseurl = baseurl[:index]
939
940 location = pobj.location()
941 location = str(location.filename())
942 if location.startswith("./"):
943 location = location[2:]
944
945 return os.path.join(baseurl, location)
946
947 def package_url(self, pkgname):
948
949 def cmpEVR(p1, p2):
950 ed1 = p1.edition()
951 ed2 = p2.edition()
952 (e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
953 (e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
954 return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
955
956 if not self.Z:
957 self.__initialize_zypp()
958
959 q = zypp.PoolQuery()
960 q.addKind(zypp.ResKind.package)
961 q.setMatchExact()
962 q.addAttribute(zypp.SolvAttr.name, pkgname)
963 items = sorted(q.queryResults(self.Z.pool()),
964 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
965 reverse=True)
966
967 if items:
968 item = zypp.asKindPackage(items[0])
969 url = self.get_url(item)
970 proxies = self.get_proxies(item)
971 return (url, proxies)
972
973 return (None, None)
diff --git a/scripts/lib/mic/plugins/hook/.py b/scripts/lib/mic/plugins/hook/.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/mic/plugins/hook/.py
diff --git a/scripts/lib/mic/plugins/hook/empty_hook.py b/scripts/lib/mic/plugins/hook/empty_hook.py
new file mode 100644
index 0000000000..397585d8c1
--- /dev/null
+++ b/scripts/lib/mic/plugins/hook/empty_hook.py
@@ -0,0 +1,3 @@
1#!/usr/bin/python
2
3# TODO: plugin base for hooks
diff --git a/scripts/lib/mic/plugins/imager/direct_plugin.py b/scripts/lib/mic/plugins/imager/direct_plugin.py
new file mode 100644
index 0000000000..fc7c10c3df
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/direct_plugin.py
@@ -0,0 +1,107 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'direct' imager plugin class for 'wic', based
22# loosely on the raw imager plugin from 'mic'
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] linux.intel.com>
26#
27
28import os
29import shutil
30import re
31import tempfile
32
33from mic import chroot, msger
34from mic.utils import misc, fs_related, errors, runner, cmdln
35from mic.conf import configmgr
36from mic.plugin import pluginmgr
37from mic.utils.partitionedfs import PartitionedMount
38
39import mic.imager.direct as direct
40from mic.pluginbase import ImagerPlugin
41
42class DirectPlugin(ImagerPlugin):
43 name = 'direct'
44
45 @classmethod
46 def __rootfs_dir_to_dict(self, rootfs_dirs):
47 """
48 Gets a string that contain 'connection=dir' splitted by
49 space and return a dict
50 """
51 krootfs_dir = {}
52 for rootfs_dir in rootfs_dirs.split(' '):
53 k, v = rootfs_dir.split('=')
54 krootfs_dir[k] = v
55
56 return krootfs_dir
57
58 @classmethod
59 def do_create(self, subcmd, opts, *args):
60 """
61 Create direct image, called from creator as 'direct' cmd
62 """
63 if len(args) != 9:
64 raise errors.Usage("Extra arguments given")
65
66 staging_data_dir = args[0]
67 hdddir = args[1]
68 native_sysroot = args[2]
69 kernel_dir = args[3]
70 bootimg_dir = args[4]
71 rootfs_dir = args[5]
72
73 creatoropts = configmgr.create
74 ksconf = args[6]
75
76 image_output_dir = args[7]
77 oe_builddir = args[8]
78
79 krootfs_dir = self.__rootfs_dir_to_dict(rootfs_dir)
80
81 configmgr._ksconf = ksconf
82
83 creator = direct.DirectImageCreator(oe_builddir,
84 image_output_dir,
85 krootfs_dir,
86 bootimg_dir,
87 kernel_dir,
88 native_sysroot,
89 hdddir,
90 staging_data_dir,
91 creatoropts,
92 None,
93 None,
94 None)
95
96 try:
97 creator.mount(None, creatoropts["cachedir"])
98 creator.install()
99 creator.configure(creatoropts["repomd"])
100 creator.print_outimage_info()
101
102 except errors.CreatorError:
103 raise
104 finally:
105 creator.cleanup()
106
107 return 0
diff --git a/scripts/lib/mic/plugins/imager/fs_plugin.py b/scripts/lib/mic/plugins/imager/fs_plugin.py
new file mode 100644
index 0000000000..6bcaf00729
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/fs_plugin.py
@@ -0,0 +1,143 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import sys
20
21from mic import chroot, msger
22from mic.utils import cmdln, misc, errors, fs_related
23from mic.imager import fs
24from mic.conf import configmgr
25from mic.plugin import pluginmgr
26
27from mic.pluginbase import ImagerPlugin
28class FsPlugin(ImagerPlugin):
29 name = 'fs'
30
31 @classmethod
32 @cmdln.option("--include-src",
33 dest="include_src",
34 action="store_true",
35 default=False,
36 help="Generate a image with source rpms included")
37 def do_create(self, subcmd, opts, *args):
38 """${cmd_name}: create fs image
39
40 Usage:
41 ${name} ${cmd_name} <ksfile> [OPTS]
42
43 ${cmd_option_list}
44 """
45
46 if len(args) != 1:
47 raise errors.Usage("Extra arguments given")
48
49 creatoropts = configmgr.create
50 ksconf = args[0]
51
52 if creatoropts['runtime'] == 'bootstrap':
53 configmgr._ksconf = ksconf
54 rt_util.bootstrap_mic()
55
56 recording_pkgs = []
57 if len(creatoropts['record_pkgs']) > 0:
58 recording_pkgs = creatoropts['record_pkgs']
59
60 if creatoropts['release'] is not None:
61 if 'name' not in recording_pkgs:
62 recording_pkgs.append('name')
63 if 'vcs' not in recording_pkgs:
64 recording_pkgs.append('vcs')
65
66 configmgr._ksconf = ksconf
67
68 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
69 if creatoropts['release'] is not None:
70 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
71
72 # try to find the pkgmgr
73 pkgmgr = None
74 backends = pluginmgr.get_plugins('backend')
75 if 'auto' == creatoropts['pkgmgr']:
76 for key in configmgr.prefer_backends:
77 if key in backends:
78 pkgmgr = backends[key]
79 break
80 else:
81 for key in backends.keys():
82 if key == creatoropts['pkgmgr']:
83 pkgmgr = backends[key]
84 break
85
86 if not pkgmgr:
87 raise errors.CreatorError("Can't find backend: %s, "
88 "available choices: %s" %
89 (creatoropts['pkgmgr'],
90 ','.join(backends.keys())))
91
92 creator = fs.FsImageCreator(creatoropts, pkgmgr)
93 creator._include_src = opts.include_src
94
95 if len(recording_pkgs) > 0:
96 creator._recording_pkgs = recording_pkgs
97
98 self.check_image_exists(creator.destdir,
99 creator.pack_to,
100 [creator.name],
101 creatoropts['release'])
102
103 try:
104 creator.check_depend_tools()
105 creator.mount(None, creatoropts["cachedir"])
106 creator.install()
107 #Download the source packages ###private options
108 if opts.include_src:
109 installed_pkgs = creator.get_installed_packages()
110 msger.info('--------------------------------------------------')
111 msger.info('Generating the image with source rpms included ...')
112 if not misc.SrcpkgsDownload(installed_pkgs, creatoropts["repomd"], creator._instroot, creatoropts["cachedir"]):
113 msger.warning("Source packages can't be downloaded")
114
115 creator.configure(creatoropts["repomd"])
116 creator.copy_kernel()
117 creator.unmount()
118 creator.package(creatoropts["outdir"])
119 if creatoropts['release'] is not None:
120 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
121 creator.print_outimage_info()
122 except errors.CreatorError:
123 raise
124 finally:
125 creator.cleanup()
126
127 msger.info("Finished.")
128 return 0
129
130 @classmethod
131 def do_chroot(self, target, cmd=[]):#chroot.py parse opts&args
132 try:
133 if len(cmd) != 0:
134 cmdline = ' '.join(cmd)
135 else:
136 cmdline = "/bin/bash"
137 envcmd = fs_related.find_binary_inchroot("env", target)
138 if envcmd:
139 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
140 chroot.chroot(target, None, cmdline)
141 finally:
142 chroot.cleanup_after_chroot("dir", None, None, None)
143 return 1
diff --git a/scripts/lib/mic/plugins/imager/livecd_plugin.py b/scripts/lib/mic/plugins/imager/livecd_plugin.py
new file mode 100644
index 0000000000..82cb1af7dc
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/livecd_plugin.py
@@ -0,0 +1,255 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors
24from mic.conf import configmgr
25import mic.imager.livecd as livecd
26from mic.plugin import pluginmgr
27
28from mic.pluginbase import ImagerPlugin
29class LiveCDPlugin(ImagerPlugin):
30 name = 'livecd'
31
32 @classmethod
33 def do_create(self, subcmd, opts, *args):
34 """${cmd_name}: create livecd image
35
36 Usage:
37 ${name} ${cmd_name} <ksfile> [OPTS]
38
39 ${cmd_option_list}
40 """
41
42 if len(args) != 1:
43 raise errors.Usage("Extra arguments given")
44
45 creatoropts = configmgr.create
46 ksconf = args[0]
47
48 if creatoropts['runtime'] == 'bootstrap':
49 configmgr._ksconf = ksconf
50 rt_util.bootstrap_mic()
51
52 if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
53 msger.warning('livecd cannot support arm images, Quit')
54 return
55
56 recording_pkgs = []
57 if len(creatoropts['record_pkgs']) > 0:
58 recording_pkgs = creatoropts['record_pkgs']
59
60 if creatoropts['release'] is not None:
61 if 'name' not in recording_pkgs:
62 recording_pkgs.append('name')
63 if 'vcs' not in recording_pkgs:
64 recording_pkgs.append('vcs')
65
66 configmgr._ksconf = ksconf
67
68 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
69 if creatoropts['release'] is not None:
70 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
71
72 # try to find the pkgmgr
73 pkgmgr = None
74 backends = pluginmgr.get_plugins('backend')
75 if 'auto' == creatoropts['pkgmgr']:
76 for key in configmgr.prefer_backends:
77 if key in backends:
78 pkgmgr = backends[key]
79 break
80 else:
81 for key in backends.keys():
82 if key == creatoropts['pkgmgr']:
83 pkgmgr = backends[key]
84 break
85
86 if not pkgmgr:
87 raise errors.CreatorError("Can't find backend: %s, "
88 "available choices: %s" %
89 (creatoropts['pkgmgr'],
90 ','.join(backends.keys())))
91
92 creator = livecd.LiveCDImageCreator(creatoropts, pkgmgr)
93
94 if len(recording_pkgs) > 0:
95 creator._recording_pkgs = recording_pkgs
96
97 self.check_image_exists(creator.destdir,
98 creator.pack_to,
99 [creator.name + ".iso"],
100 creatoropts['release'])
101
102 try:
103 creator.check_depend_tools()
104 creator.mount(None, creatoropts["cachedir"])
105 creator.install()
106 creator.configure(creatoropts["repomd"])
107 creator.copy_kernel()
108 creator.unmount()
109 creator.package(creatoropts["outdir"])
110 if creatoropts['release'] is not None:
111 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
112 creator.print_outimage_info()
113
114 except errors.CreatorError:
115 raise
116 finally:
117 creator.cleanup()
118
119 msger.info("Finished.")
120 return 0
121
122 @classmethod
123 def do_chroot(cls, target, cmd=[]):
124 os_image = cls.do_unpack(target)
125 os_image_dir = os.path.dirname(os_image)
126
127 # unpack image to target dir
128 imgsize = misc.get_file_size(os_image) * 1024L * 1024L
129 imgtype = misc.get_image_type(os_image)
130 if imgtype == "btrfsimg":
131 fstype = "btrfs"
132 myDiskMount = fs_related.BtrfsDiskMount
133 elif imgtype in ("ext3fsimg", "ext4fsimg"):
134 fstype = imgtype[:4]
135 myDiskMount = fs_related.ExtDiskMount
136 else:
137 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
138
139 extmnt = misc.mkdtemp()
140 extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
141 extmnt,
142 fstype,
143 4096,
144 "%s label" % fstype)
145 try:
146 extloop.mount()
147
148 except errors.MountError:
149 extloop.cleanup()
150 shutil.rmtree(extmnt, ignore_errors = True)
151 shutil.rmtree(os_image_dir, ignore_errors = True)
152 raise
153
154 try:
155 if len(cmd) != 0:
156 cmdline = ' '.join(cmd)
157 else:
158 cmdline = "/bin/bash"
159 envcmd = fs_related.find_binary_inchroot("env", extmnt)
160 if envcmd:
161 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
162 chroot.chroot(extmnt, None, cmdline)
163 except:
164 raise errors.CreatorError("Failed to chroot to %s." %target)
165 finally:
166 chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
167
168 @classmethod
169 def do_pack(cls, base_on):
170 import subprocess
171
172 def __mkinitrd(instance):
173 kernelver = instance._get_kernel_versions().values()[0][0]
174 args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
175 try:
176 subprocess.call(args, preexec_fn = instance._chroot)
177 except OSError, (err, msg):
178 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
179
180 def __run_post_cleanups(instance):
181 kernelver = instance._get_kernel_versions().values()[0][0]
182 args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
183
184 try:
185 subprocess.call(args, preexec_fn = instance._chroot)
186 except OSError, (err, msg):
187 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
188
189 convertoropts = configmgr.convert
190 convertoropts['name'] = os.path.splitext(os.path.basename(base_on))[0]
191 convertor = livecd.LiveCDImageCreator(convertoropts)
192 imgtype = misc.get_image_type(base_on)
193 if imgtype == "btrfsimg":
194 fstype = "btrfs"
195 elif imgtype in ("ext3fsimg", "ext4fsimg"):
196 fstype = imgtype[:4]
197 else:
198 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
199 convertor._set_fstype(fstype)
200 try:
201 convertor.mount(base_on)
202 __mkinitrd(convertor)
203 convertor._create_bootconfig()
204 __run_post_cleanups(convertor)
205 convertor.launch_shell(convertoropts['shell'])
206 convertor.unmount()
207 convertor.package()
208 convertor.print_outimage_info()
209 finally:
210 shutil.rmtree(os.path.dirname(base_on), ignore_errors = True)
211
212 @classmethod
213 def do_unpack(cls, srcimg):
214 img = srcimg
215 imgmnt = misc.mkdtemp()
216 imgloop = fs_related.DiskMount(fs_related.LoopbackDisk(img, 0), imgmnt)
217 try:
218 imgloop.mount()
219 except errors.MountError:
220 imgloop.cleanup()
221 raise
222
223 # legacy LiveOS filesystem layout support, remove for F9 or F10
224 if os.path.exists(imgmnt + "/squashfs.img"):
225 squashimg = imgmnt + "/squashfs.img"
226 else:
227 squashimg = imgmnt + "/LiveOS/squashfs.img"
228
229 tmpoutdir = misc.mkdtemp()
230 # unsquashfs requires outdir mustn't exist
231 shutil.rmtree(tmpoutdir, ignore_errors = True)
232 misc.uncompress_squashfs(squashimg, tmpoutdir)
233
234 try:
235 # legacy LiveOS filesystem layout support, remove for F9 or F10
236 if os.path.exists(tmpoutdir + "/os.img"):
237 os_image = tmpoutdir + "/os.img"
238 else:
239 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
240
241 if not os.path.exists(os_image):
242 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
243 "LiveOS/ext3fs.img nor os.img exist" %img)
244
245 imgname = os.path.basename(srcimg)
246 imgname = os.path.splitext(imgname)[0] + ".img"
247 rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), imgname)
248 shutil.copyfile(os_image, rtimage)
249
250 finally:
251 imgloop.cleanup()
252 shutil.rmtree(tmpoutdir, ignore_errors = True)
253 shutil.rmtree(imgmnt, ignore_errors = True)
254
255 return rtimage
diff --git a/scripts/lib/mic/plugins/imager/liveusb_plugin.py b/scripts/lib/mic/plugins/imager/liveusb_plugin.py
new file mode 100644
index 0000000000..3d53c84410
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/liveusb_plugin.py
@@ -0,0 +1,260 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors
24from mic.utils.partitionedfs import PartitionedMount
25from mic.conf import configmgr
26from mic.plugin import pluginmgr
27
28import mic.imager.liveusb as liveusb
29
30from mic.pluginbase import ImagerPlugin
31class LiveUSBPlugin(ImagerPlugin):
32 name = 'liveusb'
33
34 @classmethod
35 def do_create(self, subcmd, opts, *args):
36 """${cmd_name}: create liveusb image
37
38 Usage:
39 ${name} ${cmd_name} <ksfile> [OPTS]
40
41 ${cmd_option_list}
42 """
43
44 if len(args) != 1:
45 raise errors.Usage("Extra arguments given")
46
47 creatoropts = configmgr.create
48 ksconf = args[0]
49
50 if creatoropts['runtime'] == "bootstrap":
51 configmgr._ksconf = ksconf
52 rt_util.bootstrap_mic()
53
54 if creatoropts['arch'] and creatoropts['arch'].startswith('arm'):
55 msger.warning('liveusb cannot support arm images, Quit')
56 return
57
58 recording_pkgs = []
59 if len(creatoropts['record_pkgs']) > 0:
60 recording_pkgs = creatoropts['record_pkgs']
61
62 if creatoropts['release'] is not None:
63 if 'name' not in recording_pkgs:
64 recording_pkgs.append('name')
65 if 'vcs' not in recording_pkgs:
66 recording_pkgs.append('vcs')
67
68 configmgr._ksconf = ksconf
69
70 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
71 if creatoropts['release'] is not None:
72 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
73
74 # try to find the pkgmgr
75 pkgmgr = None
76 backends = pluginmgr.get_plugins('backend')
77 if 'auto' == creatoropts['pkgmgr']:
78 for key in configmgr.prefer_backends:
79 if key in backends:
80 pkgmgr = backends[key]
81 break
82 else:
83 for key in backends.keys():
84 if key == creatoropts['pkgmgr']:
85 pkgmgr = backends[key]
86 break
87
88 if not pkgmgr:
89 raise errors.CreatorError("Can't find backend: %s, "
90 "available choices: %s" %
91 (creatoropts['pkgmgr'],
92 ','.join(backends.keys())))
93
94 creator = liveusb.LiveUSBImageCreator(creatoropts, pkgmgr)
95
96 if len(recording_pkgs) > 0:
97 creator._recording_pkgs = recording_pkgs
98
99 self.check_image_exists(creator.destdir,
100 creator.pack_to,
101 [creator.name + ".usbimg"],
102 creatoropts['release'])
103 try:
104 creator.check_depend_tools()
105 creator.mount(None, creatoropts["cachedir"])
106 creator.install()
107 creator.configure(creatoropts["repomd"])
108 creator.copy_kernel()
109 creator.unmount()
110 creator.package(creatoropts["outdir"])
111 if creatoropts['release'] is not None:
112 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
113 creator.print_outimage_info()
114
115 except errors.CreatorError:
116 raise
117 finally:
118 creator.cleanup()
119
120 msger.info("Finished.")
121 return 0
122
123 @classmethod
124 def do_chroot(cls, target, cmd=[]):
125 os_image = cls.do_unpack(target)
126 os_image_dir = os.path.dirname(os_image)
127
128 # unpack image to target dir
129 imgsize = misc.get_file_size(os_image) * 1024L * 1024L
130 imgtype = misc.get_image_type(os_image)
131 if imgtype == "btrfsimg":
132 fstype = "btrfs"
133 myDiskMount = fs_related.BtrfsDiskMount
134 elif imgtype in ("ext3fsimg", "ext4fsimg"):
135 fstype = imgtype[:4]
136 myDiskMount = fs_related.ExtDiskMount
137 else:
138 raise errors.CreatorError("Unsupported filesystem type: %s" % fstype)
139
140 extmnt = misc.mkdtemp()
141 extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize),
142 extmnt,
143 fstype,
144 4096,
145 "%s label" % fstype)
146
147 try:
148 extloop.mount()
149
150 except errors.MountError:
151 extloop.cleanup()
152 shutil.rmtree(extmnt, ignore_errors = True)
153 raise
154
155 try:
156 if len(cmd) != 0:
157 cmdline = ' '.join(cmd)
158 else:
159 cmdline = "/bin/bash"
160 envcmd = fs_related.find_binary_inchroot("env", extmnt)
161 if envcmd:
162 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
163 chroot.chroot(extmnt, None, cmdline)
164 except:
165 raise errors.CreatorError("Failed to chroot to %s." %target)
166 finally:
167 chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
168
169 @classmethod
170 def do_pack(cls, base_on):
171 import subprocess
172
173 def __mkinitrd(instance):
174 kernelver = instance._get_kernel_versions().values()[0][0]
175 args = [ "/usr/libexec/mkliveinitrd", "/boot/initrd-%s.img" % kernelver, "%s" % kernelver ]
176 try:
177 subprocess.call(args, preexec_fn = instance._chroot)
178
179 except OSError, (err, msg):
180 raise errors.CreatorError("Failed to execute /usr/libexec/mkliveinitrd: %s" % msg)
181
182 def __run_post_cleanups(instance):
183 kernelver = instance._get_kernel_versions().values()[0][0]
184 args = ["rm", "-f", "/boot/initrd-%s.img" % kernelver]
185
186 try:
187 subprocess.call(args, preexec_fn = instance._chroot)
188 except OSError, (err, msg):
189 raise errors.CreatorError("Failed to run post cleanups: %s" % msg)
190
191 convertoropts = configmgr.convert
192 convertoropts['name'] = os.path.splitext(os.path.basename(base_on))[0]
193 convertor = liveusb.LiveUSBImageCreator(convertoropts)
194 imgtype = misc.get_image_type(base_on)
195 if imgtype == "btrfsimg":
196 fstype = "btrfs"
197 elif imgtype in ("ext3fsimg", "ext4fsimg"):
198 fstype = imgtype[:4]
199 else:
200 raise errors.CreatorError("Unsupported filesystem type: %s" % fstyp)
201 convertor._set_fstype(fstype)
202 try:
203 convertor.mount(base_on)
204 __mkinitrd(convertor)
205 convertor._create_bootconfig()
206 __run_post_cleanups(convertor)
207 convertor.launch_shell(convertoropts['shell'])
208 convertor.unmount()
209 convertor.package()
210 convertor.print_outimage_info()
211 finally:
212 shutil.rmtree(os.path.dirname(base_on), ignore_errors = True)
213
214 @classmethod
215 def do_unpack(cls, srcimg):
216 img = srcimg
217 imgsize = misc.get_file_size(img) * 1024L * 1024L
218 imgmnt = misc.mkdtemp()
219 disk = fs_related.SparseLoopbackDisk(img, imgsize)
220 imgloop = PartitionedMount(imgmnt, skipformat = True)
221 imgloop.add_disk('/dev/sdb', disk)
222 imgloop.add_partition(imgsize/1024/1024, "/dev/sdb", "/", "vfat", boot=False)
223 try:
224 imgloop.mount()
225 except errors.MountError:
226 imgloop.cleanup()
227 raise
228
229 # legacy LiveOS filesystem layout support, remove for F9 or F10
230 if os.path.exists(imgmnt + "/squashfs.img"):
231 squashimg = imgmnt + "/squashfs.img"
232 else:
233 squashimg = imgmnt + "/LiveOS/squashfs.img"
234
235 tmpoutdir = misc.mkdtemp()
236 # unsquashfs requires outdir mustn't exist
237 shutil.rmtree(tmpoutdir, ignore_errors = True)
238 misc.uncompress_squashfs(squashimg, tmpoutdir)
239
240 try:
241 # legacy LiveOS filesystem layout support, remove for F9 or F10
242 if os.path.exists(tmpoutdir + "/os.img"):
243 os_image = tmpoutdir + "/os.img"
244 else:
245 os_image = tmpoutdir + "/LiveOS/ext3fs.img"
246
247 if not os.path.exists(os_image):
248 raise errors.CreatorError("'%s' is not a valid live CD ISO : neither "
249 "LiveOS/ext3fs.img nor os.img exist" %img)
250 imgname = os.path.basename(srcimg)
251 imgname = os.path.splitext(imgname)[0] + ".img"
252 rtimage = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), imgname)
253 shutil.copyfile(os_image, rtimage)
254
255 finally:
256 imgloop.cleanup()
257 shutil.rmtree(tmpoutdir, ignore_errors = True)
258 shutil.rmtree(imgmnt, ignore_errors = True)
259
260 return rtimage
diff --git a/scripts/lib/mic/plugins/imager/loop_plugin.py b/scripts/lib/mic/plugins/imager/loop_plugin.py
new file mode 100644
index 0000000000..2a05b3c238
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/loop_plugin.py
@@ -0,0 +1,255 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import tempfile
21
22from mic import chroot, msger
23from mic.utils import misc, fs_related, errors, cmdln
24from mic.conf import configmgr
25from mic.plugin import pluginmgr
26from mic.imager.loop import LoopImageCreator, load_mountpoints
27
28from mic.pluginbase import ImagerPlugin
29class LoopPlugin(ImagerPlugin):
30 name = 'loop'
31
32 @classmethod
33 @cmdln.option("--compress-disk-image", dest="compress_image",
34 type='choice', choices=("gz", "bz2"), default=None,
35 help="Same with --compress-image")
36 # alias to compress-image for compatibility
37 @cmdln.option("--compress-image", dest="compress_image",
38 type='choice', choices=("gz", "bz2"), default=None,
39 help="Compress all loop images with 'gz' or 'bz2'")
40 @cmdln.option("--shrink", action='store_true', default=False,
41 help="Whether to shrink loop images to minimal size")
42 def do_create(self, subcmd, opts, *args):
43 """${cmd_name}: create loop image
44
45 Usage:
46 ${name} ${cmd_name} <ksfile> [OPTS]
47
48 ${cmd_option_list}
49 """
50
51 if len(args) != 1:
52 raise errors.Usage("Extra arguments given")
53
54 creatoropts = configmgr.create
55 ksconf = args[0]
56
57 if creatoropts['runtime'] == "bootstrap":
58 configmgr._ksconf = ksconf
59 rt_util.bootstrap_mic()
60
61 recording_pkgs = []
62 if len(creatoropts['record_pkgs']) > 0:
63 recording_pkgs = creatoropts['record_pkgs']
64
65 if creatoropts['release'] is not None:
66 if 'name' not in recording_pkgs:
67 recording_pkgs.append('name')
68 if 'vcs' not in recording_pkgs:
69 recording_pkgs.append('vcs')
70
71 configmgr._ksconf = ksconf
72
73 # Called After setting the configmgr._ksconf
74 # as the creatoropts['name'] is reset there.
75 if creatoropts['release'] is not None:
76 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'],
77 creatoropts['release'],
78 creatoropts['name'])
79 # try to find the pkgmgr
80 pkgmgr = None
81 backends = pluginmgr.get_plugins('backend')
82 if 'auto' == creatoropts['pkgmgr']:
83 for key in configmgr.prefer_backends:
84 if key in backends:
85 pkgmgr = backends[key]
86 break
87 else:
88 for key in backends.keys():
89 if key == creatoropts['pkgmgr']:
90 pkgmgr = backends[key]
91 break
92
93 if not pkgmgr:
94 raise errors.CreatorError("Can't find backend: %s, "
95 "available choices: %s" %
96 (creatoropts['pkgmgr'],
97 ','.join(backends.keys())))
98
99 creator = LoopImageCreator(creatoropts,
100 pkgmgr,
101 opts.compress_image,
102 opts.shrink)
103
104 if len(recording_pkgs) > 0:
105 creator._recording_pkgs = recording_pkgs
106
107 image_names = [creator.name + ".img"]
108 image_names.extend(creator.get_image_names())
109 self.check_image_exists(creator.destdir,
110 creator.pack_to,
111 image_names,
112 creatoropts['release'])
113
114 try:
115 creator.check_depend_tools()
116 creator.mount(None, creatoropts["cachedir"])
117 creator.install()
118 creator.configure(creatoropts["repomd"])
119 creator.copy_kernel()
120 creator.unmount()
121 creator.package(creatoropts["outdir"])
122
123 if creatoropts['release'] is not None:
124 creator.release_output(ksconf,
125 creatoropts['outdir'],
126 creatoropts['release'])
127 creator.print_outimage_info()
128
129 except errors.CreatorError:
130 raise
131 finally:
132 creator.cleanup()
133
134 msger.info("Finished.")
135 return 0
136
137 @classmethod
138 def _do_chroot_tar(cls, target, cmd=[]):
139 mountfp_xml = os.path.splitext(target)[0] + '.xml'
140 if not os.path.exists(mountfp_xml):
141 raise errors.CreatorError("No mount point file found for this tar "
142 "image, please check %s" % mountfp_xml)
143
144 import tarfile
145 tar = tarfile.open(target, 'r')
146 tmpdir = misc.mkdtemp()
147 tar.extractall(path=tmpdir)
148 tar.close()
149
150 mntdir = misc.mkdtemp()
151
152 loops = []
153 for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml):
154 if fstype in ("ext2", "ext3", "ext4"):
155 myDiskMount = fs_related.ExtDiskMount
156 elif fstype == "btrfs":
157 myDiskMount = fs_related.BtrfsDiskMount
158 elif fstype in ("vfat", "msdos"):
159 myDiskMount = fs_related.VfatDiskMount
160 else:
161 msger.error("Cannot support fstype: %s" % fstype)
162
163 name = os.path.join(tmpdir, name)
164 size = size * 1024L * 1024L
165 loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size),
166 os.path.join(mntdir, mp.lstrip('/')),
167 fstype, size, label)
168
169 try:
170 msger.verbose("Mount %s to %s" % (mp, mntdir + mp))
171 fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/')))
172 loop.mount()
173
174 except:
175 loop.cleanup()
176 for lp in reversed(loops):
177 chroot.cleanup_after_chroot("img", lp, None, mntdir)
178
179 shutil.rmtree(tmpdir, ignore_errors=True)
180 raise
181
182 loops.append(loop)
183
184 try:
185 if len(cmd) != 0:
186 cmdline = "/usr/bin/env HOME=/root " + ' '.join(cmd)
187 else:
188 cmdline = "/usr/bin/env HOME=/root /bin/bash"
189 chroot.chroot(mntdir, None, cmdline)
190 except:
191 raise errors.CreatorError("Failed to chroot to %s." % target)
192 finally:
193 for loop in reversed(loops):
194 chroot.cleanup_after_chroot("img", loop, None, mntdir)
195
196 shutil.rmtree(tmpdir, ignore_errors=True)
197
198 @classmethod
199 def do_chroot(cls, target, cmd=[]):
200 if target.endswith('.tar'):
201 import tarfile
202 if tarfile.is_tarfile(target):
203 LoopPlugin._do_chroot_tar(target, cmd)
204 return
205 else:
206 raise errors.CreatorError("damaged tarball for loop images")
207
208 img = target
209 imgsize = misc.get_file_size(img) * 1024L * 1024L
210 imgtype = misc.get_image_type(img)
211 if imgtype == "btrfsimg":
212 fstype = "btrfs"
213 myDiskMount = fs_related.BtrfsDiskMount
214 elif imgtype in ("ext3fsimg", "ext4fsimg"):
215 fstype = imgtype[:4]
216 myDiskMount = fs_related.ExtDiskMount
217 else:
218 raise errors.CreatorError("Unsupported filesystem type: %s" \
219 % imgtype)
220
221 extmnt = misc.mkdtemp()
222 extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize),
223 extmnt,
224 fstype,
225 4096,
226 "%s label" % fstype)
227 try:
228 extloop.mount()
229
230 except errors.MountError:
231 extloop.cleanup()
232 shutil.rmtree(extmnt, ignore_errors=True)
233 raise
234
235 try:
236 if len(cmd) != 0:
237 cmdline = ' '.join(cmd)
238 else:
239 cmdline = "/bin/bash"
240 envcmd = fs_related.find_binary_inchroot("env", extmnt)
241 if envcmd:
242 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
243 chroot.chroot(extmnt, None, cmdline)
244 except:
245 raise errors.CreatorError("Failed to chroot to %s." % img)
246 finally:
247 chroot.cleanup_after_chroot("img", extloop, None, extmnt)
248
249 @classmethod
250 def do_unpack(cls, srcimg):
251 image = os.path.join(tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"),
252 "target.img")
253 msger.info("Copying file system ...")
254 shutil.copyfile(srcimg, image)
255 return image
diff --git a/scripts/lib/mic/plugins/imager/raw_plugin.py b/scripts/lib/mic/plugins/imager/raw_plugin.py
new file mode 100644
index 0000000000..f9625b87e8
--- /dev/null
+++ b/scripts/lib/mic/plugins/imager/raw_plugin.py
@@ -0,0 +1,275 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import shutil
20import re
21import tempfile
22
23from mic import chroot, msger
24from mic.utils import misc, fs_related, errors, runner, cmdln
25from mic.conf import configmgr
26from mic.plugin import pluginmgr
27from mic.utils.partitionedfs import PartitionedMount
28
29import mic.imager.raw as raw
30
31from mic.pluginbase import ImagerPlugin
32class RawPlugin(ImagerPlugin):
33 name = 'raw'
34
35 @classmethod
36 @cmdln.option("--compress-disk-image", dest="compress_image", type='choice',
37 choices=("gz", "bz2"), default=None,
38 help="Same with --compress-image")
39 @cmdln.option("--compress-image", dest="compress_image", type='choice',
40 choices=("gz", "bz2"), default = None,
41 help="Compress all raw images before package")
42 @cmdln.option("--generate-bmap", action="store_true", default = None,
43 help="also generate the block map file")
44 @cmdln.option("--fstab-entry", dest="fstab_entry", type='choice',
45 choices=("name", "uuid"), default="uuid",
46 help="Set fstab entry, 'name' means using device names, "
47 "'uuid' means using filesystem uuid")
48 def do_create(self, subcmd, opts, *args):
49 """${cmd_name}: create raw image
50
51 Usage:
52 ${name} ${cmd_name} <ksfile> [OPTS]
53
54 ${cmd_option_list}
55 """
56
57 if len(args) != 1:
58 raise errors.Usage("Extra arguments given")
59
60 creatoropts = configmgr.create
61 ksconf = args[0]
62
63 if creatoropts['runtime'] == "bootstrap":
64 configmgr._ksconf = ksconf
65 rt_util.bootstrap_mic()
66
67 recording_pkgs = []
68 if len(creatoropts['record_pkgs']) > 0:
69 recording_pkgs = creatoropts['record_pkgs']
70
71 if creatoropts['release'] is not None:
72 if 'name' not in recording_pkgs:
73 recording_pkgs.append('name')
74 if 'vcs' not in recording_pkgs:
75 recording_pkgs.append('vcs')
76
77 configmgr._ksconf = ksconf
78
79 # Called After setting the configmgr._ksconf as the creatoropts['name'] is reset there.
80 if creatoropts['release'] is not None:
81 creatoropts['outdir'] = "%s/%s/images/%s/" % (creatoropts['outdir'], creatoropts['release'], creatoropts['name'])
82
83 # try to find the pkgmgr
84 pkgmgr = None
85 backends = pluginmgr.get_plugins('backend')
86 if 'auto' == creatoropts['pkgmgr']:
87 for key in configmgr.prefer_backends:
88 if key in backends:
89 pkgmgr = backends[key]
90 break
91 else:
92 for key in backends.keys():
93 if key == creatoropts['pkgmgr']:
94 pkgmgr = backends[key]
95 break
96
97 if not pkgmgr:
98 raise errors.CreatorError("Can't find backend: %s, "
99 "available choices: %s" %
100 (creatoropts['pkgmgr'],
101 ','.join(backends.keys())))
102
103 creator = raw.RawImageCreator(creatoropts, pkgmgr, opts.compress_image,
104 opts.generate_bmap, opts.fstab_entry)
105
106 if len(recording_pkgs) > 0:
107 creator._recording_pkgs = recording_pkgs
108
109 images = ["%s-%s.raw" % (creator.name, disk_name)
110 for disk_name in creator.get_disk_names()]
111 self.check_image_exists(creator.destdir,
112 creator.pack_to,
113 images,
114 creatoropts['release'])
115
116 try:
117 creator.check_depend_tools()
118 creator.mount(None, creatoropts["cachedir"])
119 creator.install()
120 creator.configure(creatoropts["repomd"])
121 creator.copy_kernel()
122 creator.unmount()
123 creator.generate_bmap()
124 creator.package(creatoropts["outdir"])
125 if creatoropts['release'] is not None:
126 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['release'])
127 creator.print_outimage_info()
128
129 except errors.CreatorError:
130 raise
131 finally:
132 creator.cleanup()
133
134 msger.info("Finished.")
135 return 0
136
137 @classmethod
138 def do_chroot(cls, target, cmd=[]):
139 img = target
140 imgsize = misc.get_file_size(img) * 1024L * 1024L
141 partedcmd = fs_related.find_binary_path("parted")
142 disk = fs_related.SparseLoopbackDisk(img, imgsize)
143 imgmnt = misc.mkdtemp()
144 imgloop = PartitionedMount(imgmnt, skipformat = True)
145 imgloop.add_disk('/dev/sdb', disk)
146 img_fstype = "ext3"
147
148 msger.info("Partition Table:")
149 partnum = []
150 for line in runner.outs([partedcmd, "-s", img, "print"]).splitlines():
151 # no use strip to keep line output here
152 if "Number" in line:
153 msger.raw(line)
154 if line.strip() and line.strip()[0].isdigit():
155 partnum.append(line.strip()[0])
156 msger.raw(line)
157
158 rootpart = None
159 if len(partnum) > 1:
160 rootpart = msger.choice("please choose root partition", partnum)
161
162 # Check the partitions from raw disk.
163 # if choose root part, the mark it as mounted
164 if rootpart:
165 root_mounted = True
166 else:
167 root_mounted = False
168 partition_mounts = 0
169 for line in runner.outs([partedcmd,"-s",img,"unit","B","print"]).splitlines():
170 line = line.strip()
171
172 # Lines that start with number are the partitions,
173 # because parted can be translated we can't refer to any text lines.
174 if not line or not line[0].isdigit():
175 continue
176
177 # Some vars have extra , as list seperator.
178 line = line.replace(",","")
179
180 # Example of parted output lines that are handled:
181 # Number Start End Size Type File system Flags
182 # 1 512B 3400000511B 3400000000B primary
183 # 2 3400531968B 3656384511B 255852544B primary linux-swap(v1)
184 # 3 3656384512B 3720347647B 63963136B primary fat16 boot, lba
185
186 partition_info = re.split("\s+",line)
187
188 size = partition_info[3].split("B")[0]
189
190 if len(partition_info) < 6 or partition_info[5] in ["boot"]:
191 # No filesystem can be found from partition line. Assuming
192 # btrfs, because that is the only MeeGo fs that parted does
193 # not recognize properly.
194 # TODO: Can we make better assumption?
195 fstype = "btrfs"
196 elif partition_info[5] in ["ext2","ext3","ext4","btrfs"]:
197 fstype = partition_info[5]
198 elif partition_info[5] in ["fat16","fat32"]:
199 fstype = "vfat"
200 elif "swap" in partition_info[5]:
201 fstype = "swap"
202 else:
203 raise errors.CreatorError("Could not recognize partition fs type '%s'." % partition_info[5])
204
205 if rootpart and rootpart == line[0]:
206 mountpoint = '/'
207 elif not root_mounted and fstype in ["ext2","ext3","ext4","btrfs"]:
208 # TODO: Check that this is actually the valid root partition from /etc/fstab
209 mountpoint = "/"
210 root_mounted = True
211 elif fstype == "swap":
212 mountpoint = "swap"
213 else:
214 # TODO: Assing better mount points for the rest of the partitions.
215 partition_mounts += 1
216 mountpoint = "/media/partition_%d" % partition_mounts
217
218 if "boot" in partition_info:
219 boot = True
220 else:
221 boot = False
222
223 msger.verbose("Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot))
224 # TODO: add_partition should take bytes as size parameter.
225 imgloop.add_partition((int)(size)/1024/1024, "/dev/sdb", mountpoint, fstype = fstype, boot = boot)
226
227 try:
228 imgloop.mount()
229
230 except errors.MountError:
231 imgloop.cleanup()
232 raise
233
234 try:
235 if len(cmd) != 0:
236 cmdline = ' '.join(cmd)
237 else:
238 cmdline = "/bin/bash"
239 envcmd = fs_related.find_binary_inchroot("env", imgmnt)
240 if envcmd:
241 cmdline = "%s HOME=/root %s" % (envcmd, cmdline)
242 chroot.chroot(imgmnt, None, cmdline)
243 except:
244 raise errors.CreatorError("Failed to chroot to %s." %img)
245 finally:
246 chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
247
248 @classmethod
249 def do_unpack(cls, srcimg):
250 srcimgsize = (misc.get_file_size(srcimg)) * 1024L * 1024L
251 srcmnt = misc.mkdtemp("srcmnt")
252 disk = fs_related.SparseLoopbackDisk(srcimg, srcimgsize)
253 srcloop = PartitionedMount(srcmnt, skipformat = True)
254
255 srcloop.add_disk('/dev/sdb', disk)
256 srcloop.add_partition(srcimgsize/1024/1024, "/dev/sdb", "/", "ext3", boot=False)
257 try:
258 srcloop.mount()
259
260 except errors.MountError:
261 srcloop.cleanup()
262 raise
263
264 image = os.path.join(tempfile.mkdtemp(dir = "/var/tmp", prefix = "tmp"), "target.img")
265 args = ['dd', "if=%s" % srcloop.partitions[0]['device'], "of=%s" % image]
266
267 msger.info("`dd` image ...")
268 rc = runner.show(args)
269 srcloop.cleanup()
270 shutil.rmtree(os.path.dirname(srcmnt), ignore_errors = True)
271
272 if rc != 0:
273 raise errors.CreatorError("Failed to dd")
274 else:
275 return image
diff --git a/scripts/lib/mic/plugins/source/bootimg-efi.py b/scripts/lib/mic/plugins/source/bootimg-efi.py
new file mode 100644
index 0000000000..2cc179a337
--- /dev/null
+++ b/scripts/lib/mic/plugins/source/bootimg-efi.py
@@ -0,0 +1,169 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'bootimg-efi' source plugin class for 'wic'
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27import os
28import shutil
29import re
30import tempfile
31
32from mic import kickstart, chroot, msger
33from mic.utils import misc, fs_related, errors, runner, cmdln
34from mic.conf import configmgr
35from mic.plugin import pluginmgr
36from mic.utils.partitionedfs import PartitionedMount
37import mic.imager.direct as direct
38from mic.pluginbase import SourcePlugin
39from mic.utils.oe.misc import *
40from mic.imager.direct import DirectImageCreator
41
42class BootimgEFIPlugin(SourcePlugin):
43 name = 'bootimg-efi'
44
45 @classmethod
46 def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
47 bootimg_dir, kernel_dir, native_sysroot):
48 """
49 Called before do_prepare_partition(), creates grubefi config
50 """
51 hdddir = "%s/hdd/boot" % cr_workdir
52 rm_cmd = "rm -rf %s" % cr_workdir
53 exec_cmd(rm_cmd)
54
55 install_cmd = "install -d %s/EFI/BOOT" % hdddir
56 tmp = exec_cmd(install_cmd)
57
58 splash = os.path.join(cr_workdir, "/EFI/boot/splash.jpg")
59 if os.path.exists(splash):
60 splashline = "menu background splash.jpg"
61 else:
62 splashline = ""
63
64 (rootdev, root_part_uuid) = cr._get_boot_config()
65 options = cr.ks.handler.bootloader.appendLine
66
67 grubefi_conf = ""
68 grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
69 grubefi_conf += "default=boot\n"
70 timeout = kickstart.get_timeout(cr.ks)
71 if not timeout:
72 timeout = 0
73 grubefi_conf += "timeout=%s\n" % timeout
74 grubefi_conf += "menuentry 'boot'{\n"
75
76 kernel = "/vmlinuz"
77
78 if cr._ptable_format == 'msdos':
79 rootstr = rootdev
80 else:
81 if not root_part_uuid:
82 raise MountError("Cannot find the root GPT partition UUID")
83 rootstr = "PARTUUID=%s" % root_part_uuid
84
85 grubefi_conf += "linux %s root=%s rootwait %s\n" \
86 % (kernel, rootstr, options)
87 grubefi_conf += "}\n"
88 if splashline:
89 syslinux_conf += "%s\n" % splashline
90
91 msger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg" \
92 % cr_workdir)
93 cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
94 cfg.write(grubefi_conf)
95 cfg.close()
96
97 @classmethod
98 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
99 kernel_dir, rootfs_dir, native_sysroot):
100 """
101 Called to do the actual content population for a partition i.e. it
102 'prepares' the partition to be incorporated into the image.
103 In this case, prepare content for an EFI (grub) boot partition.
104 """
105 if not bootimg_dir:
106 bootimg_dir = get_bitbake_var("HDDDIR")
107 if not bootimg_dir:
108 msger.error("Couldn't find HDDDIR, exiting\n")
109 # just so the result notes display it
110 cr.set_bootimg_dir(bootimg_dir)
111
112 staging_kernel_dir = kernel_dir
113 staging_data_dir = bootimg_dir
114
115 hdddir = "%s/hdd" % cr_workdir
116
117 install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
118 (staging_kernel_dir, hdddir)
119 tmp = exec_cmd(install_cmd)
120
121 shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
122 "%s/grub.cfg" % cr_workdir)
123
124 cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (staging_data_dir, hdddir)
125 exec_cmd(cp_cmd, True)
126
127 shutil.move("%s/grub.cfg" % cr_workdir,
128 "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
129
130 du_cmd = "du -bks %s" % hdddir
131 rc, out = exec_cmd(du_cmd)
132 blocks = int(out.split()[0])
133
134 extra_blocks = part.get_extra_block_count(blocks)
135
136 if extra_blocks < BOOTDD_EXTRA_SPACE:
137 extra_blocks = BOOTDD_EXTRA_SPACE
138
139 blocks += extra_blocks
140
141 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
142 (extra_blocks, part.mountpoint, blocks))
143
144 # Ensure total sectors is an integral number of sectors per
145 # track or mcopy will complain. Sectors are 512 bytes, and we
146 # generate images with 32 sectors per track. This calculation is
147 # done in blocks, thus the mod by 16 instead of 32.
148 blocks += (16 - (blocks % 16))
149
150 # dosfs image, created by mkdosfs
151 bootimg = "%s/boot.img" % cr_workdir
152
153 dosfs_cmd = "mkdosfs -n efi -C %s %d" % (bootimg, blocks)
154 exec_native_cmd(dosfs_cmd, native_sysroot)
155
156 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
157 exec_native_cmd(mcopy_cmd, native_sysroot)
158
159 chmod_cmd = "chmod 644 %s" % bootimg
160 exec_cmd(chmod_cmd)
161
162 du_cmd = "du -Lbms %s" % bootimg
163 rc, out = exec_cmd(du_cmd)
164 bootimg_size = out.split()[0]
165
166 part.set_size(bootimg_size)
167 part.set_source_file(bootimg)
168
169
diff --git a/scripts/lib/mic/plugins/source/bootimg-pcbios.py b/scripts/lib/mic/plugins/source/bootimg-pcbios.py
new file mode 100644
index 0000000000..1211e5c93b
--- /dev/null
+++ b/scripts/lib/mic/plugins/source/bootimg-pcbios.py
@@ -0,0 +1,195 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'bootimg-pcbios' source plugin class for 'wic'
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25#
26
27import os
28import shutil
29import re
30import tempfile
31
32from mic import kickstart, chroot, msger
33from mic.utils import misc, fs_related, errors, runner, cmdln
34from mic.conf import configmgr
35from mic.plugin import pluginmgr
36from mic.utils.partitionedfs import PartitionedMount
37import mic.imager.direct as direct
38from mic.pluginbase import SourcePlugin
39from mic.utils.oe.misc import *
40from mic.imager.direct import DirectImageCreator
41
42class BootimgPcbiosPlugin(SourcePlugin):
43 name = 'bootimg-pcbios'
44
45 @classmethod
46 def do_install_disk(self, disk, disk_name, cr, workdir, oe_builddir,
47 bootimg_dir, kernel_dir, native_sysroot):
48 """
49 Called after all partitions have been prepared and assembled into a
50 disk image. In this case, we install the MBR.
51 """
52 mbrfile = "%s/syslinux/" % bootimg_dir
53 if cr._ptable_format == 'gpt':
54 mbrfile += "gptmbr.bin"
55 else:
56 mbrfile += "mbr.bin"
57
58 if not os.path.exists(mbrfile):
59 msger.error("Couldn't find %s. If using the -e option, do you have the right MACHINE set in local.conf? If not, is the bootimg_dir path correct?" % mbrfile)
60
61 full_path = cr._full_path(workdir, disk_name, "direct")
62 msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
63 % (disk_name, full_path, disk['min_size']))
64
65 rc = runner.show(['dd', 'if=%s' % mbrfile,
66 'of=%s' % full_path, 'conv=notrunc'])
67 if rc != 0:
68 raise MountError("Unable to set MBR to %s" % full_path)
69
70 @classmethod
71 def do_configure_partition(self, part, cr, cr_workdir, oe_builddir,
72 bootimg_dir, kernel_dir, native_sysroot):
73 """
74 Called before do_prepare_partition(), creates syslinux config
75 """
76 hdddir = "%s/hdd/boot" % cr_workdir
77 rm_cmd = "rm -rf " + cr_workdir
78 exec_cmd(rm_cmd)
79
80 install_cmd = "install -d %s" % hdddir
81 tmp = exec_cmd(install_cmd)
82
83 splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg")
84 if os.path.exists(splash):
85 splashline = "menu background splash.jpg"
86 else:
87 splashline = ""
88
89 (rootdev, root_part_uuid) = cr._get_boot_config()
90 options = cr.ks.handler.bootloader.appendLine
91
92 syslinux_conf = ""
93 syslinux_conf += "PROMPT 0\n"
94 timeout = kickstart.get_timeout(cr.ks)
95 if not timeout:
96 timeout = 0
97 syslinux_conf += "TIMEOUT " + str(timeout) + "\n"
98 syslinux_conf += "\n"
99 syslinux_conf += "ALLOWOPTIONS 1\n"
100 syslinux_conf += "SERIAL 0 115200\n"
101 syslinux_conf += "\n"
102 if splashline:
103 syslinux_conf += "%s\n" % splashline
104 syslinux_conf += "DEFAULT boot\n"
105 syslinux_conf += "LABEL boot\n"
106
107 kernel = "/vmlinuz"
108 syslinux_conf += "KERNEL " + kernel + "\n"
109
110 if cr._ptable_format == 'msdos':
111 rootstr = rootdev
112 else:
113 if not root_part_uuid:
114 raise MountError("Cannot find the root GPT partition UUID")
115 rootstr = "PARTUUID=%s" % root_part_uuid
116
117 syslinux_conf += "APPEND label=boot root=%s %s\n" % (rootstr, options)
118
119 msger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg" \
120 % cr_workdir)
121 cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w")
122 cfg.write(syslinux_conf)
123 cfg.close()
124
125 @classmethod
126 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
127 kernel_dir, rootfs_dir, native_sysroot):
128 """
129 Called to do the actual content population for a partition i.e. it
130 'prepares' the partition to be incorporated into the image.
131 In this case, prepare content for legacy bios boot partition.
132 """
133 if not bootimg_dir:
134 bootimg_dir = get_bitbake_var("STAGING_DATADIR")
135 if not bootimg_dir:
136 msger.error("Couldn't find STAGING_DATADIR, exiting\n")
137 # just so the result notes display it
138 cr.set_bootimg_dir(bootimg_dir)
139
140 staging_kernel_dir = kernel_dir
141 staging_data_dir = bootimg_dir
142
143 hdddir = "%s/hdd/boot" % cr_workdir
144
145 install_cmd = "install -m 0644 %s/bzImage %s/vmlinuz" \
146 % (staging_kernel_dir, hdddir)
147 tmp = exec_cmd(install_cmd)
148
149 install_cmd = "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" \
150 % (staging_data_dir, hdddir)
151 tmp = exec_cmd(install_cmd)
152
153 du_cmd = "du -bks %s" % hdddir
154 rc, out = exec_cmd(du_cmd)
155 blocks = int(out.split()[0])
156
157 extra_blocks = part.get_extra_block_count(blocks)
158
159 if extra_blocks < BOOTDD_EXTRA_SPACE:
160 extra_blocks = BOOTDD_EXTRA_SPACE
161
162 blocks += extra_blocks
163
164 msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
165 (extra_blocks, part.mountpoint, blocks))
166
167 # Ensure total sectors is an integral number of sectors per
168 # track or mcopy will complain. Sectors are 512 bytes, and we
169 # generate images with 32 sectors per track. This calculation is
170 # done in blocks, thus the mod by 16 instead of 32.
171 blocks += (16 - (blocks % 16))
172
173 # dosfs image, created by mkdosfs
174 bootimg = "%s/boot.img" % cr_workdir
175
176 dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (bootimg, blocks)
177 exec_native_cmd(dosfs_cmd, native_sysroot)
178
179 mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
180 exec_native_cmd(mcopy_cmd, native_sysroot)
181
182 syslinux_cmd = "syslinux %s" % bootimg
183 exec_native_cmd(syslinux_cmd, native_sysroot)
184
185 chmod_cmd = "chmod 644 %s" % bootimg
186 exec_cmd(chmod_cmd)
187
188 du_cmd = "du -Lbms %s" % bootimg
189 rc, out = exec_cmd(du_cmd)
190 bootimg_size = out.split()[0]
191
192 part.set_size(bootimg_size)
193 part.set_source_file(bootimg)
194
195
diff --git a/scripts/lib/mic/plugins/source/rootfs.py b/scripts/lib/mic/plugins/source/rootfs.py
new file mode 100644
index 0000000000..75999e03d2
--- /dev/null
+++ b/scripts/lib/mic/plugins/source/rootfs.py
@@ -0,0 +1,71 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'rootfs' source plugin class for 'wic'
22#
23# AUTHORS
24# Tom Zanussi <tom.zanussi (at] linux.intel.com>
25# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
26#
27
28import os
29import shutil
30import re
31import tempfile
32
33from mic import kickstart, chroot, msger
34from mic.utils import misc, fs_related, errors, runner, cmdln
35from mic.conf import configmgr
36from mic.plugin import pluginmgr
37from mic.utils.partitionedfs import PartitionedMount
38import mic.imager.direct as direct
39from mic.pluginbase import SourcePlugin
40from mic.utils.oe.misc import *
41from mic.imager.direct import DirectImageCreator
42
43class RootfsPlugin(SourcePlugin):
44 name = 'rootfs'
45
46 @classmethod
47 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
48 kernel_dir, krootfs_dir, native_sysroot):
49 """
50 Called to do the actual content population for a partition i.e. it
51 'prepares' the partition to be incorporated into the image.
52 In this case, prepare content for legacy bios boot partition.
53 """
54 if part.rootfs is None:
55 if not 'ROOTFS_DIR' in krootfs_dir:
56 msg = "Couldn't find --rootfs-dir, exiting"
57 msger.error(msg)
58 rootfs_dir = krootfs_dir['ROOTFS_DIR']
59 else:
60 if part.rootfs in krootfs_dir:
61 rootfs_dir = krootfs_dir[part.rootfs]
62 elif os.path.isdir(part.rootfs):
63 rootfs_dir = part.rootfs
64 else:
65 msg = "Couldn't find --rootfs-dir=%s connection"
66 msg += " or it is not a valid path, exiting"
67 msger.error(msg % part.rootfs)
68
69 part.set_rootfs(rootfs_dir)
70 part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, native_sysroot)
71
diff --git a/scripts/lib/mic/plugins/source/uboot.py b/scripts/lib/mic/plugins/source/uboot.py
new file mode 100644
index 0000000000..57cb3cf8fe
--- /dev/null
+++ b/scripts/lib/mic/plugins/source/uboot.py
@@ -0,0 +1,173 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Enea AB.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the 'uboot' source plugin class for 'wic'
22#
23# AUTHORS
24# Adrian Calianu <adrian.calianu (at] enea.com>
25#
26
27import os
28import shutil
29import re
30import tempfile
31
32from mic import kickstart, chroot, msger
33from mic.utils import misc, fs_related, errors, runner, cmdln
34from mic.conf import configmgr
35from mic.plugin import pluginmgr
36from mic.utils.partitionedfs import PartitionedMount
37import mic.imager.direct as direct
38from mic.pluginbase import SourcePlugin
39from mic.utils.oe.misc import *
40from mic.imager.direct import DirectImageCreator
41
42def create_local_rootfs(part, creator, cr_workdir, krootfs_dir, native_sysroot):
43 # In order to have a full control over rootfs we will make a local copy under workdir
44 # and change rootfs_dir to new location.
45 # In this way we can install more than one ROOTFS_DIRs and/or use
46 # an empty rootfs to install packages, so a rootfs could be generated only from pkgs
47 # TBD: create workdir/rootfs ; copy rootfs-> workdir/rootfs; set rootfs=workdir/rootfs
48
49 cr_workdir = os.path.abspath(cr_workdir)
50 new_rootfs_dir = "%s/rootfs_%s" % (cr_workdir, creator.name)
51
52 rootfs_exists = 1
53 if part.rootfs is None:
54 if not 'ROOTFS_DIR' in krootfs_dir:
55 msg = "Couldn't find --rootfs-dir, exiting, "
56 msger.info(msg)
57 rootfs_exists = 0
58 rootfs_dir = krootfs_dir['ROOTFS_DIR']
59 creator.rootfs_dir['ROOTFS_DIR'] = new_rootfs_dir
60 else:
61 if part.rootfs in krootfs_dir:
62 rootfs_dir = krootfs_dir[part.rootfs]
63 creator.rootfs_dir[part.rootfs] = new_rootfs_dir
64 elif os.path.isdir(part.rootfs):
65 rootfs_dir = part.rootfs
66 part.rootfs = new_rootfs_dir
67 else:
68 msg = "Couldn't find --rootfs-dir=%s connection"
69 msg += " or it is not a valid path, exiting"
70 msger.info(msg % part.rootfs)
71 rootfs_exists = 0
72 creator.rootfs_dir['ROOTFS_DIR'] = new_rootfs_dir
73
74 pseudox = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
75 pseudox += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % new_rootfs_dir
76 pseudox += "export PSEUDO_PASSWD=%s;" % new_rootfs_dir
77 pseudox += "export PSEUDO_NOSYMLINKEXP=1;"
78 pseudox += "%s/usr/bin/pseudo " % native_sysroot
79
80 mkdir_cmd = "mkdir %s" % (new_rootfs_dir)
81 # rc, out = exec_native_cmd(pseudox + mkdir_cmd, native_sysroot)
82 rc, out = exec_cmd(mkdir_cmd, True)
83
84 if rootfs_exists == 1 and os.path.isdir(rootfs_dir):
85 defpath = os.environ['PATH']
86 os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
87
88 rootfs_dir = os.path.abspath(rootfs_dir)
89
90 pseudoc = "export PSEUDO_PREFIX=%s/usr;" % native_sysroot
91 pseudoc += "export PSEUDO_LOCALSTATEDIR=%s/../pseudo;" % rootfs_dir
92 pseudoc += "export PSEUDO_PASSWD=%s;" % rootfs_dir
93 pseudoc += "export PSEUDO_NOSYMLINKEXP=1;"
94 pseudoc += "%s/usr/bin/pseudo " % native_sysroot
95
96 tarc_cmd = "tar cvpf %s/rootfs.tar -C %s ." % (cr_workdir, rootfs_dir)
97 rc, out = exec_native_cmd(pseudoc + tarc_cmd, native_sysroot)
98
99 tarx_cmd = "tar xpvf %s/rootfs.tar -C %s" % (cr_workdir, new_rootfs_dir)
100 rc, out = exec_native_cmd(pseudox + tarx_cmd, native_sysroot)
101
102 rm_cmd = "rm %s/rootfs.tar" % cr_workdir
103 rc, out = exec_cmd(rm_cmd, True)
104
105 os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
106
107 return new_rootfs_dir
108
109class UBootPlugin(SourcePlugin):
110 name = 'uboot'
111
112 @classmethod
113 def do_install_pkgs(self, part, creator, cr_workdir, oe_builddir, krootfs_dir,
114 bootimg_dir, kernel_dir, native_sysroot):
115 """
116 Called before all partitions have been prepared and assembled into a
117 disk image. Intall packages based on wic configuration.
118 """
119
120 # set new rootfs_dir
121 rootfs_dir = create_local_rootfs(part, creator, cr_workdir, krootfs_dir, native_sysroot)
122
123 # wks file parsing
124 packages = kickstart.get_packages(creator.ks)
125
126 # wic.conf file parsing = found under 'creator'
127 local_pkgs_path = creator._local_pkgs_path
128 repourl = creator.repourl
129 pkgmgr = creator.pkgmgr_name
130
131 # install packages
132 if packages and pkgmgr in ["opkg"]:
133 if len(repourl) > 0 :
134 part.install_pkgs_ipk(cr_workdir, oe_builddir, rootfs_dir, native_sysroot,
135 packages, repourl)
136 else:
137 msger.error("No packages repository provided in wic.conf")
138
139 @classmethod
140 def do_prepare_partition(self, part, cr, cr_workdir, oe_builddir, bootimg_dir,
141 kernel_dir, krootfs_dir, native_sysroot):
142 """
143 Called to do the actual content population for a partition i.e. it
144 'prepares' the partition to be incorporated into the image.
145 In this case, prepare content for legacy bios boot partition.
146 """
147 if part.rootfs is None:
148 if not 'ROOTFS_DIR' in krootfs_dir:
149 msg = "Couldn't find --rootfs-dir, exiting"
150 msger.error(msg)
151 rootfs_dir = krootfs_dir['ROOTFS_DIR']
152 else:
153 if part.rootfs in krootfs_dir:
154 rootfs_dir = krootfs_dir[part.rootfs]
155 elif os.path.isdir(part.rootfs):
156 rootfs_dir = part.rootfs
157 else:
158 msg = "Couldn't find --rootfs-dir=%s connection"
159 msg += " or it is not a valid path, exiting"
160 msger.error(msg % part.rootfs)
161
162 part.set_rootfs(rootfs_dir)
163
164 # change partition label wich will reflect into the final rootfs image name
165 part.label = "%s_%s" % (part.label, cr.name)
166
167 defpath = os.environ['PATH']
168 os.environ['PATH'] = native_sysroot + "/usr/bin/" + ":/bin:/usr/bin:"
169
170 part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, native_sysroot)
171 part.prepare_for_uboot(cr.target_arch,cr_workdir, oe_builddir, rootfs_dir, native_sysroot)
172
173 os.environ['PATH'] += defpath + ":" + native_sysroot + "/usr/bin/"
diff --git a/scripts/lib/mic/rt_util.py b/scripts/lib/mic/rt_util.py
new file mode 100644
index 0000000000..2a31f4a218
--- /dev/null
+++ b/scripts/lib/mic/rt_util.py
@@ -0,0 +1,223 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from __future__ import with_statement
19import os
20import sys
21import glob
22import re
23import shutil
24import subprocess
25
26from mic import bootstrap, msger
27from mic.conf import configmgr
28from mic.utils import errors, proxy
29from mic.utils.fs_related import find_binary_path, makedirs
30from mic.chroot import setup_chrootenv, cleanup_chrootenv
31
32expath = lambda p: os.path.abspath(os.path.expanduser(p))
33
34def bootstrap_mic(argv=None):
35
36
37 def mychroot():
38 os.chroot(rootdir)
39 os.chdir(cwd)
40
41 # by default, sys.argv is used to run mic in bootstrap
42 if not argv:
43 argv = sys.argv
44 if argv[0] not in ('/usr/bin/mic', 'mic'):
45 argv[0] = '/usr/bin/mic'
46
47 cropts = configmgr.create
48 bsopts = configmgr.bootstrap
49 distro = bsopts['distro_name'].lower()
50
51 rootdir = bsopts['rootdir']
52 pkglist = bsopts['packages']
53 cwd = os.getcwd()
54
55 # create bootstrap and run mic in bootstrap
56 bsenv = bootstrap.Bootstrap(rootdir, distro, cropts['arch'])
57 bsenv.logfile = cropts['logfile']
58 # rootdir is regenerated as a temp dir
59 rootdir = bsenv.rootdir
60
61 if 'optional' in bsopts:
62 optlist = bsopts['optional']
63 else:
64 optlist = []
65
66 try:
67 msger.info("Creating %s bootstrap ..." % distro)
68 bsenv.create(cropts['repomd'], pkglist, optlist)
69
70 # bootstrap is relocated under "bootstrap"
71 if os.path.exists(os.path.join(rootdir, "bootstrap")):
72 rootdir = os.path.join(rootdir, "bootstrap")
73
74 bsenv.dirsetup(rootdir)
75 sync_mic(rootdir)
76
77 #FIXME: sync the ks file to bootstrap
78 if "/" == os.path.dirname(os.path.abspath(configmgr._ksconf)):
79 safecopy(configmgr._ksconf, rootdir)
80
81 msger.info("Start mic in bootstrap: %s\n" % rootdir)
82 bindmounts = get_bindmounts(cropts)
83 ret = bsenv.run(argv, cwd, rootdir, bindmounts)
84
85 except errors.BootstrapError, err:
86 msger.warning('\n%s' % err)
87 if msger.ask("Switch to native mode and continue?"):
88 return
89 raise
90 except RuntimeError, err:
91 #change exception type but keep the trace back
92 value, tb = sys.exc_info()[1:]
93 raise errors.BootstrapError, value, tb
94 else:
95 sys.exit(ret)
96 finally:
97 bsenv.cleanup()
98
99def get_bindmounts(cropts):
100 binddirs = [
101 os.getcwd(),
102 cropts['tmpdir'],
103 cropts['cachedir'],
104 cropts['outdir'],
105 cropts['local_pkgs_path'],
106 ]
107 bindfiles = [
108 cropts['logfile'],
109 configmgr._ksconf,
110 ]
111
112 for lrepo in cropts['localrepos']:
113 binddirs.append(lrepo)
114
115 bindlist = map(expath, filter(None, binddirs))
116 bindlist += map(os.path.dirname, map(expath, filter(None, bindfiles)))
117 bindlist = sorted(set(bindlist))
118 bindmounts = ';'.join(bindlist)
119 return bindmounts
120
121
122def get_mic_binpath():
123 fp = None
124 try:
125 import pkg_resources # depends on 'setuptools'
126 except ImportError:
127 pass
128 else:
129 dist = pkg_resources.get_distribution('mic')
130 # the real script is under EGG_INFO/scripts
131 if dist.has_metadata('scripts/mic'):
132 fp = os.path.join(dist.egg_info, "scripts/mic")
133
134 if fp:
135 return fp
136
137 # not found script if 'flat' egg installed
138 try:
139 return find_binary_path('mic')
140 except errors.CreatorError:
141 raise errors.BootstrapError("Can't find mic binary in host OS")
142
143
144def get_mic_modpath():
145 try:
146 import mic
147 except ImportError:
148 raise errors.BootstrapError("Can't find mic module in host OS")
149 path = os.path.abspath(mic.__file__)
150 return os.path.dirname(path)
151
152def get_mic_libpath():
153 # TBD: so far mic lib path is hard coded
154 return "/usr/lib/mic"
155
156# the hard code path is prepared for bootstrap
157def sync_mic(bootstrap, binpth = '/usr/bin/mic',
158 libpth='/usr/lib',
159 pylib = '/usr/lib/python2.7/site-packages',
160 conf = '/etc/mic/mic.conf'):
161 _path = lambda p: os.path.join(bootstrap, p.lstrip('/'))
162
163 micpaths = {
164 'binpth': get_mic_binpath(),
165 'libpth': get_mic_libpath(),
166 'pylib': get_mic_modpath(),
167 'conf': '/etc/mic/mic.conf',
168 }
169
170 if not os.path.exists(_path(pylib)):
171 pyptn = '/usr/lib/python?.?/site-packages'
172 pylibs = glob.glob(_path(pyptn))
173 if pylibs:
174 pylib = pylibs[0].replace(bootstrap, '')
175 else:
176 raise errors.BootstrapError("Can't find python site dir in: %s" %
177 bootstrap)
178
179 for key, value in micpaths.items():
180 try:
181 safecopy(value, _path(eval(key)), False, ["*.pyc", "*.pyo"])
182 except (OSError, IOError), err:
183 raise errors.BootstrapError(err)
184
185 # auto select backend
186 conf_str = file(_path(conf)).read()
187 conf_str = re.sub("pkgmgr\s*=\s*.*", "pkgmgr=auto", conf_str)
188 with open(_path(conf), 'w') as wf:
189 wf.write(conf_str)
190
191 # chmod +x /usr/bin/mic
192 os.chmod(_path(binpth), 0777)
193
194 # correct python interpreter
195 mic_cont = file(_path(binpth)).read()
196 mic_cont = "#!/usr/bin/python\n" + mic_cont
197 with open(_path(binpth), 'w') as wf:
198 wf.write(mic_cont)
199
200
201def safecopy(src, dst, symlinks=False, ignore_ptns=()):
202 if os.path.isdir(src):
203 if os.path.isdir(dst):
204 dst = os.path.join(dst, os.path.basename(src))
205 if os.path.exists(dst):
206 shutil.rmtree(dst, ignore_errors=True)
207
208 src = src.rstrip('/')
209 # check common prefix to ignore copying itself
210 if dst.startswith(src + '/'):
211 ignore_ptns = list(ignore_ptns) + [ os.path.basename(src) ]
212
213 ignores = shutil.ignore_patterns(*ignore_ptns)
214 try:
215 shutil.copytree(src, dst, symlinks, ignores)
216 except (OSError, IOError):
217 shutil.rmtree(dst, ignore_errors=True)
218 raise
219 else:
220 if not os.path.isdir(dst):
221 makedirs(os.path.dirname(dst))
222
223 shutil.copy2(src, dst)
diff --git a/scripts/lib/mic/test b/scripts/lib/mic/test
new file mode 100644
index 0000000000..9daeafb986
--- /dev/null
+++ b/scripts/lib/mic/test
@@ -0,0 +1 @@
test
diff --git a/scripts/lib/mic/utils/BmapCreate.py b/scripts/lib/mic/utils/BmapCreate.py
new file mode 100644
index 0000000000..65b19a5f46
--- /dev/null
+++ b/scripts/lib/mic/utils/BmapCreate.py
@@ -0,0 +1,298 @@
1""" This module implements the block map (bmap) creation functionality and
2provides the corresponding API in form of the 'BmapCreate' class.
3
4The idea is that while images files may generally be very large (e.g., 4GiB),
5they may nevertheless contain only little real data, e.g., 512MiB. This data
6are files, directories, file-system meta-data, partition table, etc. When
7copying the image to the target device, you do not have to copy all the 4GiB of
8data, you can copy only 512MiB of it, which is 4 times less, so copying should
9presumably be 4 times faster.
10
11The block map file is an XML file which contains a list of blocks which have to
12be copied to the target device. The other blocks are not used and there is no
13need to copy them. The XML file also contains some additional information like
14block size, image size, count of mapped blocks, etc. There are also many
15commentaries, so it is human-readable.
16
17The image has to be a sparse file. Generally, this means that when you generate
18this image file, you should start with a huge sparse file which contains a
19single hole spanning the entire file. Then you should partition it, write all
20the data (probably by means of loop-back mounting the image or parts of it),
21etc. The end result should be a sparse file where mapped areas represent useful
22parts of the image and holes represent useless parts of the image, which do not
23have to be copied when copying the image to the target device.
24
25This module uses the FIBMAP ioctl to detect holes. """
26
27# Disable the following pylint recommendations:
28# * Too many instance attributes - R0902
29# * Too few public methods - R0903
30# pylint: disable=R0902,R0903
31
32import hashlib
33from mic.utils.misc import human_size
34from mic.utils import Fiemap
35
36# The bmap format version we generate
37SUPPORTED_BMAP_VERSION = "1.3"
38
39_BMAP_START_TEMPLATE = \
40"""<?xml version="1.0" ?>
41<!-- This file contains the block map for an image file, which is basically
42 a list of useful (mapped) block numbers in the image file. In other words,
43 it lists only those blocks which contain data (boot sector, partition
44 table, file-system metadata, files, directories, extents, etc). These
45 blocks have to be copied to the target device. The other blocks do not
46 contain any useful data and do not have to be copied to the target
47 device.
48
49 The block map an optimization which allows to copy or flash the image to
50 the image quicker than copying of flashing the entire image. This is
51 because with bmap less data is copied: <MappedBlocksCount> blocks instead
52 of <BlocksCount> blocks.
53
54 Besides the machine-readable data, this file contains useful commentaries
55 which contain human-readable information like image size, percentage of
56 mapped data, etc.
57
58 The 'version' attribute is the block map file format version in the
59 'major.minor' format. The version major number is increased whenever an
60 incompatible block map format change is made. The minor number changes
61 in case of minor backward-compatible changes. -->
62
63<bmap version="%s">
64 <!-- Image size in bytes: %s -->
65 <ImageSize> %u </ImageSize>
66
67 <!-- Size of a block in bytes -->
68 <BlockSize> %u </BlockSize>
69
70 <!-- Count of blocks in the image file -->
71 <BlocksCount> %u </BlocksCount>
72
73"""
74
75class Error(Exception):
76 """ A class for exceptions generated by this module. We currently support
77 only one type of exceptions, and we basically throw human-readable problem
78 description in case of errors. """
79 pass
80
81class BmapCreate:
82 """ This class implements the bmap creation functionality. To generate a
83 bmap for an image (which is supposedly a sparse file), you should first
84 create an instance of 'BmapCreate' and provide:
85
86 * full path or a file-like object of the image to create bmap for
87 * full path or a file object to use for writing the results to
88
89 Then you should invoke the 'generate()' method of this class. It will use
90 the FIEMAP ioctl to generate the bmap. """
91
92 def _open_image_file(self):
93 """ Open the image file. """
94
95 try:
96 self._f_image = open(self._image_path, 'rb')
97 except IOError as err:
98 raise Error("cannot open image file '%s': %s" \
99 % (self._image_path, err))
100
101 self._f_image_needs_close = True
102
103 def _open_bmap_file(self):
104 """ Open the bmap file. """
105
106 try:
107 self._f_bmap = open(self._bmap_path, 'w+')
108 except IOError as err:
109 raise Error("cannot open bmap file '%s': %s" \
110 % (self._bmap_path, err))
111
112 self._f_bmap_needs_close = True
113
114 def __init__(self, image, bmap):
115 """ Initialize a class instance:
116 * image - full path or a file-like object of the image to create bmap
117 for
118 * bmap - full path or a file object to use for writing the resulting
119 bmap to """
120
121 self.image_size = None
122 self.image_size_human = None
123 self.block_size = None
124 self.blocks_cnt = None
125 self.mapped_cnt = None
126 self.mapped_size = None
127 self.mapped_size_human = None
128 self.mapped_percent = None
129
130 self._mapped_count_pos1 = None
131 self._mapped_count_pos2 = None
132 self._sha1_pos = None
133
134 self._f_image_needs_close = False
135 self._f_bmap_needs_close = False
136
137 if hasattr(image, "read"):
138 self._f_image = image
139 self._image_path = image.name
140 else:
141 self._image_path = image
142 self._open_image_file()
143
144 if hasattr(bmap, "read"):
145 self._f_bmap = bmap
146 self._bmap_path = bmap.name
147 else:
148 self._bmap_path = bmap
149 self._open_bmap_file()
150
151 self.fiemap = Fiemap.Fiemap(self._f_image)
152
153 self.image_size = self.fiemap.image_size
154 self.image_size_human = human_size(self.image_size)
155 if self.image_size == 0:
156 raise Error("cannot generate bmap for zero-sized image file '%s'" \
157 % self._image_path)
158
159 self.block_size = self.fiemap.block_size
160 self.blocks_cnt = self.fiemap.blocks_cnt
161
162 def _bmap_file_start(self):
163 """ A helper function which generates the starting contents of the
164 block map file: the header comment, image size, block size, etc. """
165
166 # We do not know the amount of mapped blocks at the moment, so just put
167 # whitespaces instead of real numbers. Assume the longest possible
168 # numbers.
169 mapped_count = ' ' * len(str(self.image_size))
170 mapped_size_human = ' ' * len(self.image_size_human)
171
172 xml = _BMAP_START_TEMPLATE \
173 % (SUPPORTED_BMAP_VERSION, self.image_size_human,
174 self.image_size, self.block_size, self.blocks_cnt)
175 xml += " <!-- Count of mapped blocks: "
176
177 self._f_bmap.write(xml)
178 self._mapped_count_pos1 = self._f_bmap.tell()
179
180 # Just put white-spaces instead of real information about mapped blocks
181 xml = "%s or %.1f -->\n" % (mapped_size_human, 100.0)
182 xml += " <MappedBlocksCount> "
183
184 self._f_bmap.write(xml)
185 self._mapped_count_pos2 = self._f_bmap.tell()
186
187 xml = "%s </MappedBlocksCount>\n\n" % mapped_count
188
189 # pylint: disable=C0301
190 xml += " <!-- The checksum of this bmap file. When it is calculated, the value of\n"
191 xml += " the SHA1 checksum has be zeoro (40 ASCII \"0\" symbols). -->\n"
192 xml += " <BmapFileSHA1> "
193
194 self._f_bmap.write(xml)
195 self._sha1_pos = self._f_bmap.tell()
196
197 xml = "0" * 40 + " </BmapFileSHA1>\n\n"
198 xml += " <!-- The block map which consists of elements which may either be a\n"
199 xml += " range of blocks or a single block. The 'sha1' attribute (if present)\n"
200 xml += " is the SHA1 checksum of this blocks range. -->\n"
201 xml += " <BlockMap>\n"
202 # pylint: enable=C0301
203
204 self._f_bmap.write(xml)
205
206 def _bmap_file_end(self):
207 """ A helper function which generates the final parts of the block map
208 file: the ending tags and the information about the amount of mapped
209 blocks. """
210
211 xml = " </BlockMap>\n"
212 xml += "</bmap>\n"
213
214 self._f_bmap.write(xml)
215
216 self._f_bmap.seek(self._mapped_count_pos1)
217 self._f_bmap.write("%s or %.1f%%" % \
218 (self.mapped_size_human, self.mapped_percent))
219
220 self._f_bmap.seek(self._mapped_count_pos2)
221 self._f_bmap.write("%u" % self.mapped_cnt)
222
223 self._f_bmap.seek(0)
224 sha1 = hashlib.sha1(self._f_bmap.read()).hexdigest()
225 self._f_bmap.seek(self._sha1_pos)
226 self._f_bmap.write("%s" % sha1)
227
228 def _calculate_sha1(self, first, last):
229 """ A helper function which calculates SHA1 checksum for the range of
230 blocks of the image file: from block 'first' to block 'last'. """
231
232 start = first * self.block_size
233 end = (last + 1) * self.block_size
234
235 self._f_image.seek(start)
236 hash_obj = hashlib.new("sha1")
237
238 chunk_size = 1024*1024
239 to_read = end - start
240 read = 0
241
242 while read < to_read:
243 if read + chunk_size > to_read:
244 chunk_size = to_read - read
245 chunk = self._f_image.read(chunk_size)
246 hash_obj.update(chunk)
247 read += chunk_size
248
249 return hash_obj.hexdigest()
250
251 def generate(self, include_checksums = True):
252 """ Generate bmap for the image file. If 'include_checksums' is 'True',
253 also generate SHA1 checksums for block ranges. """
254
255 # Save image file position in order to restore it at the end
256 image_pos = self._f_image.tell()
257
258 self._bmap_file_start()
259
260 # Generate the block map and write it to the XML block map
261 # file as we go.
262 self.mapped_cnt = 0
263 for first, last in self.fiemap.get_mapped_ranges(0, self.blocks_cnt):
264 self.mapped_cnt += last - first + 1
265 if include_checksums:
266 sha1 = self._calculate_sha1(first, last)
267 sha1 = " sha1=\"%s\"" % sha1
268 else:
269 sha1 = ""
270
271 if first != last:
272 self._f_bmap.write(" <Range%s> %s-%s </Range>\n" \
273 % (sha1, first, last))
274 else:
275 self._f_bmap.write(" <Range%s> %s </Range>\n" \
276 % (sha1, first))
277
278 self.mapped_size = self.mapped_cnt * self.block_size
279 self.mapped_size_human = human_size(self.mapped_size)
280 self.mapped_percent = (self.mapped_cnt * 100.0) / self.blocks_cnt
281
282 self._bmap_file_end()
283
284 try:
285 self._f_bmap.flush()
286 except IOError as err:
287 raise Error("cannot flush the bmap file '%s': %s" \
288 % (self._bmap_path, err))
289
290 self._f_image.seek(image_pos)
291
292 def __del__(self):
293 """ The class destructor which closes the opened files. """
294
295 if self._f_image_needs_close:
296 self._f_image.close()
297 if self._f_bmap_needs_close:
298 self._f_bmap.close()
diff --git a/scripts/lib/mic/utils/Fiemap.py b/scripts/lib/mic/utils/Fiemap.py
new file mode 100644
index 0000000000..f2db6ff0b8
--- /dev/null
+++ b/scripts/lib/mic/utils/Fiemap.py
@@ -0,0 +1,252 @@
1""" This module implements python API for the FIEMAP ioctl. The FIEMAP ioctl
2allows to find holes and mapped areas in a file. """
3
4# Note, a lot of code in this module is not very readable, because it deals
5# with the rather complex FIEMAP ioctl. To understand the code, you need to
6# know the FIEMAP interface, which is documented in the
7# Documentation/filesystems/fiemap.txt file in the Linux kernel sources.
8
9# Disable the following pylint recommendations:
10# * Too many instance attributes (R0902)
11# pylint: disable=R0902
12
13import os
14import struct
15import array
16import fcntl
17from mic.utils.misc import get_block_size
18
19# Format string for 'struct fiemap'
20_FIEMAP_FORMAT = "=QQLLLL"
21# sizeof(struct fiemap)
22_FIEMAP_SIZE = struct.calcsize(_FIEMAP_FORMAT)
23# Format string for 'struct fiemap_extent'
24_FIEMAP_EXTENT_FORMAT = "=QQQQQLLLL"
25# sizeof(struct fiemap_extent)
26_FIEMAP_EXTENT_SIZE = struct.calcsize(_FIEMAP_EXTENT_FORMAT)
27# The FIEMAP ioctl number
28_FIEMAP_IOCTL = 0xC020660B
29
30# Minimum buffer which is required for 'class Fiemap' to operate
31MIN_BUFFER_SIZE = _FIEMAP_SIZE + _FIEMAP_EXTENT_SIZE
32# The default buffer size for 'class Fiemap'
33DEFAULT_BUFFER_SIZE = 256 * 1024
34
35class Error(Exception):
36 """ A class for exceptions generated by this module. We currently support
37 only one type of exceptions, and we basically throw human-readable problem
38 description in case of errors. """
39 pass
40
41class Fiemap:
42 """ This class provides API to the FIEMAP ioctl. Namely, it allows to
43 iterate over all mapped blocks and over all holes. """
44
45 def _open_image_file(self):
46 """ Open the image file. """
47
48 try:
49 self._f_image = open(self._image_path, 'rb')
50 except IOError as err:
51 raise Error("cannot open image file '%s': %s" \
52 % (self._image_path, err))
53
54 self._f_image_needs_close = True
55
56 def __init__(self, image, buf_size = DEFAULT_BUFFER_SIZE):
57 """ Initialize a class instance. The 'image' argument is full path to
58 the file to operate on, or a file object to operate on.
59
60 The 'buf_size' argument is the size of the buffer for 'struct
61 fiemap_extent' elements which will be used when invoking the FIEMAP
62 ioctl. The larger is the buffer, the less times the FIEMAP ioctl will
63 be invoked. """
64
65 self._f_image_needs_close = False
66
67 if hasattr(image, "fileno"):
68 self._f_image = image
69 self._image_path = image.name
70 else:
71 self._image_path = image
72 self._open_image_file()
73
74 # Validate 'buf_size'
75 if buf_size < MIN_BUFFER_SIZE:
76 raise Error("too small buffer (%d bytes), minimum is %d bytes" \
77 % (buf_size, MIN_BUFFER_SIZE))
78
79 # How many 'struct fiemap_extent' elements fit the buffer
80 buf_size -= _FIEMAP_SIZE
81 self._fiemap_extent_cnt = buf_size / _FIEMAP_EXTENT_SIZE
82 self._buf_size = self._fiemap_extent_cnt * _FIEMAP_EXTENT_SIZE
83 self._buf_size += _FIEMAP_SIZE
84
85 # Allocate a mutable buffer for the FIEMAP ioctl
86 self._buf = array.array('B', [0] * self._buf_size)
87
88 self.image_size = os.fstat(self._f_image.fileno()).st_size
89
90 try:
91 self.block_size = get_block_size(self._f_image)
92 except IOError as err:
93 raise Error("cannot get block size for '%s': %s" \
94 % (self._image_path, err))
95
96 self.blocks_cnt = self.image_size + self.block_size - 1
97 self.blocks_cnt /= self.block_size
98
99 # Synchronize the image file to make sure FIEMAP returns correct values
100 try:
101 self._f_image.flush()
102 except IOError as err:
103 raise Error("cannot flush image file '%s': %s" \
104 % (self._image_path, err))
105 try:
106 os.fsync(self._f_image.fileno()),
107 except OSError as err:
108 raise Error("cannot synchronize image file '%s': %s " \
109 % (self._image_path, err.strerror))
110
111 # Check if the FIEMAP ioctl is supported
112 self.block_is_mapped(0)
113
114 def __del__(self):
115 """ The class destructor which closes the opened files. """
116
117 if self._f_image_needs_close:
118 self._f_image.close()
119
120 def _invoke_fiemap(self, block, count):
121 """ Invoke the FIEMAP ioctl for 'count' blocks of the file starting from
122 block number 'block'.
123
124 The full result of the operation is stored in 'self._buf' on exit.
125 Returns the unpacked 'struct fiemap' data structure in form of a python
126 list (just like 'struct.upack()'). """
127
128 if block < 0 or block >= self.blocks_cnt:
129 raise Error("bad block number %d, should be within [0, %d]" \
130 % (block, self.blocks_cnt))
131
132 # Initialize the 'struct fiemap' part of the buffer
133 struct.pack_into(_FIEMAP_FORMAT, self._buf, 0, block * self.block_size,
134 count * self.block_size, 0, 0,
135 self._fiemap_extent_cnt, 0)
136
137 try:
138 fcntl.ioctl(self._f_image, _FIEMAP_IOCTL, self._buf, 1)
139 except IOError as err:
140 error_msg = "the FIEMAP ioctl failed for '%s': %s" \
141 % (self._image_path, err)
142 if err.errno == os.errno.EPERM or err.errno == os.errno.EACCES:
143 # The FIEMAP ioctl was added in kernel version 2.6.28 in 2008
144 error_msg += " (looks like your kernel does not support FIEMAP)"
145
146 raise Error(error_msg)
147
148 return struct.unpack(_FIEMAP_FORMAT, self._buf[:_FIEMAP_SIZE])
149
150 def block_is_mapped(self, block):
151 """ This function returns 'True' if block number 'block' of the image
152 file is mapped and 'False' otherwise. """
153
154 struct_fiemap = self._invoke_fiemap(block, 1)
155
156 # The 3rd element of 'struct_fiemap' is the 'fm_mapped_extents' field.
157 # If it contains zero, the block is not mapped, otherwise it is
158 # mapped.
159 return bool(struct_fiemap[3])
160
161 def block_is_unmapped(self, block):
162 """ This function returns 'True' if block number 'block' of the image
163 file is not mapped (hole) and 'False' otherwise. """
164
165 return not self.block_is_mapped(block)
166
167 def _unpack_fiemap_extent(self, index):
168 """ Unpack a 'struct fiemap_extent' structure object number 'index'
169 from the internal 'self._buf' buffer. """
170
171 offset = _FIEMAP_SIZE + _FIEMAP_EXTENT_SIZE * index
172 return struct.unpack(_FIEMAP_EXTENT_FORMAT,
173 self._buf[offset : offset + _FIEMAP_EXTENT_SIZE])
174
175 def _do_get_mapped_ranges(self, start, count):
176 """ Implements most the functionality for the 'get_mapped_ranges()'
177 generator: invokes the FIEMAP ioctl, walks through the mapped
178 extents and yields mapped block ranges. However, the ranges may be
179 consecutive (e.g., (1, 100), (100, 200)) and 'get_mapped_ranges()'
180 simply merges them. """
181
182 block = start
183 while block < start + count:
184 struct_fiemap = self._invoke_fiemap(block, count)
185
186 mapped_extents = struct_fiemap[3]
187 if mapped_extents == 0:
188 # No more mapped blocks
189 return
190
191 extent = 0
192 while extent < mapped_extents:
193 fiemap_extent = self._unpack_fiemap_extent(extent)
194
195 # Start of the extent
196 extent_start = fiemap_extent[0]
197 # Starting block number of the extent
198 extent_block = extent_start / self.block_size
199 # Length of the extent
200 extent_len = fiemap_extent[2]
201 # Count of blocks in the extent
202 extent_count = extent_len / self.block_size
203
204 # Extent length and offset have to be block-aligned
205 assert extent_start % self.block_size == 0
206 assert extent_len % self.block_size == 0
207
208 if extent_block > start + count - 1:
209 return
210
211 first = max(extent_block, block)
212 last = min(extent_block + extent_count, start + count) - 1
213 yield (first, last)
214
215 extent += 1
216
217 block = extent_block + extent_count
218
219 def get_mapped_ranges(self, start, count):
220 """ A generator which yields ranges of mapped blocks in the file. The
221 ranges are tuples of 2 elements: [first, last], where 'first' is the
222 first mapped block and 'last' is the last mapped block.
223
224 The ranges are yielded for the area of the file of size 'count' blocks,
225 starting from block 'start'. """
226
227 iterator = self._do_get_mapped_ranges(start, count)
228
229 first_prev, last_prev = iterator.next()
230
231 for first, last in iterator:
232 if last_prev == first - 1:
233 last_prev = last
234 else:
235 yield (first_prev, last_prev)
236 first_prev, last_prev = first, last
237
238 yield (first_prev, last_prev)
239
240 def get_unmapped_ranges(self, start, count):
241 """ Just like 'get_mapped_ranges()', but yields unmapped block ranges
242 instead (holes). """
243
244 hole_first = start
245 for first, last in self._do_get_mapped_ranges(start, count):
246 if first > hole_first:
247 yield (hole_first, first - 1)
248
249 hole_first = last + 1
250
251 if hole_first < start + count:
252 yield (hole_first, start + count - 1)
diff --git a/scripts/lib/mic/utils/__init__.py b/scripts/lib/mic/utils/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/lib/mic/utils/__init__.py
diff --git a/scripts/lib/mic/utils/cmdln.py b/scripts/lib/mic/utils/cmdln.py
new file mode 100644
index 0000000000..b099473ee4
--- /dev/null
+++ b/scripts/lib/mic/utils/cmdln.py
@@ -0,0 +1,1586 @@
1#!/usr/bin/env python
2# Copyright (c) 2002-2007 ActiveState Software Inc.
3# License: MIT (see LICENSE.txt for license details)
4# Author: Trent Mick
5# Home: http://trentm.com/projects/cmdln/
6
7"""An improvement on Python's standard cmd.py module.
8
9As with cmd.py, this module provides "a simple framework for writing
10line-oriented command intepreters." This module provides a 'RawCmdln'
11class that fixes some design flaws in cmd.Cmd, making it more scalable
12and nicer to use for good 'cvs'- or 'svn'-style command line interfaces
13or simple shells. And it provides a 'Cmdln' class that add
14optparse-based option processing. Basically you use it like this:
15
16 import cmdln
17
18 class MySVN(cmdln.Cmdln):
19 name = "svn"
20
21 @cmdln.alias('stat', 'st')
22 @cmdln.option('-v', '--verbose', action='store_true'
23 help='print verbose information')
24 def do_status(self, subcmd, opts, *paths):
25 print "handle 'svn status' command"
26
27 #...
28
29 if __name__ == "__main__":
30 shell = MySVN()
31 retval = shell.main()
32 sys.exit(retval)
33
34See the README.txt or <http://trentm.com/projects/cmdln/> for more
35details.
36"""
37
38__version_info__ = (1, 1, 2)
39__version__ = '.'.join(map(str, __version_info__))
40
41import os
42import sys
43import re
44import cmd
45import optparse
46from pprint import pprint
47import sys
48
49
50
51
52#---- globals
53
54LOOP_ALWAYS, LOOP_NEVER, LOOP_IF_EMPTY = range(3)
55
56# An unspecified optional argument when None is a meaningful value.
57_NOT_SPECIFIED = ("Not", "Specified")
58
59# Pattern to match a TypeError message from a call that
60# failed because of incorrect number of arguments (see
61# Python/getargs.c).
62_INCORRECT_NUM_ARGS_RE = re.compile(
63 r"(takes [\w ]+ )(\d+)( arguments? \()(\d+)( given\))")
64
65
66
67#---- exceptions
68
69class CmdlnError(Exception):
70 """A cmdln.py usage error."""
71 def __init__(self, msg):
72 self.msg = msg
73 def __str__(self):
74 return self.msg
75
76class CmdlnUserError(Exception):
77 """An error by a user of a cmdln-based tool/shell."""
78 pass
79
80
81
82#---- public methods and classes
83
84def alias(*aliases):
85 """Decorator to add aliases for Cmdln.do_* command handlers.
86
87 Example:
88 class MyShell(cmdln.Cmdln):
89 @cmdln.alias("!", "sh")
90 def do_shell(self, argv):
91 #...implement 'shell' command
92 """
93 def decorate(f):
94 if not hasattr(f, "aliases"):
95 f.aliases = []
96 f.aliases += aliases
97 return f
98 return decorate
99
100
101class RawCmdln(cmd.Cmd):
102 """An improved (on cmd.Cmd) framework for building multi-subcommand
103 scripts (think "svn" & "cvs") and simple shells (think "pdb" and
104 "gdb").
105
106 A simple example:
107
108 import cmdln
109
110 class MySVN(cmdln.RawCmdln):
111 name = "svn"
112
113 @cmdln.aliases('stat', 'st')
114 def do_status(self, argv):
115 print "handle 'svn status' command"
116
117 if __name__ == "__main__":
118 shell = MySVN()
119 retval = shell.main()
120 sys.exit(retval)
121
122 See <http://trentm.com/projects/cmdln> for more information.
123 """
124 name = None # if unset, defaults basename(sys.argv[0])
125 prompt = None # if unset, defaults to self.name+"> "
126 version = None # if set, default top-level options include --version
127
128 # Default messages for some 'help' command error cases.
129 # They are interpolated with one arg: the command.
130 nohelp = "no help on '%s'"
131 unknowncmd = "unknown command: '%s'"
132
133 helpindent = '' # string with which to indent help output
134
135 def __init__(self, completekey='tab',
136 stdin=None, stdout=None, stderr=None):
137 """Cmdln(completekey='tab', stdin=None, stdout=None, stderr=None)
138
139 The optional argument 'completekey' is the readline name of a
140 completion key; it defaults to the Tab key. If completekey is
141 not None and the readline module is available, command completion
142 is done automatically.
143
144 The optional arguments 'stdin', 'stdout' and 'stderr' specify
145 alternate input, output and error output file objects; if not
146 specified, sys.* are used.
147
148 If 'stdout' but not 'stderr' is specified, stdout is used for
149 error output. This is to provide least surprise for users used
150 to only the 'stdin' and 'stdout' options with cmd.Cmd.
151 """
152 import sys
153 if self.name is None:
154 self.name = os.path.basename(sys.argv[0])
155 if self.prompt is None:
156 self.prompt = self.name+"> "
157 self._name_str = self._str(self.name)
158 self._prompt_str = self._str(self.prompt)
159 if stdin is not None:
160 self.stdin = stdin
161 else:
162 self.stdin = sys.stdin
163 if stdout is not None:
164 self.stdout = stdout
165 else:
166 self.stdout = sys.stdout
167 if stderr is not None:
168 self.stderr = stderr
169 elif stdout is not None:
170 self.stderr = stdout
171 else:
172 self.stderr = sys.stderr
173 self.cmdqueue = []
174 self.completekey = completekey
175 self.cmdlooping = False
176
177 def get_optparser(self):
178 """Hook for subclasses to set the option parser for the
179 top-level command/shell.
180
181 This option parser is used retrieved and used by `.main()' to
182 handle top-level options.
183
184 The default implements a single '-h|--help' option. Sub-classes
185 can return None to have no options at the top-level. Typically
186 an instance of CmdlnOptionParser should be returned.
187 """
188 version = (self.version is not None
189 and "%s %s" % (self._name_str, self.version)
190 or None)
191 return CmdlnOptionParser(self, version=version)
192
193 def postoptparse(self):
194 """Hook method executed just after `.main()' parses top-level
195 options.
196
197 When called `self.options' holds the results of the option parse.
198 """
199 pass
200
201 def main(self, argv=None, loop=LOOP_NEVER):
202 """A possible mainline handler for a script, like so:
203
204 import cmdln
205 class MyCmd(cmdln.Cmdln):
206 name = "mycmd"
207 ...
208
209 if __name__ == "__main__":
210 MyCmd().main()
211
212 By default this will use sys.argv to issue a single command to
213 'MyCmd', then exit. The 'loop' argument can be use to control
214 interactive shell behaviour.
215
216 Arguments:
217 "argv" (optional, default sys.argv) is the command to run.
218 It must be a sequence, where the first element is the
219 command name and subsequent elements the args for that
220 command.
221 "loop" (optional, default LOOP_NEVER) is a constant
222 indicating if a command loop should be started (i.e. an
223 interactive shell). Valid values (constants on this module):
224 LOOP_ALWAYS start loop and run "argv", if any
225 LOOP_NEVER run "argv" (or .emptyline()) and exit
226 LOOP_IF_EMPTY run "argv", if given, and exit;
227 otherwise, start loop
228 """
229 if argv is None:
230 import sys
231 argv = sys.argv
232 else:
233 argv = argv[:] # don't modify caller's list
234
235 self.optparser = self.get_optparser()
236 if self.optparser: # i.e. optparser=None means don't process for opts
237 try:
238 self.options, args = self.optparser.parse_args(argv[1:])
239 except CmdlnUserError, ex:
240 msg = "%s: %s\nTry '%s help' for info.\n"\
241 % (self.name, ex, self.name)
242 self.stderr.write(self._str(msg))
243 self.stderr.flush()
244 return 1
245 except StopOptionProcessing, ex:
246 return 0
247 else:
248 self.options, args = None, argv[1:]
249 self.postoptparse()
250
251 if loop == LOOP_ALWAYS:
252 if args:
253 self.cmdqueue.append(args)
254 return self.cmdloop()
255 elif loop == LOOP_NEVER:
256 if args:
257 return self.cmd(args)
258 else:
259 return self.emptyline()
260 elif loop == LOOP_IF_EMPTY:
261 if args:
262 return self.cmd(args)
263 else:
264 return self.cmdloop()
265
266 def cmd(self, argv):
267 """Run one command and exit.
268
269 "argv" is the arglist for the command to run. argv[0] is the
270 command to run. If argv is an empty list then the
271 'emptyline' handler is run.
272
273 Returns the return value from the command handler.
274 """
275 assert isinstance(argv, (list, tuple)), \
276 "'argv' is not a sequence: %r" % argv
277 retval = None
278 try:
279 argv = self.precmd(argv)
280 retval = self.onecmd(argv)
281 self.postcmd(argv)
282 except:
283 if not self.cmdexc(argv):
284 raise
285 retval = 1
286 return retval
287
288 def _str(self, s):
289 """Safely convert the given str/unicode to a string for printing."""
290 try:
291 return str(s)
292 except UnicodeError:
293 #XXX What is the proper encoding to use here? 'utf-8' seems
294 # to work better than "getdefaultencoding" (usually
295 # 'ascii'), on OS X at least.
296 #import sys
297 #return s.encode(sys.getdefaultencoding(), "replace")
298 return s.encode("utf-8", "replace")
299
300 def cmdloop(self, intro=None):
301 """Repeatedly issue a prompt, accept input, parse into an argv, and
302 dispatch (via .precmd(), .onecmd() and .postcmd()), passing them
303 the argv. In other words, start a shell.
304
305 "intro" (optional) is a introductory message to print when
306 starting the command loop. This overrides the class
307 "intro" attribute, if any.
308 """
309 self.cmdlooping = True
310 self.preloop()
311 if self.use_rawinput and self.completekey:
312 try:
313 import readline
314 self.old_completer = readline.get_completer()
315 readline.set_completer(self.complete)
316 readline.parse_and_bind(self.completekey+": complete")
317 except ImportError:
318 pass
319 try:
320 if intro is None:
321 intro = self.intro
322 if intro:
323 intro_str = self._str(intro)
324 self.stdout.write(intro_str+'\n')
325 self.stop = False
326 retval = None
327 while not self.stop:
328 if self.cmdqueue:
329 argv = self.cmdqueue.pop(0)
330 assert isinstance(argv, (list, tuple)), \
331 "item on 'cmdqueue' is not a sequence: %r" % argv
332 else:
333 if self.use_rawinput:
334 try:
335 line = raw_input(self._prompt_str)
336 except EOFError:
337 line = 'EOF'
338 else:
339 self.stdout.write(self._prompt_str)
340 self.stdout.flush()
341 line = self.stdin.readline()
342 if not len(line):
343 line = 'EOF'
344 else:
345 line = line[:-1] # chop '\n'
346 argv = line2argv(line)
347 try:
348 argv = self.precmd(argv)
349 retval = self.onecmd(argv)
350 self.postcmd(argv)
351 except:
352 if not self.cmdexc(argv):
353 raise
354 retval = 1
355 self.lastretval = retval
356 self.postloop()
357 finally:
358 if self.use_rawinput and self.completekey:
359 try:
360 import readline
361 readline.set_completer(self.old_completer)
362 except ImportError:
363 pass
364 self.cmdlooping = False
365 return retval
366
367 def precmd(self, argv):
368 """Hook method executed just before the command argv is
369 interpreted, but after the input prompt is generated and issued.
370
371 "argv" is the cmd to run.
372
373 Returns an argv to run (i.e. this method can modify the command
374 to run).
375 """
376 return argv
377
378 def postcmd(self, argv):
379 """Hook method executed just after a command dispatch is finished.
380
381 "argv" is the command that was run.
382 """
383 pass
384
385 def cmdexc(self, argv):
386 """Called if an exception is raised in any of precmd(), onecmd(),
387 or postcmd(). If True is returned, the exception is deemed to have
388 been dealt with. Otherwise, the exception is re-raised.
389
390 The default implementation handles CmdlnUserError's, which
391 typically correspond to user error in calling commands (as
392 opposed to programmer error in the design of the script using
393 cmdln.py).
394 """
395 import sys
396 type, exc, traceback = sys.exc_info()
397 if isinstance(exc, CmdlnUserError):
398 msg = "%s %s: %s\nTry '%s help %s' for info.\n"\
399 % (self.name, argv[0], exc, self.name, argv[0])
400 self.stderr.write(self._str(msg))
401 self.stderr.flush()
402 return True
403
404 def onecmd(self, argv):
405 if not argv:
406 return self.emptyline()
407 self.lastcmd = argv
408 cmdname = self._get_canonical_cmd_name(argv[0])
409 if cmdname:
410 handler = self._get_cmd_handler(cmdname)
411 if handler:
412 return self._dispatch_cmd(handler, argv)
413 return self.default(argv)
414
415 def _dispatch_cmd(self, handler, argv):
416 return handler(argv)
417
418 def default(self, argv):
419 """Hook called to handle a command for which there is no handler.
420
421 "argv" is the command and arguments to run.
422
423 The default implementation writes and error message to stderr
424 and returns an error exit status.
425
426 Returns a numeric command exit status.
427 """
428 errmsg = self._str(self.unknowncmd % (argv[0],))
429 if self.cmdlooping:
430 self.stderr.write(errmsg+"\n")
431 else:
432 self.stderr.write("%s: %s\nTry '%s help' for info.\n"
433 % (self._name_str, errmsg, self._name_str))
434 self.stderr.flush()
435 return 1
436
437 def parseline(self, line):
438 # This is used by Cmd.complete (readline completer function) to
439 # massage the current line buffer before completion processing.
440 # We override to drop special '!' handling.
441 line = line.strip()
442 if not line:
443 return None, None, line
444 elif line[0] == '?':
445 line = 'help ' + line[1:]
446 i, n = 0, len(line)
447 while i < n and line[i] in self.identchars: i = i+1
448 cmd, arg = line[:i], line[i:].strip()
449 return cmd, arg, line
450
451 def helpdefault(self, cmd, known):
452 """Hook called to handle help on a command for which there is no
453 help handler.
454
455 "cmd" is the command name on which help was requested.
456 "known" is a boolean indicating if this command is known
457 (i.e. if there is a handler for it).
458
459 Returns a return code.
460 """
461 if known:
462 msg = self._str(self.nohelp % (cmd,))
463 if self.cmdlooping:
464 self.stderr.write(msg + '\n')
465 else:
466 self.stderr.write("%s: %s\n" % (self.name, msg))
467 else:
468 msg = self.unknowncmd % (cmd,)
469 if self.cmdlooping:
470 self.stderr.write(msg + '\n')
471 else:
472 self.stderr.write("%s: %s\n"
473 "Try '%s help' for info.\n"
474 % (self.name, msg, self.name))
475 self.stderr.flush()
476 return 1
477
478 def do_help(self, argv):
479 """${cmd_name}: give detailed help on a specific sub-command
480
481 Usage:
482 ${name} help [COMMAND]
483 """
484 if len(argv) > 1: # asking for help on a particular command
485 doc = None
486 cmdname = self._get_canonical_cmd_name(argv[1]) or argv[1]
487 if not cmdname:
488 return self.helpdefault(argv[1], False)
489 else:
490 helpfunc = getattr(self, "help_"+cmdname, None)
491 if helpfunc:
492 doc = helpfunc()
493 else:
494 handler = self._get_cmd_handler(cmdname)
495 if handler:
496 doc = handler.__doc__
497 if doc is None:
498 return self.helpdefault(argv[1], handler != None)
499 else: # bare "help" command
500 doc = self.__class__.__doc__ # try class docstring
501 if doc is None:
502 # Try to provide some reasonable useful default help.
503 if self.cmdlooping: prefix = ""
504 else: prefix = self.name+' '
505 doc = """Usage:
506 %sCOMMAND [ARGS...]
507 %shelp [COMMAND]
508
509 ${option_list}
510 ${command_list}
511 ${help_list}
512 """ % (prefix, prefix)
513 cmdname = None
514
515 if doc: # *do* have help content, massage and print that
516 doc = self._help_reindent(doc)
517 doc = self._help_preprocess(doc, cmdname)
518 doc = doc.rstrip() + '\n' # trim down trailing space
519 self.stdout.write(self._str(doc))
520 self.stdout.flush()
521 do_help.aliases = ["?"]
522
523 def _help_reindent(self, help, indent=None):
524 """Hook to re-indent help strings before writing to stdout.
525
526 "help" is the help content to re-indent
527 "indent" is a string with which to indent each line of the
528 help content after normalizing. If unspecified or None
529 then the default is use: the 'self.helpindent' class
530 attribute. By default this is the empty string, i.e.
531 no indentation.
532
533 By default, all common leading whitespace is removed and then
534 the lot is indented by 'self.helpindent'. When calculating the
535 common leading whitespace the first line is ignored -- hence
536 help content for Conan can be written as follows and have the
537 expected indentation:
538
539 def do_crush(self, ...):
540 '''${cmd_name}: crush your enemies, see them driven before you...
541
542 c.f. Conan the Barbarian'''
543 """
544 if indent is None:
545 indent = self.helpindent
546 lines = help.splitlines(0)
547 _dedentlines(lines, skip_first_line=True)
548 lines = [(indent+line).rstrip() for line in lines]
549 return '\n'.join(lines)
550
551 def _help_preprocess(self, help, cmdname):
552 """Hook to preprocess a help string before writing to stdout.
553
554 "help" is the help string to process.
555 "cmdname" is the canonical sub-command name for which help
556 is being given, or None if the help is not specific to a
557 command.
558
559 By default the following template variables are interpolated in
560 help content. (Note: these are similar to Python 2.4's
561 string.Template interpolation but not quite.)
562
563 ${name}
564 The tool's/shell's name, i.e. 'self.name'.
565 ${option_list}
566 A formatted table of options for this shell/tool.
567 ${command_list}
568 A formatted table of available sub-commands.
569 ${help_list}
570 A formatted table of additional help topics (i.e. 'help_*'
571 methods with no matching 'do_*' method).
572 ${cmd_name}
573 The name (and aliases) for this sub-command formatted as:
574 "NAME (ALIAS1, ALIAS2, ...)".
575 ${cmd_usage}
576 A formatted usage block inferred from the command function
577 signature.
578 ${cmd_option_list}
579 A formatted table of options for this sub-command. (This is
580 only available for commands using the optparse integration,
581 i.e. using @cmdln.option decorators or manually setting the
582 'optparser' attribute on the 'do_*' method.)
583
584 Returns the processed help.
585 """
586 preprocessors = {
587 "${name}": self._help_preprocess_name,
588 "${option_list}": self._help_preprocess_option_list,
589 "${command_list}": self._help_preprocess_command_list,
590 "${help_list}": self._help_preprocess_help_list,
591 "${cmd_name}": self._help_preprocess_cmd_name,
592 "${cmd_usage}": self._help_preprocess_cmd_usage,
593 "${cmd_option_list}": self._help_preprocess_cmd_option_list,
594 }
595
596 for marker, preprocessor in preprocessors.items():
597 if marker in help:
598 help = preprocessor(help, cmdname)
599 return help
600
601 def _help_preprocess_name(self, help, cmdname=None):
602 return help.replace("${name}", self.name)
603
604 def _help_preprocess_option_list(self, help, cmdname=None):
605 marker = "${option_list}"
606 indent, indent_width = _get_indent(marker, help)
607 suffix = _get_trailing_whitespace(marker, help)
608
609 if self.optparser:
610 # Setup formatting options and format.
611 # - Indentation of 4 is better than optparse default of 2.
612 # C.f. Damian Conway's discussion of this in Perl Best
613 # Practices.
614 self.optparser.formatter.indent_increment = 4
615 self.optparser.formatter.current_indent = indent_width
616 block = self.optparser.format_option_help() + '\n'
617 else:
618 block = ""
619
620 help = help.replace(indent+marker+suffix, block, 1)
621 return help
622
623
624 def _help_preprocess_command_list(self, help, cmdname=None):
625 marker = "${command_list}"
626 indent, indent_width = _get_indent(marker, help)
627 suffix = _get_trailing_whitespace(marker, help)
628
629 # Find any aliases for commands.
630 token2canonical = self._get_canonical_map()
631 aliases = {}
632 for token, cmdname in token2canonical.items():
633 if token == cmdname: continue
634 aliases.setdefault(cmdname, []).append(token)
635
636 # Get the list of (non-hidden) commands and their
637 # documentation, if any.
638 cmdnames = {} # use a dict to strip duplicates
639 for attr in self.get_names():
640 if attr.startswith("do_"):
641 cmdnames[attr[3:]] = True
642 cmdnames = cmdnames.keys()
643 cmdnames.sort()
644 linedata = []
645 for cmdname in cmdnames:
646 if aliases.get(cmdname):
647 a = aliases[cmdname]
648 a.sort()
649 cmdstr = "%s (%s)" % (cmdname, ", ".join(a))
650 else:
651 cmdstr = cmdname
652 doc = None
653 try:
654 helpfunc = getattr(self, 'help_'+cmdname)
655 except AttributeError:
656 handler = self._get_cmd_handler(cmdname)
657 if handler:
658 doc = handler.__doc__
659 else:
660 doc = helpfunc()
661
662 # Strip "${cmd_name}: " from the start of a command's doc. Best
663 # practice dictates that command help strings begin with this, but
664 # it isn't at all wanted for the command list.
665 to_strip = "${cmd_name}:"
666 if doc and doc.startswith(to_strip):
667 #log.debug("stripping %r from start of %s's help string",
668 # to_strip, cmdname)
669 doc = doc[len(to_strip):].lstrip()
670 linedata.append( (cmdstr, doc) )
671
672 if linedata:
673 subindent = indent + ' '*4
674 lines = _format_linedata(linedata, subindent, indent_width+4)
675 block = indent + "Commands:\n" \
676 + '\n'.join(lines) + "\n\n"
677 help = help.replace(indent+marker+suffix, block, 1)
678 return help
679
680 def _gen_names_and_attrs(self):
681 # Inheritance says we have to look in class and
682 # base classes; order is not important.
683 names = []
684 classes = [self.__class__]
685 while classes:
686 aclass = classes.pop(0)
687 if aclass.__bases__:
688 classes = classes + list(aclass.__bases__)
689 for name in dir(aclass):
690 yield (name, getattr(aclass, name))
691
692 def _help_preprocess_help_list(self, help, cmdname=None):
693 marker = "${help_list}"
694 indent, indent_width = _get_indent(marker, help)
695 suffix = _get_trailing_whitespace(marker, help)
696
697 # Determine the additional help topics, if any.
698 helpnames = {}
699 token2cmdname = self._get_canonical_map()
700 for attrname, attr in self._gen_names_and_attrs():
701 if not attrname.startswith("help_"): continue
702 helpname = attrname[5:]
703 if helpname not in token2cmdname:
704 helpnames[helpname] = attr
705
706 if helpnames:
707 linedata = [(n, a.__doc__ or "") for n, a in helpnames.items()]
708 linedata.sort()
709
710 subindent = indent + ' '*4
711 lines = _format_linedata(linedata, subindent, indent_width+4)
712 block = (indent
713 + "Additional help topics (run `%s help TOPIC'):\n" % self.name
714 + '\n'.join(lines)
715 + "\n\n")
716 else:
717 block = ''
718 help = help.replace(indent+marker+suffix, block, 1)
719 return help
720
721 def _help_preprocess_cmd_name(self, help, cmdname=None):
722 marker = "${cmd_name}"
723 handler = self._get_cmd_handler(cmdname)
724 if not handler:
725 raise CmdlnError("cannot preprocess '%s' into help string: "
726 "could not find command handler for %r"
727 % (marker, cmdname))
728 s = cmdname
729 if hasattr(handler, "aliases"):
730 s += " (%s)" % (", ".join(handler.aliases))
731 help = help.replace(marker, s)
732 return help
733
734 #TODO: this only makes sense as part of the Cmdln class.
735 # Add hooks to add help preprocessing template vars and put
736 # this one on that class.
737 def _help_preprocess_cmd_usage(self, help, cmdname=None):
738 marker = "${cmd_usage}"
739 handler = self._get_cmd_handler(cmdname)
740 if not handler:
741 raise CmdlnError("cannot preprocess '%s' into help string: "
742 "could not find command handler for %r"
743 % (marker, cmdname))
744 indent, indent_width = _get_indent(marker, help)
745 suffix = _get_trailing_whitespace(marker, help)
746
747 # Extract the introspection bits we need.
748 func = handler.im_func
749 if func.func_defaults:
750 func_defaults = list(func.func_defaults)
751 else:
752 func_defaults = []
753 co_argcount = func.func_code.co_argcount
754 co_varnames = func.func_code.co_varnames
755 co_flags = func.func_code.co_flags
756 CO_FLAGS_ARGS = 4
757 CO_FLAGS_KWARGS = 8
758
759 # Adjust argcount for possible *args and **kwargs arguments.
760 argcount = co_argcount
761 if co_flags & CO_FLAGS_ARGS: argcount += 1
762 if co_flags & CO_FLAGS_KWARGS: argcount += 1
763
764 # Determine the usage string.
765 usage = "%s %s" % (self.name, cmdname)
766 if argcount <= 2: # handler ::= do_FOO(self, argv)
767 usage += " [ARGS...]"
768 elif argcount >= 3: # handler ::= do_FOO(self, subcmd, opts, ...)
769 argnames = list(co_varnames[3:argcount])
770 tail = ""
771 if co_flags & CO_FLAGS_KWARGS:
772 name = argnames.pop(-1)
773 import warnings
774 # There is no generally accepted mechanism for passing
775 # keyword arguments from the command line. Could
776 # *perhaps* consider: arg=value arg2=value2 ...
777 warnings.warn("argument '**%s' on '%s.%s' command "
778 "handler will never get values"
779 % (name, self.__class__.__name__,
780 func.func_name))
781 if co_flags & CO_FLAGS_ARGS:
782 name = argnames.pop(-1)
783 tail = "[%s...]" % name.upper()
784 while func_defaults:
785 func_defaults.pop(-1)
786 name = argnames.pop(-1)
787 tail = "[%s%s%s]" % (name.upper(), (tail and ' ' or ''), tail)
788 while argnames:
789 name = argnames.pop(-1)
790 tail = "%s %s" % (name.upper(), tail)
791 usage += ' ' + tail
792
793 block_lines = [
794 self.helpindent + "Usage:",
795 self.helpindent + ' '*4 + usage
796 ]
797 block = '\n'.join(block_lines) + '\n\n'
798
799 help = help.replace(indent+marker+suffix, block, 1)
800 return help
801
802 #TODO: this only makes sense as part of the Cmdln class.
803 # Add hooks to add help preprocessing template vars and put
804 # this one on that class.
805 def _help_preprocess_cmd_option_list(self, help, cmdname=None):
806 marker = "${cmd_option_list}"
807 handler = self._get_cmd_handler(cmdname)
808 if not handler:
809 raise CmdlnError("cannot preprocess '%s' into help string: "
810 "could not find command handler for %r"
811 % (marker, cmdname))
812 indent, indent_width = _get_indent(marker, help)
813 suffix = _get_trailing_whitespace(marker, help)
814 if hasattr(handler, "optparser"):
815 # Setup formatting options and format.
816 # - Indentation of 4 is better than optparse default of 2.
817 # C.f. Damian Conway's discussion of this in Perl Best
818 # Practices.
819 handler.optparser.formatter.indent_increment = 4
820 handler.optparser.formatter.current_indent = indent_width
821 block = handler.optparser.format_option_help() + '\n'
822 else:
823 block = ""
824
825 help = help.replace(indent+marker+suffix, block, 1)
826 return help
827
828 def _get_canonical_cmd_name(self, token):
829 map = self._get_canonical_map()
830 return map.get(token, None)
831
832 def _get_canonical_map(self):
833 """Return a mapping of available command names and aliases to
834 their canonical command name.
835 """
836 cacheattr = "_token2canonical"
837 if not hasattr(self, cacheattr):
838 # Get the list of commands and their aliases, if any.
839 token2canonical = {}
840 cmd2funcname = {} # use a dict to strip duplicates
841 for attr in self.get_names():
842 if attr.startswith("do_"): cmdname = attr[3:]
843 elif attr.startswith("_do_"): cmdname = attr[4:]
844 else:
845 continue
846 cmd2funcname[cmdname] = attr
847 token2canonical[cmdname] = cmdname
848 for cmdname, funcname in cmd2funcname.items(): # add aliases
849 func = getattr(self, funcname)
850 aliases = getattr(func, "aliases", [])
851 for alias in aliases:
852 if alias in cmd2funcname:
853 import warnings
854 warnings.warn("'%s' alias for '%s' command conflicts "
855 "with '%s' handler"
856 % (alias, cmdname, cmd2funcname[alias]))
857 continue
858 token2canonical[alias] = cmdname
859 setattr(self, cacheattr, token2canonical)
860 return getattr(self, cacheattr)
861
862 def _get_cmd_handler(self, cmdname):
863 handler = None
864 try:
865 handler = getattr(self, 'do_' + cmdname)
866 except AttributeError:
867 try:
868 # Private command handlers begin with "_do_".
869 handler = getattr(self, '_do_' + cmdname)
870 except AttributeError:
871 pass
872 return handler
873
874 def _do_EOF(self, argv):
875 # Default EOF handler
876 # Note: an actual EOF is redirected to this command.
877 #TODO: separate name for this. Currently it is available from
878 # command-line. Is that okay?
879 self.stdout.write('\n')
880 self.stdout.flush()
881 self.stop = True
882
883 def emptyline(self):
884 # Different from cmd.Cmd: don't repeat the last command for an
885 # emptyline.
886 if self.cmdlooping:
887 pass
888 else:
889 return self.do_help(["help"])
890
891
892#---- optparse.py extension to fix (IMO) some deficiencies
893#
894# See the class _OptionParserEx docstring for details.
895#
896
897class StopOptionProcessing(Exception):
898 """Indicate that option *and argument* processing should stop
899 cleanly. This is not an error condition. It is similar in spirit to
900 StopIteration. This is raised by _OptionParserEx's default "help"
901 and "version" option actions and can be raised by custom option
902 callbacks too.
903
904 Hence the typical CmdlnOptionParser (a subclass of _OptionParserEx)
905 usage is:
906
907 parser = CmdlnOptionParser(mycmd)
908 parser.add_option("-f", "--force", dest="force")
909 ...
910 try:
911 opts, args = parser.parse_args()
912 except StopOptionProcessing:
913 # normal termination, "--help" was probably given
914 sys.exit(0)
915 """
916
917class _OptionParserEx(optparse.OptionParser):
918 """An optparse.OptionParser that uses exceptions instead of sys.exit.
919
920 This class is an extension of optparse.OptionParser that differs
921 as follows:
922 - Correct (IMO) the default OptionParser error handling to never
923 sys.exit(). Instead OptParseError exceptions are passed through.
924 - Add the StopOptionProcessing exception (a la StopIteration) to
925 indicate normal termination of option processing.
926 See StopOptionProcessing's docstring for details.
927
928 I'd also like to see the following in the core optparse.py, perhaps
929 as a RawOptionParser which would serve as a base class for the more
930 generally used OptionParser (that works as current):
931 - Remove the implicit addition of the -h|--help and --version
932 options. They can get in the way (e.g. if want '-?' and '-V' for
933 these as well) and it is not hard to do:
934 optparser.add_option("-h", "--help", action="help")
935 optparser.add_option("--version", action="version")
936 These are good practices, just not valid defaults if they can
937 get in the way.
938 """
939 def error(self, msg):
940 raise optparse.OptParseError(msg)
941
942 def exit(self, status=0, msg=None):
943 if status == 0:
944 raise StopOptionProcessing(msg)
945 else:
946 #TODO: don't lose status info here
947 raise optparse.OptParseError(msg)
948
949
950
951#---- optparse.py-based option processing support
952
953class CmdlnOptionParser(_OptionParserEx):
954 """An optparse.OptionParser class more appropriate for top-level
955 Cmdln options. For parsing of sub-command options, see
956 SubCmdOptionParser.
957
958 Changes:
959 - disable_interspersed_args() by default, because a Cmdln instance
960 has sub-commands which may themselves have options.
961 - Redirect print_help() to the Cmdln.do_help() which is better
962 equiped to handle the "help" action.
963 - error() will raise a CmdlnUserError: OptionParse.error() is meant
964 to be called for user errors. Raising a well-known error here can
965 make error handling clearer.
966 - Also see the changes in _OptionParserEx.
967 """
968 def __init__(self, cmdln, **kwargs):
969 self.cmdln = cmdln
970 kwargs["prog"] = self.cmdln.name
971 _OptionParserEx.__init__(self, **kwargs)
972 self.disable_interspersed_args()
973
974 def print_help(self, file=None):
975 self.cmdln.onecmd(["help"])
976
977 def error(self, msg):
978 raise CmdlnUserError(msg)
979
980
981class SubCmdOptionParser(_OptionParserEx):
982 def set_cmdln_info(self, cmdln, subcmd):
983 """Called by Cmdln to pass relevant info about itself needed
984 for print_help().
985 """
986 self.cmdln = cmdln
987 self.subcmd = subcmd
988
989 def print_help(self, file=None):
990 self.cmdln.onecmd(["help", self.subcmd])
991
992 def error(self, msg):
993 raise CmdlnUserError(msg)
994
995
996def option(*args, **kwargs):
997 """Decorator to add an option to the optparser argument of a Cmdln
998 subcommand.
999
1000 Example:
1001 class MyShell(cmdln.Cmdln):
1002 @cmdln.option("-f", "--force", help="force removal")
1003 def do_remove(self, subcmd, opts, *args):
1004 #...
1005 """
1006 #XXX Is there a possible optimization for many options to not have a
1007 # large stack depth here?
1008 def decorate(f):
1009 if not hasattr(f, "optparser"):
1010 f.optparser = SubCmdOptionParser()
1011 f.optparser.add_option(*args, **kwargs)
1012 return f
1013 return decorate
1014
1015
1016class Cmdln(RawCmdln):
1017 """An improved (on cmd.Cmd) framework for building multi-subcommand
1018 scripts (think "svn" & "cvs") and simple shells (think "pdb" and
1019 "gdb").
1020
1021 A simple example:
1022
1023 import cmdln
1024
1025 class MySVN(cmdln.Cmdln):
1026 name = "svn"
1027
1028 @cmdln.aliases('stat', 'st')
1029 @cmdln.option('-v', '--verbose', action='store_true'
1030 help='print verbose information')
1031 def do_status(self, subcmd, opts, *paths):
1032 print "handle 'svn status' command"
1033
1034 #...
1035
1036 if __name__ == "__main__":
1037 shell = MySVN()
1038 retval = shell.main()
1039 sys.exit(retval)
1040
1041 'Cmdln' extends 'RawCmdln' by providing optparse option processing
1042 integration. See this class' _dispatch_cmd() docstring and
1043 <http://trentm.com/projects/cmdln> for more information.
1044 """
1045 def _dispatch_cmd(self, handler, argv):
1046 """Introspect sub-command handler signature to determine how to
1047 dispatch the command. The raw handler provided by the base
1048 'RawCmdln' class is still supported:
1049
1050 def do_foo(self, argv):
1051 # 'argv' is the vector of command line args, argv[0] is
1052 # the command name itself (i.e. "foo" or an alias)
1053 pass
1054
1055 In addition, if the handler has more than 2 arguments option
1056 processing is automatically done (using optparse):
1057
1058 @cmdln.option('-v', '--verbose', action='store_true')
1059 def do_bar(self, subcmd, opts, *args):
1060 # subcmd = <"bar" or an alias>
1061 # opts = <an optparse.Values instance>
1062 if opts.verbose:
1063 print "lots of debugging output..."
1064 # args = <tuple of arguments>
1065 for arg in args:
1066 bar(arg)
1067
1068 TODO: explain that "*args" can be other signatures as well.
1069
1070 The `cmdln.option` decorator corresponds to an `add_option()`
1071 method call on an `optparse.OptionParser` instance.
1072
1073 You can declare a specific number of arguments:
1074
1075 @cmdln.option('-v', '--verbose', action='store_true')
1076 def do_bar2(self, subcmd, opts, bar_one, bar_two):
1077 #...
1078
1079 and an appropriate error message will be raised/printed if the
1080 command is called with a different number of args.
1081 """
1082 co_argcount = handler.im_func.func_code.co_argcount
1083 if co_argcount == 2: # handler ::= do_foo(self, argv)
1084 return handler(argv)
1085 elif co_argcount >= 3: # handler ::= do_foo(self, subcmd, opts, ...)
1086 try:
1087 optparser = handler.optparser
1088 except AttributeError:
1089 optparser = handler.im_func.optparser = SubCmdOptionParser()
1090 assert isinstance(optparser, SubCmdOptionParser)
1091 optparser.set_cmdln_info(self, argv[0])
1092 try:
1093 opts, args = optparser.parse_args(argv[1:])
1094 except StopOptionProcessing:
1095 #TODO: this doesn't really fly for a replacement of
1096 # optparse.py behaviour, does it?
1097 return 0 # Normal command termination
1098
1099 try:
1100 return handler(argv[0], opts, *args)
1101 except TypeError, ex:
1102 # Some TypeError's are user errors:
1103 # do_foo() takes at least 4 arguments (3 given)
1104 # do_foo() takes at most 5 arguments (6 given)
1105 # do_foo() takes exactly 5 arguments (6 given)
1106 # Raise CmdlnUserError for these with a suitably
1107 # massaged error message.
1108 import sys
1109 tb = sys.exc_info()[2] # the traceback object
1110 if tb.tb_next is not None:
1111 # If the traceback is more than one level deep, then the
1112 # TypeError do *not* happen on the "handler(...)" call
1113 # above. In that we don't want to handle it specially
1114 # here: it would falsely mask deeper code errors.
1115 raise
1116 msg = ex.args[0]
1117 match = _INCORRECT_NUM_ARGS_RE.search(msg)
1118 if match:
1119 msg = list(match.groups())
1120 msg[1] = int(msg[1]) - 3
1121 if msg[1] == 1:
1122 msg[2] = msg[2].replace("arguments", "argument")
1123 msg[3] = int(msg[3]) - 3
1124 msg = ''.join(map(str, msg))
1125 raise CmdlnUserError(msg)
1126 else:
1127 raise
1128 else:
1129 raise CmdlnError("incorrect argcount for %s(): takes %d, must "
1130 "take 2 for 'argv' signature or 3+ for 'opts' "
1131 "signature" % (handler.__name__, co_argcount))
1132
1133
1134
1135#---- internal support functions
1136
1137def _format_linedata(linedata, indent, indent_width):
1138 """Format specific linedata into a pleasant layout.
1139
1140 "linedata" is a list of 2-tuples of the form:
1141 (<item-display-string>, <item-docstring>)
1142 "indent" is a string to use for one level of indentation
1143 "indent_width" is a number of columns by which the
1144 formatted data will be indented when printed.
1145
1146 The <item-display-string> column is held to 15 columns.
1147 """
1148 lines = []
1149 WIDTH = 78 - indent_width
1150 SPACING = 2
1151 NAME_WIDTH_LOWER_BOUND = 13
1152 NAME_WIDTH_UPPER_BOUND = 16
1153 NAME_WIDTH = max([len(s) for s,d in linedata])
1154 if NAME_WIDTH < NAME_WIDTH_LOWER_BOUND:
1155 NAME_WIDTH = NAME_WIDTH_LOWER_BOUND
1156 else:
1157 NAME_WIDTH = NAME_WIDTH_UPPER_BOUND
1158
1159 DOC_WIDTH = WIDTH - NAME_WIDTH - SPACING
1160 for namestr, doc in linedata:
1161 line = indent + namestr
1162 if len(namestr) <= NAME_WIDTH:
1163 line += ' ' * (NAME_WIDTH + SPACING - len(namestr))
1164 else:
1165 lines.append(line)
1166 line = indent + ' ' * (NAME_WIDTH + SPACING)
1167 line += _summarize_doc(doc, DOC_WIDTH)
1168 lines.append(line.rstrip())
1169 return lines
1170
1171def _summarize_doc(doc, length=60):
1172 r"""Parse out a short one line summary from the given doclines.
1173
1174 "doc" is the doc string to summarize.
1175 "length" is the max length for the summary
1176
1177 >>> _summarize_doc("this function does this")
1178 'this function does this'
1179 >>> _summarize_doc("this function does this", 10)
1180 'this fu...'
1181 >>> _summarize_doc("this function does this\nand that")
1182 'this function does this and that'
1183 >>> _summarize_doc("this function does this\n\nand that")
1184 'this function does this'
1185 """
1186 import re
1187 if doc is None:
1188 return ""
1189 assert length > 3, "length <= 3 is absurdly short for a doc summary"
1190 doclines = doc.strip().splitlines(0)
1191 if not doclines:
1192 return ""
1193
1194 summlines = []
1195 for i, line in enumerate(doclines):
1196 stripped = line.strip()
1197 if not stripped:
1198 break
1199 summlines.append(stripped)
1200 if len(''.join(summlines)) >= length:
1201 break
1202
1203 summary = ' '.join(summlines)
1204 if len(summary) > length:
1205 summary = summary[:length-3] + "..."
1206 return summary
1207
1208
1209def line2argv(line):
1210 r"""Parse the given line into an argument vector.
1211
1212 "line" is the line of input to parse.
1213
1214 This may get niggly when dealing with quoting and escaping. The
1215 current state of this parsing may not be completely thorough/correct
1216 in this respect.
1217
1218 >>> from cmdln import line2argv
1219 >>> line2argv("foo")
1220 ['foo']
1221 >>> line2argv("foo bar")
1222 ['foo', 'bar']
1223 >>> line2argv("foo bar ")
1224 ['foo', 'bar']
1225 >>> line2argv(" foo bar")
1226 ['foo', 'bar']
1227
1228 Quote handling:
1229
1230 >>> line2argv("'foo bar'")
1231 ['foo bar']
1232 >>> line2argv('"foo bar"')
1233 ['foo bar']
1234 >>> line2argv(r'"foo\"bar"')
1235 ['foo"bar']
1236 >>> line2argv("'foo bar' spam")
1237 ['foo bar', 'spam']
1238 >>> line2argv("'foo 'bar spam")
1239 ['foo bar', 'spam']
1240
1241 >>> line2argv('some\tsimple\ttests')
1242 ['some', 'simple', 'tests']
1243 >>> line2argv('a "more complex" test')
1244 ['a', 'more complex', 'test']
1245 >>> line2argv('a more="complex test of " quotes')
1246 ['a', 'more=complex test of ', 'quotes']
1247 >>> line2argv('a more" complex test of " quotes')
1248 ['a', 'more complex test of ', 'quotes']
1249 >>> line2argv('an "embedded \\"quote\\""')
1250 ['an', 'embedded "quote"']
1251
1252 # Komodo bug 48027
1253 >>> line2argv('foo bar C:\\')
1254 ['foo', 'bar', 'C:\\']
1255
1256 # Komodo change 127581
1257 >>> line2argv(r'"\test\slash" "foo bar" "foo\"bar"')
1258 ['\\test\\slash', 'foo bar', 'foo"bar']
1259
1260 # Komodo change 127629
1261 >>> if sys.platform == "win32":
1262 ... line2argv(r'\foo\bar') == ['\\foo\\bar']
1263 ... line2argv(r'\\foo\\bar') == ['\\\\foo\\\\bar']
1264 ... line2argv('"foo') == ['foo']
1265 ... else:
1266 ... line2argv(r'\foo\bar') == ['foobar']
1267 ... line2argv(r'\\foo\\bar') == ['\\foo\\bar']
1268 ... try:
1269 ... line2argv('"foo')
1270 ... except ValueError, ex:
1271 ... "not terminated" in str(ex)
1272 True
1273 True
1274 True
1275 """
1276 import string
1277 line = line.strip()
1278 argv = []
1279 state = "default"
1280 arg = None # the current argument being parsed
1281 i = -1
1282 while 1:
1283 i += 1
1284 if i >= len(line): break
1285 ch = line[i]
1286
1287 if ch == "\\" and i+1 < len(line):
1288 # escaped char always added to arg, regardless of state
1289 if arg is None: arg = ""
1290 if (sys.platform == "win32"
1291 or state in ("double-quoted", "single-quoted")
1292 ) and line[i+1] not in tuple('"\''):
1293 arg += ch
1294 i += 1
1295 arg += line[i]
1296 continue
1297
1298 if state == "single-quoted":
1299 if ch == "'":
1300 state = "default"
1301 else:
1302 arg += ch
1303 elif state == "double-quoted":
1304 if ch == '"':
1305 state = "default"
1306 else:
1307 arg += ch
1308 elif state == "default":
1309 if ch == '"':
1310 if arg is None: arg = ""
1311 state = "double-quoted"
1312 elif ch == "'":
1313 if arg is None: arg = ""
1314 state = "single-quoted"
1315 elif ch in string.whitespace:
1316 if arg is not None:
1317 argv.append(arg)
1318 arg = None
1319 else:
1320 if arg is None: arg = ""
1321 arg += ch
1322 if arg is not None:
1323 argv.append(arg)
1324 if not sys.platform == "win32" and state != "default":
1325 raise ValueError("command line is not terminated: unfinished %s "
1326 "segment" % state)
1327 return argv
1328
1329
1330def argv2line(argv):
1331 r"""Put together the given argument vector into a command line.
1332
1333 "argv" is the argument vector to process.
1334
1335 >>> from cmdln import argv2line
1336 >>> argv2line(['foo'])
1337 'foo'
1338 >>> argv2line(['foo', 'bar'])
1339 'foo bar'
1340 >>> argv2line(['foo', 'bar baz'])
1341 'foo "bar baz"'
1342 >>> argv2line(['foo"bar'])
1343 'foo"bar'
1344 >>> print argv2line(['foo" bar'])
1345 'foo" bar'
1346 >>> print argv2line(["foo' bar"])
1347 "foo' bar"
1348 >>> argv2line(["foo'bar"])
1349 "foo'bar"
1350 """
1351 escapedArgs = []
1352 for arg in argv:
1353 if ' ' in arg and '"' not in arg:
1354 arg = '"'+arg+'"'
1355 elif ' ' in arg and "'" not in arg:
1356 arg = "'"+arg+"'"
1357 elif ' ' in arg:
1358 arg = arg.replace('"', r'\"')
1359 arg = '"'+arg+'"'
1360 escapedArgs.append(arg)
1361 return ' '.join(escapedArgs)
1362
1363
1364# Recipe: dedent (0.1) in /Users/trentm/tm/recipes/cookbook
1365def _dedentlines(lines, tabsize=8, skip_first_line=False):
1366 """_dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines
1367
1368 "lines" is a list of lines to dedent.
1369 "tabsize" is the tab width to use for indent width calculations.
1370 "skip_first_line" is a boolean indicating if the first line should
1371 be skipped for calculating the indent width and for dedenting.
1372 This is sometimes useful for docstrings and similar.
1373
1374 Same as dedent() except operates on a sequence of lines. Note: the
1375 lines list is modified **in-place**.
1376 """
1377 DEBUG = False
1378 if DEBUG:
1379 print "dedent: dedent(..., tabsize=%d, skip_first_line=%r)"\
1380 % (tabsize, skip_first_line)
1381 indents = []
1382 margin = None
1383 for i, line in enumerate(lines):
1384 if i == 0 and skip_first_line: continue
1385 indent = 0
1386 for ch in line:
1387 if ch == ' ':
1388 indent += 1
1389 elif ch == '\t':
1390 indent += tabsize - (indent % tabsize)
1391 elif ch in '\r\n':
1392 continue # skip all-whitespace lines
1393 else:
1394 break
1395 else:
1396 continue # skip all-whitespace lines
1397 if DEBUG: print "dedent: indent=%d: %r" % (indent, line)
1398 if margin is None:
1399 margin = indent
1400 else:
1401 margin = min(margin, indent)
1402 if DEBUG: print "dedent: margin=%r" % margin
1403
1404 if margin is not None and margin > 0:
1405 for i, line in enumerate(lines):
1406 if i == 0 and skip_first_line: continue
1407 removed = 0
1408 for j, ch in enumerate(line):
1409 if ch == ' ':
1410 removed += 1
1411 elif ch == '\t':
1412 removed += tabsize - (removed % tabsize)
1413 elif ch in '\r\n':
1414 if DEBUG: print "dedent: %r: EOL -> strip up to EOL" % line
1415 lines[i] = lines[i][j:]
1416 break
1417 else:
1418 raise ValueError("unexpected non-whitespace char %r in "
1419 "line %r while removing %d-space margin"
1420 % (ch, line, margin))
1421 if DEBUG:
1422 print "dedent: %r: %r -> removed %d/%d"\
1423 % (line, ch, removed, margin)
1424 if removed == margin:
1425 lines[i] = lines[i][j+1:]
1426 break
1427 elif removed > margin:
1428 lines[i] = ' '*(removed-margin) + lines[i][j+1:]
1429 break
1430 return lines
1431
1432def _dedent(text, tabsize=8, skip_first_line=False):
1433 """_dedent(text, tabsize=8, skip_first_line=False) -> dedented text
1434
1435 "text" is the text to dedent.
1436 "tabsize" is the tab width to use for indent width calculations.
1437 "skip_first_line" is a boolean indicating if the first line should
1438 be skipped for calculating the indent width and for dedenting.
1439 This is sometimes useful for docstrings and similar.
1440
1441 textwrap.dedent(s), but don't expand tabs to spaces
1442 """
1443 lines = text.splitlines(1)
1444 _dedentlines(lines, tabsize=tabsize, skip_first_line=skip_first_line)
1445 return ''.join(lines)
1446
1447
1448def _get_indent(marker, s, tab_width=8):
1449 """_get_indent(marker, s, tab_width=8) ->
1450 (<indentation-of-'marker'>, <indentation-width>)"""
1451 # Figure out how much the marker is indented.
1452 INDENT_CHARS = tuple(' \t')
1453 start = s.index(marker)
1454 i = start
1455 while i > 0:
1456 if s[i-1] not in INDENT_CHARS:
1457 break
1458 i -= 1
1459 indent = s[i:start]
1460 indent_width = 0
1461 for ch in indent:
1462 if ch == ' ':
1463 indent_width += 1
1464 elif ch == '\t':
1465 indent_width += tab_width - (indent_width % tab_width)
1466 return indent, indent_width
1467
1468def _get_trailing_whitespace(marker, s):
1469 """Return the whitespace content trailing the given 'marker' in string 's',
1470 up to and including a newline.
1471 """
1472 suffix = ''
1473 start = s.index(marker) + len(marker)
1474 i = start
1475 while i < len(s):
1476 if s[i] in ' \t':
1477 suffix += s[i]
1478 elif s[i] in '\r\n':
1479 suffix += s[i]
1480 if s[i] == '\r' and i+1 < len(s) and s[i+1] == '\n':
1481 suffix += s[i+1]
1482 break
1483 else:
1484 break
1485 i += 1
1486 return suffix
1487
1488
1489
1490#---- bash completion support
1491# Note: This is still experimental. I expect to change this
1492# significantly.
1493#
1494# To get Bash completion for a cmdln.Cmdln class, run the following
1495# bash command:
1496# $ complete -C 'python -m cmdln /path/to/script.py CmdlnClass' cmdname
1497# For example:
1498# $ complete -C 'python -m cmdln ~/bin/svn.py SVN' svn
1499#
1500#TODO: Simplify the above so don't have to given path to script (try to
1501# find it on PATH, if possible). Could also make class name
1502# optional if there is only one in the module (common case).
1503
1504if __name__ == "__main__" and len(sys.argv) == 6:
1505 def _log(s):
1506 return # no-op, comment out for debugging
1507 from os.path import expanduser
1508 fout = open(expanduser("~/tmp/bashcpln.log"), 'a')
1509 fout.write(str(s) + '\n')
1510 fout.close()
1511
1512 # Recipe: module_from_path (1.0.1+)
1513 def _module_from_path(path):
1514 import imp, os, sys
1515 path = os.path.expanduser(path)
1516 dir = os.path.dirname(path) or os.curdir
1517 name = os.path.splitext(os.path.basename(path))[0]
1518 sys.path.insert(0, dir)
1519 try:
1520 iinfo = imp.find_module(name, [dir])
1521 return imp.load_module(name, *iinfo)
1522 finally:
1523 sys.path.remove(dir)
1524
1525 def _get_bash_cplns(script_path, class_name, cmd_name,
1526 token, preceding_token):
1527 _log('--')
1528 _log('get_cplns(%r, %r, %r, %r, %r)'
1529 % (script_path, class_name, cmd_name, token, preceding_token))
1530 comp_line = os.environ["COMP_LINE"]
1531 comp_point = int(os.environ["COMP_POINT"])
1532 _log("COMP_LINE: %r" % comp_line)
1533 _log("COMP_POINT: %r" % comp_point)
1534
1535 try:
1536 script = _module_from_path(script_path)
1537 except ImportError, ex:
1538 _log("error importing `%s': %s" % (script_path, ex))
1539 return []
1540 shell = getattr(script, class_name)()
1541 cmd_map = shell._get_canonical_map()
1542 del cmd_map["EOF"]
1543
1544 # Determine if completing the sub-command name.
1545 parts = comp_line[:comp_point].split(None, 1)
1546 _log(parts)
1547 if len(parts) == 1 or not (' ' in parts[1] or '\t' in parts[1]):
1548 #TODO: if parts[1].startswith('-'): handle top-level opts
1549 _log("complete sub-command names")
1550 matches = {}
1551 for name, canon_name in cmd_map.items():
1552 if name.startswith(token):
1553 matches[name] = canon_name
1554 if not matches:
1555 return []
1556 elif len(matches) == 1:
1557 return matches.keys()
1558 elif len(set(matches.values())) == 1:
1559 return [matches.values()[0]]
1560 else:
1561 return matches.keys()
1562
1563 # Otherwise, complete options for the given sub-command.
1564 #TODO: refine this so it does the right thing with option args
1565 if token.startswith('-'):
1566 cmd_name = comp_line.split(None, 2)[1]
1567 try:
1568 cmd_canon_name = cmd_map[cmd_name]
1569 except KeyError:
1570 return []
1571 handler = shell._get_cmd_handler(cmd_canon_name)
1572 optparser = getattr(handler, "optparser", None)
1573 if optparser is None:
1574 optparser = SubCmdOptionParser()
1575 opt_strs = []
1576 for option in optparser.option_list:
1577 for opt_str in option._short_opts + option._long_opts:
1578 if opt_str.startswith(token):
1579 opt_strs.append(opt_str)
1580 return opt_strs
1581
1582 return []
1583
1584 for cpln in _get_bash_cplns(*sys.argv[1:]):
1585 print cpln
1586
diff --git a/scripts/lib/mic/utils/errors.py b/scripts/lib/mic/utils/errors.py
new file mode 100644
index 0000000000..8d720f9080
--- /dev/null
+++ b/scripts/lib/mic/utils/errors.py
@@ -0,0 +1,71 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007 Red Hat, Inc.
4# Copyright (c) 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19class CreatorError(Exception):
20 """An exception base class for all imgcreate errors."""
21 keyword = '<creator>'
22
23 def __init__(self, msg):
24 self.msg = msg
25
26 def __str__(self):
27 if isinstance(self.msg, unicode):
28 self.msg = self.msg.encode('utf-8', 'ignore')
29 else:
30 self.msg = str(self.msg)
31 return self.keyword + self.msg
32
33class Usage(CreatorError):
34 keyword = '<usage>'
35
36 def __str__(self):
37 if isinstance(self.msg, unicode):
38 self.msg = self.msg.encode('utf-8', 'ignore')
39 else:
40 self.msg = str(self.msg)
41 return self.keyword + self.msg + ', please use "--help" for more info'
42
43class Abort(CreatorError):
44 keyword = ''
45
46class ConfigError(CreatorError):
47 keyword = '<config>'
48
49class KsError(CreatorError):
50 keyword = '<kickstart>'
51
52class RepoError(CreatorError):
53 keyword = '<repo>'
54
55class RpmError(CreatorError):
56 keyword = '<rpm>'
57
58class MountError(CreatorError):
59 keyword = '<mount>'
60
61class SnapshotError(CreatorError):
62 keyword = '<snapshot>'
63
64class SquashfsError(CreatorError):
65 keyword = '<squashfs>'
66
67class BootstrapError(CreatorError):
68 keyword = '<bootstrap>'
69
70class RuntimeError(CreatorError):
71 keyword = '<runtime>'
diff --git a/scripts/lib/mic/utils/fs_related.py b/scripts/lib/mic/utils/fs_related.py
new file mode 100644
index 0000000000..dd420e88dc
--- /dev/null
+++ b/scripts/lib/mic/utils/fs_related.py
@@ -0,0 +1,1060 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2007, Red Hat, Inc.
4# Copyright (c) 2009, 2010, 2011 Intel, Inc.
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms of the GNU General Public License as published by the Free
8# Software Foundation; version 2 of the License
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc., 59
17# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19from __future__ import with_statement
20import os
21import sys
22import errno
23import stat
24import random
25import string
26import time
27import uuid
28
29from mic import msger
30from mic.utils import runner
31from mic.utils.errors import *
32from mic.utils.oe.misc import *
33
34def find_binary_inchroot(binary, chroot):
35 paths = ["/usr/sbin",
36 "/usr/bin",
37 "/sbin",
38 "/bin"
39 ]
40
41 for path in paths:
42 bin_path = "%s/%s" % (path, binary)
43 if os.path.exists("%s/%s" % (chroot, bin_path)):
44 return bin_path
45 return None
46
47def find_binary_path(binary):
48 if os.environ.has_key("PATH"):
49 paths = os.environ["PATH"].split(":")
50 else:
51 paths = []
52 if os.environ.has_key("HOME"):
53 paths += [os.environ["HOME"] + "/bin"]
54 paths += ["/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin"]
55
56 for path in paths:
57 bin_path = "%s/%s" % (path, binary)
58 if os.path.exists(bin_path):
59 return bin_path
60
61 print "External command '%s' not found, exiting." % binary
62 print " (Please install '%s' on your host system)" % binary
63 sys.exit(1)
64
65def makedirs(dirname):
66 """A version of os.makedirs() that doesn't throw an
67 exception if the leaf directory already exists.
68 """
69 try:
70 os.makedirs(dirname)
71 except OSError, err:
72 if err.errno != errno.EEXIST:
73 raise
74
75def mksquashfs(in_img, out_img):
76 fullpathmksquashfs = find_binary_path("mksquashfs")
77 args = [fullpathmksquashfs, in_img, out_img]
78
79 if not sys.stdout.isatty():
80 args.append("-no-progress")
81
82 ret = runner.show(args)
83 if ret != 0:
84 raise SquashfsError("'%s' exited with error (%d)" % (' '.join(args), ret))
85
86def resize2fs(fs, size):
87 resize2fs = find_binary_path("resize2fs")
88 if size == 0:
89 # it means to minimalize it
90 return runner.show([resize2fs, '-M', fs])
91 else:
92 return runner.show([resize2fs, fs, "%sK" % (size / 1024,)])
93
94def my_fuser(fp):
95 fuser = find_binary_path("fuser")
96 if not os.path.exists(fp):
97 return False
98
99 rc = runner.quiet([fuser, "-s", fp])
100 if rc == 0:
101 for pid in runner.outs([fuser, fp]).split():
102 fd = open("/proc/%s/cmdline" % pid, "r")
103 cmdline = fd.read()
104 fd.close()
105 if cmdline[:-1] == "/bin/bash":
106 return True
107
108 # not found
109 return False
110
111class BindChrootMount:
112 """Represents a bind mount of a directory into a chroot."""
113 def __init__(self, src, chroot, dest = None, option = None):
114 self.root = os.path.abspath(os.path.expanduser(chroot))
115 self.option = option
116
117 self.orig_src = self.src = src
118 if os.path.islink(src):
119 self.src = os.readlink(src)
120 if not self.src.startswith('/'):
121 self.src = os.path.abspath(os.path.join(os.path.dirname(src),
122 self.src))
123
124 if not dest:
125 dest = self.src
126 self.dest = os.path.join(self.root, dest.lstrip('/'))
127
128 self.mounted = False
129 self.mountcmd = find_binary_path("mount")
130 self.umountcmd = find_binary_path("umount")
131
132 def ismounted(self):
133 with open('/proc/mounts') as f:
134 for line in f:
135 if line.split()[1] == os.path.abspath(self.dest):
136 return True
137
138 return False
139
140 def has_chroot_instance(self):
141 lock = os.path.join(self.root, ".chroot.lock")
142 return my_fuser(lock)
143
144 def mount(self):
145 if self.mounted or self.ismounted():
146 return
147
148 makedirs(self.dest)
149 rc = runner.show([self.mountcmd, "--bind", self.src, self.dest])
150 if rc != 0:
151 raise MountError("Bind-mounting '%s' to '%s' failed" %
152 (self.src, self.dest))
153 if self.option:
154 rc = runner.show([self.mountcmd, "--bind", "-o", "remount,%s" % self.option, self.dest])
155 if rc != 0:
156 raise MountError("Bind-remounting '%s' failed" % self.dest)
157
158 self.mounted = True
159 if os.path.islink(self.orig_src):
160 dest = os.path.join(self.root, self.orig_src.lstrip('/'))
161 if not os.path.exists(dest):
162 os.symlink(self.src, dest)
163
164 def unmount(self):
165 if self.has_chroot_instance():
166 return
167
168 if self.ismounted():
169 runner.show([self.umountcmd, "-l", self.dest])
170 self.mounted = False
171
172class LoopbackMount:
173 """LoopbackMount compatibility layer for old API"""
174 def __init__(self, lofile, mountdir, fstype = None):
175 self.diskmount = DiskMount(LoopbackDisk(lofile,size = 0),mountdir,fstype,rmmountdir = True)
176 self.losetup = False
177 self.losetupcmd = find_binary_path("losetup")
178
179 def cleanup(self):
180 self.diskmount.cleanup()
181
182 def unmount(self):
183 self.diskmount.unmount()
184
185 def lounsetup(self):
186 if self.losetup:
187 runner.show([self.losetupcmd, "-d", self.loopdev])
188 self.losetup = False
189 self.loopdev = None
190
191 def loopsetup(self):
192 if self.losetup:
193 return
194
195 self.loopdev = get_loop_device(self.losetupcmd, self.lofile)
196 self.losetup = True
197
198 def mount(self):
199 self.diskmount.mount()
200
201class SparseLoopbackMount(LoopbackMount):
202 """SparseLoopbackMount compatibility layer for old API"""
203 def __init__(self, lofile, mountdir, size, fstype = None):
204 self.diskmount = DiskMount(SparseLoopbackDisk(lofile,size),mountdir,fstype,rmmountdir = True)
205
206 def expand(self, create = False, size = None):
207 self.diskmount.disk.expand(create, size)
208
209 def truncate(self, size = None):
210 self.diskmount.disk.truncate(size)
211
212 def create(self):
213 self.diskmount.disk.create()
214
215class SparseExtLoopbackMount(SparseLoopbackMount):
216 """SparseExtLoopbackMount compatibility layer for old API"""
217 def __init__(self, lofile, mountdir, size, fstype, blocksize, fslabel):
218 self.diskmount = ExtDiskMount(SparseLoopbackDisk(lofile,size), mountdir, fstype, blocksize, fslabel, rmmountdir = True)
219
220
221 def __format_filesystem(self):
222 self.diskmount.__format_filesystem()
223
224 def create(self):
225 self.diskmount.disk.create()
226
227 def resize(self, size = None):
228 return self.diskmount.__resize_filesystem(size)
229
230 def mount(self):
231 self.diskmount.mount()
232
233 def __fsck(self):
234 self.extdiskmount.__fsck()
235
236 def __get_size_from_filesystem(self):
237 return self.diskmount.__get_size_from_filesystem()
238
239 def __resize_to_minimal(self):
240 return self.diskmount.__resize_to_minimal()
241
242 def resparse(self, size = None):
243 return self.diskmount.resparse(size)
244
245class Disk:
246 """Generic base object for a disk
247
248 The 'create' method must make the disk visible as a block device - eg
249 by calling losetup. For RawDisk, this is obviously a no-op. The 'cleanup'
250 method must undo the 'create' operation.
251 """
252 def __init__(self, size, device = None):
253 self._device = device
254 self._size = size
255
256 def create(self):
257 pass
258
259 def cleanup(self):
260 pass
261
262 def get_device(self):
263 return self._device
264 def set_device(self, path):
265 self._device = path
266 device = property(get_device, set_device)
267
268 def get_size(self):
269 return self._size
270 size = property(get_size)
271
272
273class RawDisk(Disk):
274 """A Disk backed by a block device.
275 Note that create() is a no-op.
276 """
277 def __init__(self, size, device):
278 Disk.__init__(self, size, device)
279
280 def fixed(self):
281 return True
282
283 def exists(self):
284 return True
285
286
287class DiskImage(Disk):
288 """
289 A Disk backed by a file.
290 """
291 def __init__(self, image_file, size):
292 Disk.__init__(self, size)
293 self.image_file = image_file
294
295 def exists(self):
296 return os.path.exists(self.image_file)
297
298 def create(self):
299 if self.device is not None:
300 return
301
302 blocks = self.size / 1024
303 if self.size - blocks * 1024:
304 blocks += 1
305
306 # create disk image
307 dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=1" % \
308 (self.image_file, blocks)
309 rc, out = exec_cmd(dd_cmd)
310
311 self.device = self.image_file
312
313
314class LoopbackDisk(Disk):
315 """A Disk backed by a file via the loop module."""
316 def __init__(self, lofile, size):
317 Disk.__init__(self, size)
318 self.lofile = lofile
319 self.losetupcmd = find_binary_path("losetup")
320
321 def fixed(self):
322 return False
323
324 def exists(self):
325 return os.path.exists(self.lofile)
326
327 def create(self):
328 if self.device is not None:
329 return
330
331 self.device = get_loop_device(self.losetupcmd, self.lofile)
332
333 def cleanup(self):
334 if self.device is None:
335 return
336 msger.debug("Losetup remove %s" % self.device)
337 rc = runner.show([self.losetupcmd, "-d", self.device])
338 self.device = None
339
340class SparseLoopbackDisk(LoopbackDisk):
341 """A Disk backed by a sparse file via the loop module."""
342 def __init__(self, lofile, size):
343 LoopbackDisk.__init__(self, lofile, size)
344
345 def expand(self, create = False, size = None):
346 flags = os.O_WRONLY
347 if create:
348 flags |= os.O_CREAT
349 if not os.path.exists(self.lofile):
350 makedirs(os.path.dirname(self.lofile))
351
352 if size is None:
353 size = self.size
354
355 msger.debug("Extending sparse file %s to %d" % (self.lofile, size))
356 if create:
357 fd = os.open(self.lofile, flags, 0644)
358 else:
359 fd = os.open(self.lofile, flags)
360
361 if size <= 0:
362 size = 1
363 try:
364 os.ftruncate(fd, size)
365 except:
366 # may be limited by 2G in 32bit env
367 os.ftruncate(fd, 2**31L)
368
369 os.close(fd)
370
371 def truncate(self, size = None):
372 if size is None:
373 size = self.size
374
375 msger.debug("Truncating sparse file %s to %d" % (self.lofile, size))
376 fd = os.open(self.lofile, os.O_WRONLY)
377 os.ftruncate(fd, size)
378 os.close(fd)
379
380 def create(self):
381 self.expand(create = True)
382 LoopbackDisk.create(self)
383
384class Mount:
385 """A generic base class to deal with mounting things."""
386 def __init__(self, mountdir):
387 self.mountdir = mountdir
388
389 def cleanup(self):
390 self.unmount()
391
392 def mount(self, options = None):
393 pass
394
395 def unmount(self):
396 pass
397
398class DiskMount(Mount):
399 """A Mount object that handles mounting of a Disk."""
400 def __init__(self, disk, mountdir, fstype = None, rmmountdir = True):
401 Mount.__init__(self, mountdir)
402
403 self.disk = disk
404 self.fstype = fstype
405 self.rmmountdir = rmmountdir
406
407 self.mounted = False
408 self.rmdir = False
409 if fstype:
410 self.mkfscmd = find_binary_path("mkfs." + self.fstype)
411 else:
412 self.mkfscmd = None
413 self.mountcmd = find_binary_path("mount")
414 self.umountcmd = find_binary_path("umount")
415
416 def cleanup(self):
417 Mount.cleanup(self)
418 self.disk.cleanup()
419
420 def unmount(self):
421 if self.mounted:
422 msger.debug("Unmounting directory %s" % self.mountdir)
423 runner.quiet('sync') # sync the data on this mount point
424 rc = runner.show([self.umountcmd, "-l", self.mountdir])
425 if rc == 0:
426 self.mounted = False
427 else:
428 raise MountError("Failed to umount %s" % self.mountdir)
429 if self.rmdir and not self.mounted:
430 try:
431 os.rmdir(self.mountdir)
432 except OSError, e:
433 pass
434 self.rmdir = False
435
436
437 def __create(self):
438 self.disk.create()
439
440
441 def mount(self, options = None):
442 if self.mounted:
443 return
444
445 if not os.path.isdir(self.mountdir):
446 msger.debug("Creating mount point %s" % self.mountdir)
447 os.makedirs(self.mountdir)
448 self.rmdir = self.rmmountdir
449
450 self.__create()
451
452 msger.debug("Mounting %s at %s" % (self.disk.device, self.mountdir))
453 if options:
454 args = [ self.mountcmd, "-o", options, self.disk.device, self.mountdir ]
455 else:
456 args = [ self.mountcmd, self.disk.device, self.mountdir ]
457 if self.fstype:
458 args.extend(["-t", self.fstype])
459
460 rc = runner.show(args)
461 if rc != 0:
462 raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" %
463 (self.disk.device, self.mountdir, " ".join(args), rc))
464
465 self.mounted = True
466
467class ExtDiskMount(DiskMount):
468 """A DiskMount object that is able to format/resize ext[23] filesystems."""
469 def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
470 DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
471 self.blocksize = blocksize
472 self.fslabel = fslabel.replace("/", "")
473 self.uuid = str(uuid.uuid4())
474 self.skipformat = skipformat
475 self.fsopts = fsopts
476 self.extopts = None
477 self.dumpe2fs = find_binary_path("dumpe2fs")
478 self.tune2fs = find_binary_path("tune2fs")
479
480 def __parse_field(self, output, field):
481 for line in output.split("\n"):
482 if line.startswith(field + ":"):
483 return line[len(field) + 1:].strip()
484
485 raise KeyError("Failed to find field '%s' in output" % field)
486
487 def __format_filesystem(self):
488 if self.skipformat:
489 msger.debug("Skip filesystem format.")
490 return
491
492 msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
493 cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b",
494 str(self.blocksize), "-U", self.uuid]
495 if self.extopts:
496 cmdlist.extend(self.extopts.split())
497 cmdlist.extend([self.disk.device])
498
499 rc, errout = runner.runtool(cmdlist, catch=2)
500 if rc != 0:
501 raise MountError("Error creating %s filesystem on disk %s:\n%s" %
502 (self.fstype, self.disk.device, errout))
503
504 if not self.extopts:
505 msger.debug("Tuning filesystem on %s" % self.disk.device)
506 runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
507
508 def __resize_filesystem(self, size = None):
509 current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
510
511 if size is None:
512 size = self.disk.size
513
514 if size == current_size:
515 return
516
517 if size > current_size:
518 self.disk.expand(size)
519
520 self.__fsck()
521
522 resize2fs(self.disk.lofile, size)
523 return size
524
525 def __create(self):
526 resize = False
527 if not self.disk.fixed() and self.disk.exists():
528 resize = True
529
530 self.disk.create()
531
532 if resize:
533 self.__resize_filesystem()
534 else:
535 self.__format_filesystem()
536
537 def mount(self, options = None):
538 self.__create()
539 DiskMount.mount(self, options)
540
541 def __fsck(self):
542 msger.info("Checking filesystem %s" % self.disk.lofile)
543 runner.quiet(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
544
545 def __get_size_from_filesystem(self):
546 return int(self.__parse_field(runner.outs([self.dumpe2fs, '-h', self.disk.lofile]),
547 "Block count")) * self.blocksize
548
549 def __resize_to_minimal(self):
550 self.__fsck()
551
552 #
553 # Use a binary search to find the minimal size
554 # we can resize the image to
555 #
556 bot = 0
557 top = self.__get_size_from_filesystem()
558 while top != (bot + 1):
559 t = bot + ((top - bot) / 2)
560
561 if not resize2fs(self.disk.lofile, t):
562 top = t
563 else:
564 bot = t
565 return top
566
567 def resparse(self, size = None):
568 self.cleanup()
569 if size == 0:
570 minsize = 0
571 else:
572 minsize = self.__resize_to_minimal()
573 self.disk.truncate(minsize)
574
575 self.__resize_filesystem(size)
576 return minsize
577
578class VfatDiskMount(DiskMount):
579 """A DiskMount object that is able to format vfat/msdos filesystems."""
580 def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
581 DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
582 self.blocksize = blocksize
583 self.fslabel = fslabel.replace("/", "")
584 rand1 = random.randint(0, 2**16 - 1)
585 rand2 = random.randint(0, 2**16 - 1)
586 self.uuid = "%04X-%04X" % (rand1, rand2)
587 self.skipformat = skipformat
588 self.fsopts = fsopts
589 self.fsckcmd = find_binary_path("fsck." + self.fstype)
590
591 def __format_filesystem(self):
592 if self.skipformat:
593 msger.debug("Skip filesystem format.")
594 return
595
596 msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
597 rc = runner.show([self.mkfscmd, "-n", self.fslabel,
598 "-i", self.uuid.replace("-", ""), self.disk.device])
599 if rc != 0:
600 raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
601
602 msger.verbose("Tuning filesystem on %s" % self.disk.device)
603
604 def __resize_filesystem(self, size = None):
605 current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
606
607 if size is None:
608 size = self.disk.size
609
610 if size == current_size:
611 return
612
613 if size > current_size:
614 self.disk.expand(size)
615
616 self.__fsck()
617
618 #resize2fs(self.disk.lofile, size)
619 return size
620
621 def __create(self):
622 resize = False
623 if not self.disk.fixed() and self.disk.exists():
624 resize = True
625
626 self.disk.create()
627
628 if resize:
629 self.__resize_filesystem()
630 else:
631 self.__format_filesystem()
632
633 def mount(self, options = None):
634 self.__create()
635 DiskMount.mount(self, options)
636
637 def __fsck(self):
638 msger.debug("Checking filesystem %s" % self.disk.lofile)
639 runner.show([self.fsckcmd, "-y", self.disk.lofile])
640
641 def __get_size_from_filesystem(self):
642 return self.disk.size
643
644 def __resize_to_minimal(self):
645 self.__fsck()
646
647 #
648 # Use a binary search to find the minimal size
649 # we can resize the image to
650 #
651 bot = 0
652 top = self.__get_size_from_filesystem()
653 return top
654
655 def resparse(self, size = None):
656 self.cleanup()
657 minsize = self.__resize_to_minimal()
658 self.disk.truncate(minsize)
659 self.__resize_filesystem(size)
660 return minsize
661
662class BtrfsDiskMount(DiskMount):
663 """A DiskMount object that is able to format/resize btrfs filesystems."""
664 def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
665 self.__check_btrfs()
666 DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
667 self.blocksize = blocksize
668 self.fslabel = fslabel.replace("/", "")
669 self.uuid = None
670 self.skipformat = skipformat
671 self.fsopts = fsopts
672 self.blkidcmd = find_binary_path("blkid")
673 self.btrfsckcmd = find_binary_path("btrfsck")
674
675 def __check_btrfs(self):
676 found = False
677 """ Need to load btrfs module to mount it """
678 load_module("btrfs")
679 for line in open("/proc/filesystems").xreadlines():
680 if line.find("btrfs") > -1:
681 found = True
682 break
683 if not found:
684 raise MountError("Your system can't mount btrfs filesystem, please make sure your kernel has btrfs support and the module btrfs.ko has been loaded.")
685
686 # disable selinux, selinux will block write
687 if os.path.exists("/usr/sbin/setenforce"):
688 runner.show(["/usr/sbin/setenforce", "0"])
689
690 def __parse_field(self, output, field):
691 for line in output.split(" "):
692 if line.startswith(field + "="):
693 return line[len(field) + 1:].strip().replace("\"", "")
694
695 raise KeyError("Failed to find field '%s' in output" % field)
696
697 def __format_filesystem(self):
698 if self.skipformat:
699 msger.debug("Skip filesystem format.")
700 return
701
702 msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
703 rc = runner.show([self.mkfscmd, "-L", self.fslabel, self.disk.device])
704 if rc != 0:
705 raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
706
707 self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
708
709 def __resize_filesystem(self, size = None):
710 current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
711
712 if size is None:
713 size = self.disk.size
714
715 if size == current_size:
716 return
717
718 if size > current_size:
719 self.disk.expand(size)
720
721 self.__fsck()
722 return size
723
724 def __create(self):
725 resize = False
726 if not self.disk.fixed() and self.disk.exists():
727 resize = True
728
729 self.disk.create()
730
731 if resize:
732 self.__resize_filesystem()
733 else:
734 self.__format_filesystem()
735
736 def mount(self, options = None):
737 self.__create()
738 DiskMount.mount(self, options)
739
740 def __fsck(self):
741 msger.debug("Checking filesystem %s" % self.disk.lofile)
742 runner.quiet([self.btrfsckcmd, self.disk.lofile])
743
744 def __get_size_from_filesystem(self):
745 return self.disk.size
746
747 def __resize_to_minimal(self):
748 self.__fsck()
749
750 return self.__get_size_from_filesystem()
751
752 def resparse(self, size = None):
753 self.cleanup()
754 minsize = self.__resize_to_minimal()
755 self.disk.truncate(minsize)
756 self.__resize_filesystem(size)
757 return minsize
758
759class DeviceMapperSnapshot(object):
760 def __init__(self, imgloop, cowloop):
761 self.imgloop = imgloop
762 self.cowloop = cowloop
763
764 self.__created = False
765 self.__name = None
766 self.dmsetupcmd = find_binary_path("dmsetup")
767
768 """Load dm_snapshot if it isn't loaded"""
769 load_module("dm_snapshot")
770
771 def get_path(self):
772 if self.__name is None:
773 return None
774 return os.path.join("/dev/mapper", self.__name)
775 path = property(get_path)
776
777 def create(self):
778 if self.__created:
779 return
780
781 self.imgloop.create()
782 self.cowloop.create()
783
784 self.__name = "imgcreate-%d-%d" % (os.getpid(),
785 random.randint(0, 2**16))
786
787 size = os.stat(self.imgloop.lofile)[stat.ST_SIZE]
788
789 table = "0 %d snapshot %s %s p 8" % (size / 512,
790 self.imgloop.device,
791 self.cowloop.device)
792
793 args = [self.dmsetupcmd, "create", self.__name, "--table", table]
794 if runner.show(args) != 0:
795 self.cowloop.cleanup()
796 self.imgloop.cleanup()
797 raise SnapshotError("Could not create snapshot device using: " + ' '.join(args))
798
799 self.__created = True
800
801 def remove(self, ignore_errors = False):
802 if not self.__created:
803 return
804
805 time.sleep(2)
806 rc = runner.show([self.dmsetupcmd, "remove", self.__name])
807 if not ignore_errors and rc != 0:
808 raise SnapshotError("Could not remove snapshot device")
809
810 self.__name = None
811 self.__created = False
812
813 self.cowloop.cleanup()
814 self.imgloop.cleanup()
815
816 def get_cow_used(self):
817 if not self.__created:
818 return 0
819
820 #
821 # dmsetup status on a snapshot returns e.g.
822 # "0 8388608 snapshot 416/1048576"
823 # or, more generally:
824 # "A B snapshot C/D"
825 # where C is the number of 512 byte sectors in use
826 #
827 out = runner.outs([self.dmsetupcmd, "status", self.__name])
828 try:
829 return int((out.split()[3]).split('/')[0]) * 512
830 except ValueError:
831 raise SnapshotError("Failed to parse dmsetup status: " + out)
832
833def create_image_minimizer(path, image, minimal_size):
834 """
835 Builds a copy-on-write image which can be used to
836 create a device-mapper snapshot of an image where
837 the image's filesystem is as small as possible
838
839 The steps taken are:
840 1) Create a sparse COW
841 2) Loopback mount the image and the COW
842 3) Create a device-mapper snapshot of the image
843 using the COW
844 4) Resize the filesystem to the minimal size
845 5) Determine the amount of space used in the COW
846 6) Restroy the device-mapper snapshot
847 7) Truncate the COW, removing unused space
848 8) Create a squashfs of the COW
849 """
850 imgloop = LoopbackDisk(image, None) # Passing bogus size - doesn't matter
851
852 cowloop = SparseLoopbackDisk(os.path.join(os.path.dirname(path), "osmin"),
853 64L * 1024L * 1024L)
854
855 snapshot = DeviceMapperSnapshot(imgloop, cowloop)
856
857 try:
858 snapshot.create()
859
860 resize2fs(snapshot.path, minimal_size)
861
862 cow_used = snapshot.get_cow_used()
863 finally:
864 snapshot.remove(ignore_errors = (not sys.exc_info()[0] is None))
865
866 cowloop.truncate(cow_used)
867
868 mksquashfs(cowloop.lofile, path)
869
870 os.unlink(cowloop.lofile)
871
872def load_module(module):
873 found = False
874 for line in open('/proc/modules').xreadlines():
875 if line.startswith("%s " % module):
876 found = True
877 break
878 if not found:
879 msger.info("Loading %s..." % module)
880 runner.quiet(['modprobe', module])
881
882class LoopDevice(object):
883 def __init__(self, loopid=None):
884 self.device = None
885 self.loopid = loopid
886 self.created = False
887 self.kpartxcmd = find_binary_path("kpartx")
888 self.losetupcmd = find_binary_path("losetup")
889
890 def register(self, device):
891 self.device = device
892 self.loopid = None
893 self.created = True
894
895 def reg_atexit(self):
896 import atexit
897 atexit.register(self.close)
898
899 def _genloopid(self):
900 import glob
901 if not glob.glob("/dev/loop[0-9]*"):
902 return 10
903
904 fint = lambda x: x[9:].isdigit() and int(x[9:]) or 0
905 maxid = 1 + max(filter(lambda x: x<100,
906 map(fint, glob.glob("/dev/loop[0-9]*"))))
907 if maxid < 10: maxid = 10
908 if maxid >= 100: raise
909 return maxid
910
911 def _kpseek(self, device):
912 rc, out = runner.runtool([self.kpartxcmd, '-l', '-v', device])
913 if rc != 0:
914 raise MountError("Can't query dm snapshot on %s" % device)
915 for line in out.splitlines():
916 if line and line.startswith("loop"):
917 return True
918 return False
919
920 def _loseek(self, device):
921 import re
922 rc, out = runner.runtool([self.losetupcmd, '-a'])
923 if rc != 0:
924 raise MountError("Failed to run 'losetup -a'")
925 for line in out.splitlines():
926 m = re.match("([^:]+): .*", line)
927 if m and m.group(1) == device:
928 return True
929 return False
930
931 def create(self):
932 if not self.created:
933 if not self.loopid:
934 self.loopid = self._genloopid()
935 self.device = "/dev/loop%d" % self.loopid
936 if os.path.exists(self.device):
937 if self._loseek(self.device):
938 raise MountError("Device busy: %s" % self.device)
939 else:
940 self.created = True
941 return
942
943 mknod = find_binary_path('mknod')
944 rc = runner.show([mknod, '-m664', self.device, 'b', '7', str(self.loopid)])
945 if rc != 0:
946 raise MountError("Failed to create device %s" % self.device)
947 else:
948 self.created = True
949
950 def close(self):
951 if self.created:
952 try:
953 self.cleanup()
954 self.device = None
955 except MountError, e:
956 msger.error("%s" % e)
957
958 def cleanup(self):
959
960 if self.device is None:
961 return
962
963
964 if self._kpseek(self.device):
965 if self.created:
966 for i in range(3, os.sysconf("SC_OPEN_MAX")):
967 try:
968 os.close(i)
969 except:
970 pass
971 runner.quiet([self.kpartxcmd, "-d", self.device])
972 if self._loseek(self.device):
973 runner.quiet([self.losetupcmd, "-d", self.device])
974 # FIXME: should sleep a while between two loseek
975 if self._loseek(self.device):
976 msger.warning("Can't cleanup loop device %s" % self.device)
977 elif self.loopid:
978 os.unlink(self.device)
979
980DEVICE_PIDFILE_DIR = "/var/tmp/mic/device"
981DEVICE_LOCKFILE = "/var/lock/__mic_loopdev.lock"
982
983def get_loop_device(losetupcmd, lofile):
984 global DEVICE_PIDFILE_DIR
985 global DEVICE_LOCKFILE
986
987 import fcntl
988 makedirs(os.path.dirname(DEVICE_LOCKFILE))
989 fp = open(DEVICE_LOCKFILE, 'w')
990 fcntl.flock(fp, fcntl.LOCK_EX)
991 try:
992 loopdev = None
993 devinst = LoopDevice()
994
995 # clean up left loop device first
996 clean_loop_devices()
997
998 # provide an avaible loop device
999 rc, out = runner.runtool([losetupcmd, "--find"])
1000 if rc == 0:
1001 loopdev = out.split()[0]
1002 devinst.register(loopdev)
1003 if not loopdev or not os.path.exists(loopdev):
1004 devinst.create()
1005 loopdev = devinst.device
1006
1007 # setup a loop device for image file
1008 rc = runner.show([losetupcmd, loopdev, lofile])
1009 if rc != 0:
1010 raise MountError("Failed to setup loop device for '%s'" % lofile)
1011
1012 devinst.reg_atexit()
1013
1014 # try to save device and pid
1015 makedirs(DEVICE_PIDFILE_DIR)
1016 pidfile = os.path.join(DEVICE_PIDFILE_DIR, os.path.basename(loopdev))
1017 if os.path.exists(pidfile):
1018 os.unlink(pidfile)
1019 with open(pidfile, 'w') as wf:
1020 wf.write(str(os.getpid()))
1021
1022 except MountError, err:
1023 raise CreatorError("%s" % str(err))
1024 except:
1025 raise
1026 finally:
1027 try:
1028 fcntl.flock(fp, fcntl.LOCK_UN)
1029 fp.close()
1030 os.unlink(DEVICE_LOCKFILE)
1031 except:
1032 pass
1033
1034 return loopdev
1035
1036def clean_loop_devices(piddir=DEVICE_PIDFILE_DIR):
1037 if not os.path.exists(piddir) or not os.path.isdir(piddir):
1038 return
1039
1040 for loopdev in os.listdir(piddir):
1041 pidfile = os.path.join(piddir, loopdev)
1042 try:
1043 with open(pidfile, 'r') as rf:
1044 devpid = int(rf.read())
1045 except:
1046 devpid = None
1047
1048 # if the process using this device is alive, skip it
1049 if not devpid or os.path.exists(os.path.join('/proc', str(devpid))):
1050 continue
1051
1052 # try to clean it up
1053 try:
1054 devinst = LoopDevice()
1055 devinst.register(os.path.join('/dev', loopdev))
1056 devinst.cleanup()
1057 os.unlink(pidfile)
1058 except:
1059 pass
1060
diff --git a/scripts/lib/mic/utils/gpt_parser.py b/scripts/lib/mic/utils/gpt_parser.py
new file mode 100644
index 0000000000..5d43b70778
--- /dev/null
+++ b/scripts/lib/mic/utils/gpt_parser.py
@@ -0,0 +1,331 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2013 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18""" This module implements a simple GPT partitions parser which can read the
19GPT header and the GPT partition table. """
20
21import struct
22import uuid
23import binascii
24from mic.utils.errors import MountError
25
26_GPT_HEADER_FORMAT = "<8s4sIIIQQQQ16sQIII"
27_GPT_HEADER_SIZE = struct.calcsize(_GPT_HEADER_FORMAT)
28_GPT_ENTRY_FORMAT = "<16s16sQQQ72s"
29_GPT_ENTRY_SIZE = struct.calcsize(_GPT_ENTRY_FORMAT)
30_SUPPORTED_GPT_REVISION = '\x00\x00\x01\x00'
31
32def _stringify_uuid(binary_uuid):
33 """ A small helper function to transform a binary UUID into a string
34 format. """
35
36 uuid_str = str(uuid.UUID(bytes_le = binary_uuid))
37
38 return uuid_str.upper()
39
40def _calc_header_crc(raw_hdr):
41 """ Calculate GPT header CRC32 checksum. The 'raw_hdr' parameter has to
42 be a list or a tuple containing all the elements of the GPT header in a
43 "raw" form, meaning that it should simply contain "unpacked" disk data.
44 """
45
46 raw_hdr = list(raw_hdr)
47 raw_hdr[3] = 0
48 raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr)
49
50 return binascii.crc32(raw_hdr) & 0xFFFFFFFF
51
52def _validate_header(raw_hdr):
53 """ Validate the GPT header. The 'raw_hdr' parameter has to be a list or a
54 tuple containing all the elements of the GPT header in a "raw" form,
55 meaning that it should simply contain "unpacked" disk data. """
56
57 # Validate the signature
58 if raw_hdr[0] != 'EFI PART':
59 raise MountError("GPT partition table not found")
60
61 # Validate the revision
62 if raw_hdr[1] != _SUPPORTED_GPT_REVISION:
63 raise MountError("Unsupported GPT revision '%s', supported revision " \
64 "is '%s'" % \
65 (binascii.hexlify(raw_hdr[1]),
66 binascii.hexlify(_SUPPORTED_GPT_REVISION)))
67
68 # Validate header size
69 if raw_hdr[2] != _GPT_HEADER_SIZE:
70 raise MountError("Bad GPT header size: %d bytes, expected %d" % \
71 (raw_hdr[2], _GPT_HEADER_SIZE))
72
73 crc = _calc_header_crc(raw_hdr)
74 if raw_hdr[3] != crc:
75 raise MountError("GPT header crc mismatch: %#x, should be %#x" % \
76 (crc, raw_hdr[3]))
77
78class GptParser:
79 """ GPT partition table parser. Allows reading the GPT header and the
80 partition table, as well as modifying the partition table records. """
81
82 def __init__(self, disk_path, sector_size = 512):
83 """ The class constructor which accepts the following parameters:
84 * disk_path - full path to the disk image or device node
85 * sector_size - size of a disk sector in bytes """
86
87 self.sector_size = sector_size
88 self.disk_path = disk_path
89
90 try:
91 self._disk_obj = open(disk_path, 'r+b')
92 except IOError as err:
93 raise MountError("Cannot open file '%s' for reading GPT " \
94 "partitions: %s" % (disk_path, err))
95
96 def __del__(self):
97 """ The class destructor. """
98
99 self._disk_obj.close()
100
101 def _read_disk(self, offset, size):
102 """ A helper function which reads 'size' bytes from offset 'offset' of
103 the disk and checks all the error conditions. """
104
105 self._disk_obj.seek(offset)
106 try:
107 data = self._disk_obj.read(size)
108 except IOError as err:
109 raise MountError("cannot read from '%s': %s" % \
110 (self.disk_path, err))
111
112 if len(data) != size:
113 raise MountError("cannot read %d bytes from offset '%d' of '%s', " \
114 "read only %d bytes" % \
115 (size, offset, self.disk_path, len(data)))
116
117 return data
118
119 def _write_disk(self, offset, buf):
120 """ A helper function which writes buffer 'buf' to offset 'offset' of
121 the disk. This function takes care of unaligned writes and checks all
122 the error conditions. """
123
124 # Since we may be dealing with a block device, we only can write in
125 # 'self.sector_size' chunks. Find the aligned starting and ending
126 # disk offsets to read.
127 start = (offset / self.sector_size) * self.sector_size
128 end = ((start + len(buf)) / self.sector_size + 1) * self.sector_size
129
130 data = self._read_disk(start, end - start)
131 off = offset - start
132 data = data[:off] + buf + data[off + len(buf):]
133
134 self._disk_obj.seek(start)
135 try:
136 self._disk_obj.write(data)
137 except IOError as err:
138 raise MountError("cannot write to '%s': %s" % (self.disk_path, err))
139
140 def read_header(self, primary = True):
141 """ Read and verify the GPT header and return a dictionary containing
142 the following elements:
143
144 'signature' : header signature
145 'revision' : header revision
146 'hdr_size' : header size in bytes
147 'hdr_crc' : header CRC32
148 'hdr_lba' : LBA of this header
149 'hdr_offs' : byte disk offset of this header
150 'backup_lba' : backup header LBA
151 'backup_offs' : byte disk offset of backup header
152 'first_lba' : first usable LBA for partitions
153 'first_offs' : first usable byte disk offset for partitions
154 'last_lba' : last usable LBA for partitions
155 'last_offs' : last usable byte disk offset for partitions
156 'disk_uuid' : UUID of the disk
157 'ptable_lba' : starting LBA of array of partition entries
158 'ptable_offs' : disk byte offset of the start of the partition table
159 'ptable_size' : partition table size in bytes
160 'entries_cnt' : number of available partition table entries
161 'entry_size' : size of a single partition entry
162 'ptable_crc' : CRC32 of the partition table
163 'primary' : a boolean, if 'True', this is the primary GPT header,
164 if 'False' - the secondary
165 'primary_str' : contains string "primary" if this is the primary GPT
166 header, and "backup" otherwise
167
168 This dictionary corresponds to the GPT header format. Please, see the
169 UEFI standard for the description of these fields.
170
171 If the 'primary' parameter is 'True', the primary GPT header is read,
172 otherwise the backup GPT header is read instead. """
173
174 # Read and validate the primary GPT header
175 raw_hdr = self._read_disk(self.sector_size, _GPT_HEADER_SIZE)
176 raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr)
177 _validate_header(raw_hdr)
178 primary_str = "primary"
179
180 if not primary:
181 # Read and validate the backup GPT header
182 raw_hdr = self._read_disk(raw_hdr[6] * self.sector_size, _GPT_HEADER_SIZE)
183 raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr)
184 _validate_header(raw_hdr)
185 primary_str = "backup"
186
187 return { 'signature' : raw_hdr[0],
188 'revision' : raw_hdr[1],
189 'hdr_size' : raw_hdr[2],
190 'hdr_crc' : raw_hdr[3],
191 'hdr_lba' : raw_hdr[5],
192 'hdr_offs' : raw_hdr[5] * self.sector_size,
193 'backup_lba' : raw_hdr[6],
194 'backup_offs' : raw_hdr[6] * self.sector_size,
195 'first_lba' : raw_hdr[7],
196 'first_offs' : raw_hdr[7] * self.sector_size,
197 'last_lba' : raw_hdr[8],
198 'last_offs' : raw_hdr[8] * self.sector_size,
199 'disk_uuid' :_stringify_uuid(raw_hdr[9]),
200 'ptable_lba' : raw_hdr[10],
201 'ptable_offs' : raw_hdr[10] * self.sector_size,
202 'ptable_size' : raw_hdr[11] * raw_hdr[12],
203 'entries_cnt' : raw_hdr[11],
204 'entry_size' : raw_hdr[12],
205 'ptable_crc' : raw_hdr[13],
206 'primary' : primary,
207 'primary_str' : primary_str }
208
209 def _read_raw_ptable(self, header):
210 """ Read and validate primary or backup partition table. The 'header'
211 argument is the GPT header. If it is the primary GPT header, then the
212 primary partition table is read and validated, otherwise - the backup
213 one. The 'header' argument is a dictionary which is returned by the
214 'read_header()' method. """
215
216 raw_ptable = self._read_disk(header['ptable_offs'],
217 header['ptable_size'])
218
219 crc = binascii.crc32(raw_ptable) & 0xFFFFFFFF
220 if crc != header['ptable_crc']:
221 raise MountError("Partition table at LBA %d (%s) is corrupted" % \
222 (header['ptable_lba'], header['primary_str']))
223
224 return raw_ptable
225
226 def get_partitions(self, primary = True):
227 """ This is a generator which parses the GPT partition table and
228 generates the following dictionary for each partition:
229
230 'index' : the index of the partition table endry
231 'offs' : byte disk offset of the partition table entry
232 'type_uuid' : partition type UUID
233 'part_uuid' : partition UUID
234 'first_lba' : the first LBA
235 'last_lba' : the last LBA
236 'flags' : attribute flags
237 'name' : partition name
238 'primary' : a boolean, if 'True', this is the primary partition
239 table, if 'False' - the secondary
240 'primary_str' : contains string "primary" if this is the primary GPT
241 header, and "backup" otherwise
242
243 This dictionary corresponds to the GPT header format. Please, see the
244 UEFI standard for the description of these fields.
245
246 If the 'primary' parameter is 'True', partitions from the primary GPT
247 partition table are generated, otherwise partitions from the backup GPT
248 partition table are generated. """
249
250 if primary:
251 primary_str = "primary"
252 else:
253 primary_str = "backup"
254
255 header = self.read_header(primary)
256 raw_ptable = self._read_raw_ptable(header)
257
258 for index in xrange(0, header['entries_cnt']):
259 start = header['entry_size'] * index
260 end = start + header['entry_size']
261 raw_entry = struct.unpack(_GPT_ENTRY_FORMAT, raw_ptable[start:end])
262
263 if raw_entry[2] == 0 or raw_entry[3] == 0:
264 continue
265
266 part_name = str(raw_entry[5].decode('UTF-16').split('\0', 1)[0])
267
268 yield { 'index' : index,
269 'offs' : header['ptable_offs'] + start,
270 'type_uuid' : _stringify_uuid(raw_entry[0]),
271 'part_uuid' : _stringify_uuid(raw_entry[1]),
272 'first_lba' : raw_entry[2],
273 'last_lba' : raw_entry[3],
274 'flags' : raw_entry[4],
275 'name' : part_name,
276 'primary' : primary,
277 'primary_str' : primary_str }
278
279 def _change_partition(self, header, entry):
280 """ A helper function for 'change_partitions()' which changes a
281 a paricular instance of the partition table (primary or backup). """
282
283 if entry['index'] >= header['entries_cnt']:
284 raise MountError("Partition table at LBA %d has only %d " \
285 "records cannot change record number %d" % \
286 (header['entries_cnt'], entry['index']))
287 # Read raw GPT header
288 raw_hdr = self._read_disk(header['hdr_offs'], _GPT_HEADER_SIZE)
289 raw_hdr = list(struct.unpack(_GPT_HEADER_FORMAT, raw_hdr))
290 _validate_header(raw_hdr)
291
292 # Prepare the new partition table entry
293 raw_entry = struct.pack(_GPT_ENTRY_FORMAT,
294 uuid.UUID(entry['type_uuid']).bytes_le,
295 uuid.UUID(entry['part_uuid']).bytes_le,
296 entry['first_lba'],
297 entry['last_lba'],
298 entry['flags'],
299 entry['name'].encode('UTF-16'))
300
301 # Write the updated entry to the disk
302 entry_offs = header['ptable_offs'] + \
303 header['entry_size'] * entry['index']
304 self._write_disk(entry_offs, raw_entry)
305
306 # Calculate and update partition table CRC32
307 raw_ptable = self._read_disk(header['ptable_offs'],
308 header['ptable_size'])
309 raw_hdr[13] = binascii.crc32(raw_ptable) & 0xFFFFFFFF
310
311 # Calculate and update the GPT header CRC
312 raw_hdr[3] = _calc_header_crc(raw_hdr)
313
314 # Write the updated header to the disk
315 raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr)
316 self._write_disk(header['hdr_offs'], raw_hdr)
317
318 def change_partition(self, entry):
319 """ Change a GPT partition. The 'entry' argument has the same format as
320 'get_partitions()' returns. This function simply changes the partition
321 table record corresponding to 'entry' in both, the primary and the
322 backup GPT partition tables. The parition table CRC is re-calculated
323 and the GPT headers are modified accordingly. """
324
325 # Change the primary partition table
326 header = self.read_header(True)
327 self._change_partition(header, entry)
328
329 # Change the backup partition table
330 header = self.read_header(False)
331 self._change_partition(header, entry)
diff --git a/scripts/lib/mic/utils/grabber.py b/scripts/lib/mic/utils/grabber.py
new file mode 100644
index 0000000000..45e30b4fb0
--- /dev/null
+++ b/scripts/lib/mic/utils/grabber.py
@@ -0,0 +1,97 @@
1#!/usr/bin/python
2
3import os
4import sys
5import rpm
6import fcntl
7import struct
8import termios
9
10from mic import msger
11from mic.utils import runner
12from mic.utils.errors import CreatorError
13
14from urlgrabber import grabber
15from urlgrabber import __version__ as grabber_version
16
17if rpm.labelCompare(grabber_version.split('.'), '3.9.0'.split('.')) == -1:
18 msger.warning("Version of python-urlgrabber is %s, lower than '3.9.0', "
19 "you may encounter some network issues" % grabber_version)
20
21def myurlgrab(url, filename, proxies, progress_obj = None):
22 g = grabber.URLGrabber()
23 if progress_obj is None:
24 progress_obj = TextProgress()
25
26 if url.startswith("file:/"):
27 filepath = "/%s" % url.replace("file:", "").lstrip('/')
28 if not os.path.exists(filepath):
29 raise CreatorError("URLGrabber error: can't find file %s" % url)
30 if url.endswith('.rpm'):
31 return filepath
32 else:
33 # untouch repometadata in source path
34 runner.show(['cp', '-f', filepath, filename])
35
36 else:
37 try:
38 filename = g.urlgrab(url=str(url),
39 filename=filename,
40 ssl_verify_host=False,
41 ssl_verify_peer=False,
42 proxies=proxies,
43 http_headers=(('Pragma', 'no-cache'),),
44 quote=0,
45 progress_obj=progress_obj)
46 except grabber.URLGrabError, err:
47 msg = str(err)
48 if msg.find(url) < 0:
49 msg += ' on %s' % url
50 raise CreatorError(msg)
51
52 return filename
53
54def terminal_width(fd=1):
55 """ Get the real terminal width """
56 try:
57 buf = 'abcdefgh'
58 buf = fcntl.ioctl(fd, termios.TIOCGWINSZ, buf)
59 return struct.unpack('hhhh', buf)[1]
60 except: # IOError
61 return 80
62
63def truncate_url(url, width):
64 return os.path.basename(url)[0:width]
65
66class TextProgress(object):
67 # make the class as singleton
68 _instance = None
69 def __new__(cls, *args, **kwargs):
70 if not cls._instance:
71 cls._instance = super(TextProgress, cls).__new__(cls, *args, **kwargs)
72
73 return cls._instance
74
75 def __init__(self, totalnum = None):
76 self.total = totalnum
77 self.counter = 1
78
79 def start(self, filename, url, *args, **kwargs):
80 self.url = url
81 self.termwidth = terminal_width()
82 msger.info("\r%-*s" % (self.termwidth, " "))
83 if self.total is None:
84 msger.info("\rRetrieving %s ..." % truncate_url(self.url, self.termwidth - 15))
85 else:
86 msger.info("\rRetrieving %s [%d/%d] ..." % (truncate_url(self.url, self.termwidth - 25), self.counter, self.total))
87
88 def update(self, *args):
89 pass
90
91 def end(self, *args):
92 if self.counter == self.total:
93 msger.raw("\n")
94
95 if self.total is not None:
96 self.counter += 1
97
diff --git a/scripts/lib/mic/utils/misc.py b/scripts/lib/mic/utils/misc.py
new file mode 100644
index 0000000000..95241d7f15
--- /dev/null
+++ b/scripts/lib/mic/utils/misc.py
@@ -0,0 +1,1065 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2010, 2011 Intel Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import sys
20import time
21import tempfile
22import re
23import shutil
24import glob
25import hashlib
26import subprocess
27import platform
28import traceback
29
30
31try:
32 import sqlite3 as sqlite
33except ImportError:
34 import sqlite
35
36try:
37 from xml.etree import cElementTree
38except ImportError:
39 import cElementTree
40xmlparse = cElementTree.parse
41
42from mic import msger
43from mic.utils.errors import CreatorError, SquashfsError
44from mic.utils.fs_related import find_binary_path, makedirs
45from mic.utils.proxy import get_proxy_for
46from mic.utils import runner
47
48
49RPM_RE = re.compile("(.*)\.(.*) (.*)-(.*)")
50RPM_FMT = "%(name)s.%(arch)s %(version)s-%(release)s"
51SRPM_RE = re.compile("(.*)-(\d+.*)-(\d+\.\d+).src.rpm")
52
53
54def build_name(kscfg, release=None, prefix = None, suffix = None):
55 """Construct and return an image name string.
56
57 This is a utility function to help create sensible name and fslabel
58 strings. The name is constructed using the sans-prefix-and-extension
59 kickstart filename and the supplied prefix and suffix.
60
61 kscfg -- a path to a kickstart file
62 release -- a replacement to suffix for image release
63 prefix -- a prefix to prepend to the name; defaults to None, which causes
64 no prefix to be used
65 suffix -- a suffix to append to the name; defaults to None, which causes
66 a YYYYMMDDHHMM suffix to be used
67
68 Note, if maxlen is less then the len(suffix), you get to keep both pieces.
69
70 """
71 name = os.path.basename(kscfg)
72 idx = name.rfind('.')
73 if idx >= 0:
74 name = name[:idx]
75
76 if release is not None:
77 suffix = ""
78 if prefix is None:
79 prefix = ""
80 if suffix is None:
81 suffix = time.strftime("%Y%m%d%H%M")
82
83 if name.startswith(prefix):
84 name = name[len(prefix):]
85
86 prefix = "%s-" % prefix if prefix else ""
87 suffix = "-%s" % suffix if suffix else ""
88
89 ret = prefix + name + suffix
90 return ret
91
92def get_distro():
93 """Detect linux distribution, support "meego"
94 """
95
96 support_dists = ('SuSE',
97 'debian',
98 'fedora',
99 'redhat',
100 'centos',
101 'meego',
102 'moblin',
103 'tizen')
104 try:
105 (dist, ver, id) = platform.linux_distribution( \
106 supported_dists = support_dists)
107 except:
108 (dist, ver, id) = platform.dist( \
109 supported_dists = support_dists)
110
111 return (dist, ver, id)
112
113def get_distro_str():
114 """Get composited string for current linux distribution
115 """
116 (dist, ver, id) = get_distro()
117
118 if not dist:
119 return 'Unknown Linux Distro'
120 else:
121 distro_str = ' '.join(map(str.strip, (dist, ver, id)))
122 return distro_str.strip()
123
124_LOOP_RULE_PTH = None
125
126def hide_loopdev_presentation():
127 udev_rules = "80-prevent-loop-present.rules"
128 udev_rules_dir = [
129 '/usr/lib/udev/rules.d/',
130 '/lib/udev/rules.d/',
131 '/etc/udev/rules.d/'
132 ]
133
134 global _LOOP_RULE_PTH
135
136 for rdir in udev_rules_dir:
137 if os.path.exists(rdir):
138 _LOOP_RULE_PTH = os.path.join(rdir, udev_rules)
139
140 if not _LOOP_RULE_PTH:
141 return
142
143 try:
144 with open(_LOOP_RULE_PTH, 'w') as wf:
145 wf.write('KERNEL=="loop*", ENV{UDISKS_PRESENTATION_HIDE}="1"')
146
147 runner.quiet('udevadm trigger')
148 except:
149 pass
150
151def unhide_loopdev_presentation():
152 global _LOOP_RULE_PTH
153
154 if not _LOOP_RULE_PTH:
155 return
156
157 try:
158 os.unlink(_LOOP_RULE_PTH)
159 runner.quiet('udevadm trigger')
160 except:
161 pass
162
163def extract_rpm(rpmfile, targetdir):
164 rpm2cpio = find_binary_path("rpm2cpio")
165 cpio = find_binary_path("cpio")
166
167 olddir = os.getcwd()
168 os.chdir(targetdir)
169
170 msger.verbose("Extract rpm file with cpio: %s" % rpmfile)
171 p1 = subprocess.Popen([rpm2cpio, rpmfile], stdout=subprocess.PIPE)
172 p2 = subprocess.Popen([cpio, "-idv"], stdin=p1.stdout,
173 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
174 (sout, serr) = p2.communicate()
175 msger.verbose(sout or serr)
176
177 os.chdir(olddir)
178
179def compressing(fpath, method):
180 comp_map = {
181 "gz": "gzip",
182 "bz2": "bzip2"
183 }
184 if method not in comp_map:
185 raise CreatorError("Unsupport compress format: %s, valid values: %s"
186 % (method, ','.join(comp_map.keys())))
187 cmd = find_binary_path(comp_map[method])
188 rc = runner.show([cmd, "-f", fpath])
189 if rc:
190 raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
191
192def taring(dstfile, target):
193 import tarfile
194 basen, ext = os.path.splitext(dstfile)
195 comp = {".tar": None,
196 ".gz": "gz", # for .tar.gz
197 ".bz2": "bz2", # for .tar.bz2
198 ".tgz": "gz",
199 ".tbz": "bz2"}[ext]
200
201 # specify tarball file path
202 if not comp:
203 tarpath = dstfile
204 elif basen.endswith(".tar"):
205 tarpath = basen
206 else:
207 tarpath = basen + ".tar"
208 wf = tarfile.open(tarpath, 'w')
209
210 if os.path.isdir(target):
211 for item in os.listdir(target):
212 wf.add(os.path.join(target, item), item)
213 else:
214 wf.add(target, os.path.basename(target))
215 wf.close()
216
217 if comp:
218 compressing(tarpath, comp)
219 # when dstfile ext is ".tgz" and ".tbz", should rename
220 if not basen.endswith(".tar"):
221 shutil.move("%s.%s" % (tarpath, comp), dstfile)
222
223def ziping(dstfile, target):
224 import zipfile
225 wf = zipfile.ZipFile(dstfile, 'w', compression=zipfile.ZIP_DEFLATED)
226 if os.path.isdir(target):
227 for item in os.listdir(target):
228 fpath = os.path.join(target, item)
229 if not os.path.isfile(fpath):
230 continue
231 wf.write(fpath, item, zipfile.ZIP_DEFLATED)
232 else:
233 wf.write(target, os.path.basename(target), zipfile.ZIP_DEFLATED)
234 wf.close()
235
236pack_formats = {
237 ".tar": taring,
238 ".tar.gz": taring,
239 ".tar.bz2": taring,
240 ".tgz": taring,
241 ".tbz": taring,
242 ".zip": ziping,
243}
244
245def packing(dstfile, target):
246 (base, ext) = os.path.splitext(dstfile)
247 if ext in (".gz", ".bz2") and base.endswith(".tar"):
248 ext = ".tar" + ext
249 if ext not in pack_formats:
250 raise CreatorError("Unsupport pack format: %s, valid values: %s"
251 % (ext, ','.join(pack_formats.keys())))
252 func = pack_formats[ext]
253 # func should be callable
254 func(dstfile, target)
255
256def human_size(size):
257 """Return human readable string for Bytes size
258 """
259
260 if size <= 0:
261 return "0M"
262 import math
263 measure = ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
264 expo = int(math.log(size, 1024))
265 mant = float(size/math.pow(1024, expo))
266 return "{0:.1f}{1:s}".format(mant, measure[expo])
267
268def get_block_size(file_obj):
269 """ Returns block size for file object 'file_obj'. Errors are indicated by
270 the 'IOError' exception. """
271
272 from fcntl import ioctl
273 import struct
274
275 # Get the block size of the host file-system for the image file by calling
276 # the FIGETBSZ ioctl (number 2).
277 binary_data = ioctl(file_obj, 2, struct.pack('I', 0))
278 return struct.unpack('I', binary_data)[0]
279
280def check_space_pre_cp(src, dst):
281 """Check whether disk space is enough before 'cp' like
282 operations, else exception will be raised.
283 """
284
285 srcsize = get_file_size(src) * 1024 * 1024
286 freesize = get_filesystem_avail(dst)
287 if srcsize > freesize:
288 raise CreatorError("space on %s(%s) is not enough for about %s files"
289 % (dst, human_size(freesize), human_size(srcsize)))
290
291def calc_hashes(file_path, hash_names, start = 0, end = None):
292 """ Calculate hashes for a file. The 'file_path' argument is the file
293 to calculate hash functions for, 'start' and 'end' are the starting and
294 ending file offset to calculate the has functions for. The 'hash_names'
295 argument is a list of hash names to calculate. Returns the the list
296 of calculated hash values in the hexadecimal form in the same order
297 as 'hash_names'.
298 """
299 if end == None:
300 end = os.path.getsize(file_path)
301
302 chunk_size = 65536
303 to_read = end - start
304 read = 0
305
306 hashes = []
307 for hash_name in hash_names:
308 hashes.append(hashlib.new(hash_name))
309
310 with open(file_path, "rb") as f:
311 f.seek(start)
312
313 while read < to_read:
314 if read + chunk_size > to_read:
315 chunk_size = to_read - read
316 chunk = f.read(chunk_size)
317 for hash_obj in hashes:
318 hash_obj.update(chunk)
319 read += chunk_size
320
321 result = []
322 for hash_obj in hashes:
323 result.append(hash_obj.hexdigest())
324
325 return result
326
327def get_md5sum(fpath):
328 return calc_hashes(fpath, ('md5', ))[0]
329
330
331def normalize_ksfile(ksconf, release, arch):
332 '''
333 Return the name of a normalized ks file in which macro variables
334 @BUILD_ID@ and @ARCH@ are replace with real values.
335
336 The original ks file is returned if no special macro is used, otherwise
337 a temp file is created and returned, which will be deleted when program
338 exits normally.
339 '''
340
341 if not release:
342 release = "latest"
343 if not arch or re.match(r'i.86', arch):
344 arch = "ia32"
345
346 with open(ksconf) as f:
347 ksc = f.read()
348
349 if "@ARCH@" not in ksc and "@BUILD_ID@" not in ksc:
350 return ksconf
351
352 msger.info("Substitute macro variable @BUILD_ID@/@ARCH@ in ks: %s" % ksconf)
353 ksc = ksc.replace("@ARCH@", arch)
354 ksc = ksc.replace("@BUILD_ID@", release)
355
356 fd, ksconf = tempfile.mkstemp(prefix=os.path.basename(ksconf))
357 os.write(fd, ksc)
358 os.close(fd)
359
360 msger.debug('normalized ks file:%s' % ksconf)
361
362 def remove_temp_ks():
363 try:
364 os.unlink(ksconf)
365 except OSError, err:
366 msger.warning('Failed to remove temp ks file:%s:%s' % (ksconf, err))
367
368 import atexit
369 atexit.register(remove_temp_ks)
370
371 return ksconf
372
373
374def _check_mic_chroot(rootdir):
375 def _path(path):
376 return rootdir.rstrip('/') + path
377
378 release_files = map(_path, [ "/etc/moblin-release",
379 "/etc/meego-release",
380 "/etc/tizen-release"])
381
382 if not any(map(os.path.exists, release_files)):
383 msger.warning("Dir %s is not a MeeGo/Tizen chroot env" % rootdir)
384
385 if not glob.glob(rootdir + "/boot/vmlinuz-*"):
386 msger.warning("Failed to find kernel module under %s" % rootdir)
387
388 return
389
390def selinux_check(arch, fstypes):
391 try:
392 getenforce = find_binary_path('getenforce')
393 except CreatorError:
394 return
395
396 selinux_status = runner.outs([getenforce])
397 if arch and arch.startswith("arm") and selinux_status == "Enforcing":
398 raise CreatorError("Can't create arm image if selinux is enabled, "
399 "please run 'setenforce 0' to disable selinux")
400
401 use_btrfs = filter(lambda typ: typ == 'btrfs', fstypes)
402 if use_btrfs and selinux_status == "Enforcing":
403 raise CreatorError("Can't create btrfs image if selinux is enabled,"
404 " please run 'setenforce 0' to disable selinux")
405
406def get_image_type(path):
407 def _get_extension_name(path):
408 match = re.search("(?<=\.)\w+$", path)
409 if match:
410 return match.group(0)
411 else:
412 return None
413
414 if os.path.isdir(path):
415 _check_mic_chroot(path)
416 return "fs"
417
418 maptab = {
419 "tar": "loop",
420 "raw":"raw",
421 "vmdk":"vmdk",
422 "vdi":"vdi",
423 "iso":"livecd",
424 "usbimg":"liveusb",
425 }
426
427 extension = _get_extension_name(path)
428 if extension in maptab:
429 return maptab[extension]
430
431 fd = open(path, "rb")
432 file_header = fd.read(1024)
433 fd.close()
434 vdi_flag = "<<< Sun VirtualBox Disk Image >>>"
435 if file_header[0:len(vdi_flag)] == vdi_flag:
436 return maptab["vdi"]
437
438 output = runner.outs(['file', path])
439 isoptn = re.compile(r".*ISO 9660 CD-ROM filesystem.*(bootable).*")
440 usbimgptn = re.compile(r".*x86 boot sector.*active.*")
441 rawptn = re.compile(r".*x86 boot sector.*")
442 vmdkptn = re.compile(r".*VMware. disk image.*")
443 ext3fsimgptn = re.compile(r".*Linux.*ext3 filesystem data.*")
444 ext4fsimgptn = re.compile(r".*Linux.*ext4 filesystem data.*")
445 btrfsimgptn = re.compile(r".*BTRFS.*")
446 if isoptn.match(output):
447 return maptab["iso"]
448 elif usbimgptn.match(output):
449 return maptab["usbimg"]
450 elif rawptn.match(output):
451 return maptab["raw"]
452 elif vmdkptn.match(output):
453 return maptab["vmdk"]
454 elif ext3fsimgptn.match(output):
455 return "ext3fsimg"
456 elif ext4fsimgptn.match(output):
457 return "ext4fsimg"
458 elif btrfsimgptn.match(output):
459 return "btrfsimg"
460 else:
461 raise CreatorError("Cannot detect the type of image: %s" % path)
462
463
464def get_file_size(filename):
465 """ Return size in MB unit """
466 cmd = ['du', "-s", "-b", "-B", "1M", filename]
467 rc, duOutput = runner.runtool(cmd)
468 if rc != 0:
469 raise CreatorError("Failed to run: %s" % ' '.join(cmd))
470 size1 = int(duOutput.split()[0])
471
472 cmd = ['du', "-s", "-B", "1M", filename]
473 rc, duOutput = runner.runtool(cmd)
474 if rc != 0:
475 raise CreatorError("Failed to run: %s" % ' '.join(cmd))
476
477 size2 = int(duOutput.split()[0])
478 return max(size1, size2)
479
480
481def get_filesystem_avail(fs):
482 vfstat = os.statvfs(fs)
483 return vfstat.f_bavail * vfstat.f_bsize
484
485def convert_image(srcimg, srcfmt, dstimg, dstfmt):
486 #convert disk format
487 if dstfmt != "raw":
488 raise CreatorError("Invalid destination image format: %s" % dstfmt)
489 msger.debug("converting %s image to %s" % (srcimg, dstimg))
490 if srcfmt == "vmdk":
491 path = find_binary_path("qemu-img")
492 argv = [path, "convert", "-f", "vmdk", srcimg, "-O", dstfmt, dstimg]
493 elif srcfmt == "vdi":
494 path = find_binary_path("VBoxManage")
495 argv = [path, "internalcommands", "converttoraw", srcimg, dstimg]
496 else:
497 raise CreatorError("Invalid soure image format: %s" % srcfmt)
498
499 rc = runner.show(argv)
500 if rc == 0:
501 msger.debug("convert successful")
502 if rc != 0:
503 raise CreatorError("Unable to convert disk to %s" % dstfmt)
504
505def uncompress_squashfs(squashfsimg, outdir):
506 """Uncompress file system from squshfs image"""
507 unsquashfs = find_binary_path("unsquashfs")
508 args = [ unsquashfs, "-d", outdir, squashfsimg ]
509 rc = runner.show(args)
510 if (rc != 0):
511 raise SquashfsError("Failed to uncompress %s." % squashfsimg)
512
513def mkdtemp(dir = "/var/tmp", prefix = "wic-tmp-"):
514 """ FIXME: use the dir in wic.conf instead """
515
516 makedirs(dir)
517 return tempfile.mkdtemp(dir = dir, prefix = prefix)
518
519def get_repostrs_from_ks(ks):
520 def _get_temp_reponame(baseurl):
521 md5obj = hashlib.md5(baseurl)
522 tmpreponame = "%s" % md5obj.hexdigest()
523 return tmpreponame
524
525 kickstart_repos = []
526
527 for repodata in ks.handler.repo.repoList:
528 repo = {}
529 for attr in ('name',
530 'baseurl',
531 'mirrorlist',
532 'includepkgs', # val is list
533 'excludepkgs', # val is list
534 'cost', # int
535 'priority',# int
536 'save',
537 'proxy',
538 'proxyuser',
539 'proxypasswd',
540 'proxypasswd',
541 'debuginfo',
542 'source',
543 'gpgkey',
544 'ssl_verify'):
545 if hasattr(repodata, attr) and getattr(repodata, attr):
546 repo[attr] = getattr(repodata, attr)
547
548 if 'name' not in repo:
549 repo['name'] = _get_temp_reponame(repodata.baseurl)
550
551 kickstart_repos.append(repo)
552
553 return kickstart_repos
554
555def _get_uncompressed_data_from_url(url, filename, proxies):
556 filename = myurlgrab(url, filename, proxies)
557 suffix = None
558 if filename.endswith(".gz"):
559 suffix = ".gz"
560 runner.quiet(['gunzip', "-f", filename])
561 elif filename.endswith(".bz2"):
562 suffix = ".bz2"
563 runner.quiet(['bunzip2', "-f", filename])
564 if suffix:
565 filename = filename.replace(suffix, "")
566 return filename
567
568def _get_metadata_from_repo(baseurl, proxies, cachedir, reponame, filename,
569 sumtype=None, checksum=None):
570 url = os.path.join(baseurl, filename)
571 filename_tmp = str("%s/%s/%s" % (cachedir, reponame, os.path.basename(filename)))
572 if os.path.splitext(filename_tmp)[1] in (".gz", ".bz2"):
573 filename = os.path.splitext(filename_tmp)[0]
574 else:
575 filename = filename_tmp
576 if sumtype and checksum and os.path.exists(filename):
577 try:
578 sumcmd = find_binary_path("%ssum" % sumtype)
579 except:
580 file_checksum = None
581 else:
582 file_checksum = runner.outs([sumcmd, filename]).split()[0]
583
584 if file_checksum and file_checksum == checksum:
585 return filename
586
587 return _get_uncompressed_data_from_url(url,filename_tmp,proxies)
588
589def get_metadata_from_repos(repos, cachedir):
590 my_repo_metadata = []
591 for repo in repos:
592 reponame = repo['name']
593 baseurl = repo['baseurl']
594
595
596 if 'proxy' in repo:
597 proxy = repo['proxy']
598 else:
599 proxy = get_proxy_for(baseurl)
600
601 proxies = None
602 if proxy:
603 proxies = {str(baseurl.split(":")[0]):str(proxy)}
604
605 makedirs(os.path.join(cachedir, reponame))
606 url = os.path.join(baseurl, "repodata/repomd.xml")
607 filename = os.path.join(cachedir, reponame, 'repomd.xml')
608 repomd = myurlgrab(url, filename, proxies)
609 try:
610 root = xmlparse(repomd)
611 except SyntaxError:
612 raise CreatorError("repomd.xml syntax error.")
613
614 ns = root.getroot().tag
615 ns = ns[0:ns.rindex("}")+1]
616
617 filepaths = {}
618 checksums = {}
619 sumtypes = {}
620
621 for elm in root.getiterator("%sdata" % ns):
622 if elm.attrib["type"] == "patterns":
623 filepaths['patterns'] = elm.find("%slocation" % ns).attrib['href']
624 checksums['patterns'] = elm.find("%sopen-checksum" % ns).text
625 sumtypes['patterns'] = elm.find("%sopen-checksum" % ns).attrib['type']
626 break
627
628 for elm in root.getiterator("%sdata" % ns):
629 if elm.attrib["type"] in ("group_gz", "group"):
630 filepaths['comps'] = elm.find("%slocation" % ns).attrib['href']
631 checksums['comps'] = elm.find("%sopen-checksum" % ns).text
632 sumtypes['comps'] = elm.find("%sopen-checksum" % ns).attrib['type']
633 break
634
635 primary_type = None
636 for elm in root.getiterator("%sdata" % ns):
637 if elm.attrib["type"] in ("primary_db", "primary"):
638 primary_type = elm.attrib["type"]
639 filepaths['primary'] = elm.find("%slocation" % ns).attrib['href']
640 checksums['primary'] = elm.find("%sopen-checksum" % ns).text
641 sumtypes['primary'] = elm.find("%sopen-checksum" % ns).attrib['type']
642 break
643
644 if not primary_type:
645 continue
646
647 for item in ("primary", "patterns", "comps"):
648 if item not in filepaths:
649 filepaths[item] = None
650 continue
651 if not filepaths[item]:
652 continue
653 filepaths[item] = _get_metadata_from_repo(baseurl,
654 proxies,
655 cachedir,
656 reponame,
657 filepaths[item],
658 sumtypes[item],
659 checksums[item])
660
661 """ Get repo key """
662 try:
663 repokey = _get_metadata_from_repo(baseurl,
664 proxies,
665 cachedir,
666 reponame,
667 "repodata/repomd.xml.key")
668 except CreatorError:
669 repokey = None
670 msger.debug("\ncan't get %s/%s" % (baseurl, "repodata/repomd.xml.key"))
671
672 my_repo_metadata.append({"name":reponame,
673 "baseurl":baseurl,
674 "repomd":repomd,
675 "primary":filepaths['primary'],
676 "cachedir":cachedir,
677 "proxies":proxies,
678 "patterns":filepaths['patterns'],
679 "comps":filepaths['comps'],
680 "repokey":repokey})
681
682 return my_repo_metadata
683
684def get_rpmver_in_repo(repometadata):
685 for repo in repometadata:
686 if repo["primary"].endswith(".xml"):
687 root = xmlparse(repo["primary"])
688 ns = root.getroot().tag
689 ns = ns[0:ns.rindex("}")+1]
690
691 versionlist = []
692 for elm in root.getiterator("%spackage" % ns):
693 if elm.find("%sname" % ns).text == 'rpm':
694 for node in elm.getchildren():
695 if node.tag == "%sversion" % ns:
696 versionlist.append(node.attrib['ver'])
697
698 if versionlist:
699 return reversed(
700 sorted(
701 versionlist,
702 key = lambda ver: map(int, ver.split('.')))).next()
703
704 elif repo["primary"].endswith(".sqlite"):
705 con = sqlite.connect(repo["primary"])
706 for row in con.execute("select version from packages where "
707 "name=\"rpm\" ORDER by version DESC"):
708 con.close()
709 return row[0]
710
711 return None
712
713def get_arch(repometadata):
714 archlist = []
715 for repo in repometadata:
716 if repo["primary"].endswith(".xml"):
717 root = xmlparse(repo["primary"])
718 ns = root.getroot().tag
719 ns = ns[0:ns.rindex("}")+1]
720 for elm in root.getiterator("%spackage" % ns):
721 if elm.find("%sarch" % ns).text not in ("noarch", "src"):
722 arch = elm.find("%sarch" % ns).text
723 if arch not in archlist:
724 archlist.append(arch)
725 elif repo["primary"].endswith(".sqlite"):
726 con = sqlite.connect(repo["primary"])
727 for row in con.execute("select arch from packages where arch not in (\"src\", \"noarch\")"):
728 if row[0] not in archlist:
729 archlist.append(row[0])
730
731 con.close()
732
733 uniq_arch = []
734 for i in range(len(archlist)):
735 if archlist[i] not in rpmmisc.archPolicies.keys():
736 continue
737 need_append = True
738 j = 0
739 while j < len(uniq_arch):
740 if archlist[i] in rpmmisc.archPolicies[uniq_arch[j]].split(':'):
741 need_append = False
742 break
743 if uniq_arch[j] in rpmmisc.archPolicies[archlist[i]].split(':'):
744 if need_append:
745 uniq_arch[j] = archlist[i]
746 need_append = False
747 else:
748 uniq_arch.remove(uniq_arch[j])
749 continue
750 j += 1
751 if need_append:
752 uniq_arch.append(archlist[i])
753
754 return uniq_arch, archlist
755
756def get_package(pkg, repometadata, arch = None):
757 ver = ""
758 target_repo = None
759 if not arch:
760 arches = []
761 elif arch not in rpmmisc.archPolicies:
762 arches = [arch]
763 else:
764 arches = rpmmisc.archPolicies[arch].split(':')
765 arches.append('noarch')
766
767 for repo in repometadata:
768 if repo["primary"].endswith(".xml"):
769 root = xmlparse(repo["primary"])
770 ns = root.getroot().tag
771 ns = ns[0:ns.rindex("}")+1]
772 for elm in root.getiterator("%spackage" % ns):
773 if elm.find("%sname" % ns).text == pkg:
774 if elm.find("%sarch" % ns).text in arches:
775 version = elm.find("%sversion" % ns)
776 tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
777 if tmpver > ver:
778 ver = tmpver
779 location = elm.find("%slocation" % ns)
780 pkgpath = "%s" % location.attrib['href']
781 target_repo = repo
782 break
783 if repo["primary"].endswith(".sqlite"):
784 con = sqlite.connect(repo["primary"])
785 if arch:
786 sql = 'select version, release, location_href from packages ' \
787 'where name = "%s" and arch IN ("%s")' % \
788 (pkg, '","'.join(arches))
789 for row in con.execute(sql):
790 tmpver = "%s-%s" % (row[0], row[1])
791 if tmpver > ver:
792 ver = tmpver
793 pkgpath = "%s" % row[2]
794 target_repo = repo
795 break
796 else:
797 sql = 'select version, release, location_href from packages ' \
798 'where name = "%s"' % pkg
799 for row in con.execute(sql):
800 tmpver = "%s-%s" % (row[0], row[1])
801 if tmpver > ver:
802 ver = tmpver
803 pkgpath = "%s" % row[2]
804 target_repo = repo
805 break
806 con.close()
807 if target_repo:
808 makedirs("%s/packages/%s" % (target_repo["cachedir"], target_repo["name"]))
809 url = os.path.join(target_repo["baseurl"], pkgpath)
810 filename = str("%s/packages/%s/%s" % (target_repo["cachedir"], target_repo["name"], os.path.basename(pkgpath)))
811 if os.path.exists(filename):
812 ret = rpmmisc.checkRpmIntegrity('rpm', filename)
813 if ret == 0:
814 return filename
815
816 msger.warning("package %s is damaged: %s" %
817 (os.path.basename(filename), filename))
818 os.unlink(filename)
819
820 pkg = myurlgrab(str(url), filename, target_repo["proxies"])
821 return pkg
822 else:
823 return None
824
825def get_source_name(pkg, repometadata):
826
827 def get_bin_name(pkg):
828 m = RPM_RE.match(pkg)
829 if m:
830 return m.group(1)
831 return None
832
833 def get_src_name(srpm):
834 m = SRPM_RE.match(srpm)
835 if m:
836 return m.group(1)
837 return None
838
839 ver = ""
840 target_repo = None
841
842 pkg_name = get_bin_name(pkg)
843 if not pkg_name:
844 return None
845
846 for repo in repometadata:
847 if repo["primary"].endswith(".xml"):
848 root = xmlparse(repo["primary"])
849 ns = root.getroot().tag
850 ns = ns[0:ns.rindex("}")+1]
851 for elm in root.getiterator("%spackage" % ns):
852 if elm.find("%sname" % ns).text == pkg_name:
853 if elm.find("%sarch" % ns).text != "src":
854 version = elm.find("%sversion" % ns)
855 tmpver = "%s-%s" % (version.attrib['ver'], version.attrib['rel'])
856 if tmpver > ver:
857 ver = tmpver
858 fmt = elm.find("%sformat" % ns)
859 if fmt:
860 fns = fmt.getchildren()[0].tag
861 fns = fns[0:fns.rindex("}")+1]
862 pkgpath = fmt.find("%ssourcerpm" % fns).text
863 target_repo = repo
864 break
865
866 if repo["primary"].endswith(".sqlite"):
867 con = sqlite.connect(repo["primary"])
868 for row in con.execute("select version, release, rpm_sourcerpm from packages where name = \"%s\" and arch != \"src\"" % pkg_name):
869 tmpver = "%s-%s" % (row[0], row[1])
870 if tmpver > ver:
871 pkgpath = "%s" % row[2]
872 target_repo = repo
873 break
874 con.close()
875 if target_repo:
876 return get_src_name(pkgpath)
877 else:
878 return None
879
880def get_pkglist_in_patterns(group, patterns):
881 found = False
882 pkglist = []
883 try:
884 root = xmlparse(patterns)
885 except SyntaxError:
886 raise SyntaxError("%s syntax error." % patterns)
887
888 for elm in list(root.getroot()):
889 ns = elm.tag
890 ns = ns[0:ns.rindex("}")+1]
891 name = elm.find("%sname" % ns)
892 summary = elm.find("%ssummary" % ns)
893 if name.text == group or summary.text == group:
894 found = True
895 break
896
897 if not found:
898 return pkglist
899
900 found = False
901 for requires in list(elm):
902 if requires.tag.endswith("requires"):
903 found = True
904 break
905
906 if not found:
907 return pkglist
908
909 for pkg in list(requires):
910 pkgname = pkg.attrib["name"]
911 if pkgname not in pkglist:
912 pkglist.append(pkgname)
913
914 return pkglist
915
916def get_pkglist_in_comps(group, comps):
917 found = False
918 pkglist = []
919 try:
920 root = xmlparse(comps)
921 except SyntaxError:
922 raise SyntaxError("%s syntax error." % comps)
923
924 for elm in root.getiterator("group"):
925 id = elm.find("id")
926 name = elm.find("name")
927 if id.text == group or name.text == group:
928 packagelist = elm.find("packagelist")
929 found = True
930 break
931
932 if not found:
933 return pkglist
934
935 for require in elm.getiterator("packagereq"):
936 if require.tag.endswith("packagereq"):
937 pkgname = require.text
938 if pkgname not in pkglist:
939 pkglist.append(pkgname)
940
941 return pkglist
942
943def is_statically_linked(binary):
944 return ", statically linked, " in runner.outs(['file', binary])
945
946def setup_qemu_emulator(rootdir, arch):
947 # mount binfmt_misc if it doesn't exist
948 if not os.path.exists("/proc/sys/fs/binfmt_misc"):
949 modprobecmd = find_binary_path("modprobe")
950 runner.show([modprobecmd, "binfmt_misc"])
951 if not os.path.exists("/proc/sys/fs/binfmt_misc/register"):
952 mountcmd = find_binary_path("mount")
953 runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"])
954
955 # qemu_emulator is a special case, we can't use find_binary_path
956 # qemu emulator should be a statically-linked executable file
957 qemu_emulator = "/usr/bin/qemu-arm"
958 if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator):
959 qemu_emulator = "/usr/bin/qemu-arm-static"
960 if not os.path.exists(qemu_emulator):
961 raise CreatorError("Please install a statically-linked qemu-arm")
962
963 # qemu emulator version check
964 armv7_list = [arch for arch in rpmmisc.archPolicies.keys() if arch.startswith('armv7')]
965 if arch in armv7_list: # need qemu (>=0.13.0)
966 qemuout = runner.outs([qemu_emulator, "-h"])
967 m = re.search("version\s*([.\d]+)", qemuout)
968 if m:
969 qemu_version = m.group(1)
970 if qemu_version < "0.13":
971 raise CreatorError("Requires %s version >=0.13 for %s" % (qemu_emulator, arch))
972 else:
973 msger.warning("Can't get version info of %s, please make sure it's higher than 0.13.0" % qemu_emulator)
974
975 if not os.path.exists(rootdir + "/usr/bin"):
976 makedirs(rootdir + "/usr/bin")
977 shutil.copy(qemu_emulator, rootdir + "/usr/bin/qemu-arm-static")
978 qemu_emulator = "/usr/bin/qemu-arm-static"
979
980 # disable selinux, selinux will block qemu emulator to run
981 if os.path.exists("/usr/sbin/setenforce"):
982 msger.info('Try to disable selinux')
983 runner.show(["/usr/sbin/setenforce", "0"])
984
985 # unregister it if it has been registered and is a dynamically-linked executable
986 node = "/proc/sys/fs/binfmt_misc/arm"
987 if os.path.exists(node):
988 qemu_unregister_string = "-1\n"
989 fd = open("/proc/sys/fs/binfmt_misc/arm", "w")
990 fd.write(qemu_unregister_string)
991 fd.close()
992
993 # register qemu emulator for interpreting other arch executable file
994 if not os.path.exists(node):
995 qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator
996 fd = open("/proc/sys/fs/binfmt_misc/register", "w")
997 fd.write(qemu_arm_string)
998 fd.close()
999
1000 return qemu_emulator
1001
1002def SrcpkgsDownload(pkgs, repometadata, instroot, cachedir):
1003 def get_source_repometadata(repometadata):
1004 src_repometadata=[]
1005 for repo in repometadata:
1006 if repo["name"].endswith("-source"):
1007 src_repometadata.append(repo)
1008 if src_repometadata:
1009 return src_repometadata
1010 return None
1011
1012 def get_src_name(srpm):
1013 m = SRPM_RE.match(srpm)
1014 if m:
1015 return m.group(1)
1016 return None
1017
1018 src_repometadata = get_source_repometadata(repometadata)
1019
1020 if not src_repometadata:
1021 msger.warning("No source repo found")
1022 return None
1023
1024 src_pkgs = []
1025 lpkgs_dict = {}
1026 lpkgs_path = []
1027 for repo in src_repometadata:
1028 cachepath = "%s/%s/packages/*.src.rpm" %(cachedir, repo["name"])
1029 lpkgs_path += glob.glob(cachepath)
1030
1031 for lpkg in lpkgs_path:
1032 lpkg_name = get_src_name(os.path.basename(lpkg))
1033 lpkgs_dict[lpkg_name] = lpkg
1034 localpkgs = lpkgs_dict.keys()
1035
1036 cached_count = 0
1037 destdir = instroot+'/usr/src/SRPMS'
1038 if not os.path.exists(destdir):
1039 os.makedirs(destdir)
1040
1041 srcpkgset = set()
1042 for _pkg in pkgs:
1043 srcpkg_name = get_source_name(_pkg, repometadata)
1044 if not srcpkg_name:
1045 continue
1046 srcpkgset.add(srcpkg_name)
1047
1048 for pkg in list(srcpkgset):
1049 if pkg in localpkgs:
1050 cached_count += 1
1051 shutil.copy(lpkgs_dict[pkg], destdir)
1052 src_pkgs.append(os.path.basename(lpkgs_dict[pkg]))
1053 else:
1054 src_pkg = get_package(pkg, src_repometadata, 'src')
1055 if src_pkg:
1056 shutil.copy(src_pkg, destdir)
1057 src_pkgs.append(src_pkg)
1058 msger.info("%d source packages gotten from cache" % cached_count)
1059
1060 return src_pkgs
1061
1062def strip_end(text, suffix):
1063 if not text.endswith(suffix):
1064 return text
1065 return text[:-len(suffix)]
diff --git a/scripts/lib/mic/utils/oe/__init__.py b/scripts/lib/mic/utils/oe/__init__.py
new file mode 100644
index 0000000000..d10e802116
--- /dev/null
+++ b/scripts/lib/mic/utils/oe/__init__.py
@@ -0,0 +1,22 @@
1#
2# OpenEmbedded mic utils library
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# AUTHORS
21# Tom Zanussi <tom.zanussi (at] linux.intel.com>
22#
diff --git a/scripts/lib/mic/utils/oe/misc.py b/scripts/lib/mic/utils/oe/misc.py
new file mode 100644
index 0000000000..7ad3aa9685
--- /dev/null
+++ b/scripts/lib/mic/utils/oe/misc.py
@@ -0,0 +1,144 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2013, Intel Corporation.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This module provides a place to collect various mic-related utils
22# for the OpenEmbedded Image Tools.
23#
24# AUTHORS
25# Tom Zanussi <tom.zanussi (at] linux.intel.com>
26#
27
28from mic import msger
29from mic.utils import runner
30
31def exec_cmd(cmd_and_args, as_shell = False, catch = 3):
32 """
33 Execute command, catching stderr, stdout
34
35 Need to execute as_shell if the command uses wildcards
36 """
37 msger.debug("exec_cmd: %s" % cmd_and_args)
38 args = cmd_and_args.split()
39 msger.debug(args)
40
41 if (as_shell):
42 rc, out = runner.runtool(cmd_and_args, catch)
43 else:
44 rc, out = runner.runtool(args, catch)
45 out = out.strip()
46 msger.debug("exec_cmd: output for %s (rc = %d): %s" % \
47 (cmd_and_args, rc, out))
48
49 if rc != 0:
50 # We don't throw exception when return code is not 0, because
51 # parted always fails to reload part table with loop devices. This
52 # prevents us from distinguishing real errors based on return
53 # code.
54 msger.warning("WARNING: %s returned '%s' instead of 0" % (cmd_and_args, rc))
55
56 return (rc, out)
57
58
59def exec_cmd_quiet(cmd_and_args, as_shell = False):
60 """
61 Execute command, catching nothing in the output
62
63 Need to execute as_shell if the command uses wildcards
64 """
65 return exec_cmd(cmd_and_args, as_shell, 0)
66
67
68def exec_native_cmd(cmd_and_args, native_sysroot, catch = 3):
69 """
70 Execute native command, catching stderr, stdout
71
72 Need to execute as_shell if the command uses wildcards
73
74 Always need to execute native commands as_shell
75 """
76 native_paths = \
77 "export PATH=%s/sbin:%s/usr/sbin:%s/usr/bin:$PATH" % \
78 (native_sysroot, native_sysroot, native_sysroot)
79 native_cmd_and_args = "%s;%s" % (native_paths, cmd_and_args)
80 msger.debug("exec_native_cmd: %s" % cmd_and_args)
81
82 args = cmd_and_args.split()
83 msger.debug(args)
84
85 rc, out = exec_cmd(native_cmd_and_args, True, catch)
86
87 if rc == 127: # shell command-not-found
88 msger.error("A native (host) program required to build the image "
89 "was not found (see details above). Please make sure "
90 "it's installed and try again.")
91
92 return (rc, out)
93
94
95def exec_native_cmd_quiet(cmd_and_args, native_sysroot):
96 """
97 Execute native command, catching nothing in the output
98
99 Need to execute as_shell if the command uses wildcards
100
101 Always need to execute native commands as_shell
102 """
103 return exec_native_cmd(cmd_and_args, native_sysroot, 0)
104
105
106# kickstart doesn't support variable substution in commands, so this
107# is our current simplistic scheme for supporting that
108
109wks_vars = dict()
110
111def get_wks_var(key):
112 return wks_vars[key]
113
114def add_wks_var(key, val):
115 wks_vars[key] = val
116
117BOOTDD_EXTRA_SPACE = 16384
118IMAGE_EXTRA_SPACE = 10240
119
120__bitbake_env_lines = ""
121
122def set_bitbake_env_lines(bitbake_env_lines):
123 global __bitbake_env_lines
124 __bitbake_env_lines = bitbake_env_lines
125
126def get_bitbake_env_lines():
127 return __bitbake_env_lines
128
129def get_line_val(line, key):
130 """
131 Extract the value from the VAR="val" string
132 """
133 if line.startswith(key + "="):
134 stripped_line = line.split('=')[1]
135 stripped_line = stripped_line.replace('\"', '')
136 return stripped_line
137 return None
138
139def get_bitbake_var(key):
140 for line in __bitbake_env_lines.split('\n'):
141 if (get_line_val(line, key)):
142 val = get_line_val(line, key)
143 return val
144 return None
diff --git a/scripts/lib/mic/utils/oe/package_manager.py b/scripts/lib/mic/utils/oe/package_manager.py
new file mode 100644
index 0000000000..92ce98e2ce
--- /dev/null
+++ b/scripts/lib/mic/utils/oe/package_manager.py
@@ -0,0 +1,810 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (c) 2014, Enea AB.
5# All rights reserved.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19#
20# DESCRIPTION
21# This implements the opkg package manager wrapper as a combination of
22# meta/lib/oe/package_manager.py and bitbake/lib/bb/utils.py files and
23# adaptation of those files to 'wic'.
24#
25# AUTHORS
26# Adrian Calianu <adrian.calianu (at] enea.com>
27#
28# This file incorporates work covered by the following copyright and
29# permission notice:
30#
31# meta/COPYING.GPLv2 (GPLv2)
32# meta/COPYING.MIT (MIT)
33#
34# Copyright (C) 2004 Michael Lauer
35#
36# Permission to use, copy, modify, and/or distribute this software
37# for any purpose with or without fee is hereby granted, provided
38# that the above copyright notice and this permission notice appear
39# in all copies.
40#
41# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
42# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
43# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
44# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
45# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
46# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
47# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
48# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
49
50
51from abc import ABCMeta, abstractmethod
52import os
53import glob
54import subprocess
55import shutil
56import multiprocessing
57import re
58import errno
59import fcntl
60
61from mic.utils.oe.misc import *
62from mic import msger
63
64def mkdirhier(directory):
65 """Create a directory like 'mkdir -p', but does not complain if
66 directory already exists like os.makedirs
67 """
68
69 try:
70 os.makedirs(directory)
71 except OSError as e:
72 if e.errno != errno.EEXIST:
73 raise e
74
75def remove(path, recurse=False):
76 """Equivalent to rm -f or rm -rf"""
77 if not path:
78 return
79 if recurse:
80 # shutil.rmtree(name) would be ideal but its too slow
81 subprocess.call(['rm', '-rf'] + glob.glob(path))
82 return
83 for name in glob.glob(path):
84 try:
85 os.unlink(name)
86 except OSError as exc:
87 if exc.errno != errno.ENOENT:
88 raise
89
90def lockfile(name, shared=False, retry=True):
91 """
92 Use the file fn as a lock file, return when the lock has been acquired.
93 Returns a variable to pass to unlockfile().
94 """
95 dirname = os.path.dirname(name)
96 mkdirhier(dirname)
97
98 if not os.access(dirname, os.W_OK):
99 logger.error("Unable to acquire lock '%s', directory is not writable",
100 name)
101 sys.exit(1)
102
103 op = fcntl.LOCK_EX
104 if shared:
105 op = fcntl.LOCK_SH
106 if not retry:
107 op = op | fcntl.LOCK_NB
108
109 while True:
110 # If we leave the lockfiles lying around there is no problem
111 # but we should clean up after ourselves. This gives potential
112 # for races though. To work around this, when we acquire the lock
113 # we check the file we locked was still the lock file on disk.
114 # by comparing inode numbers. If they don't match or the lockfile
115 # no longer exists, we start again.
116
117 # This implementation is unfair since the last person to request the
118 # lock is the most likely to win it.
119
120 try:
121 lf = open(name, 'a+')
122 fileno = lf.fileno()
123 fcntl.flock(fileno, op)
124 statinfo = os.fstat(fileno)
125 if os.path.exists(lf.name):
126 statinfo2 = os.stat(lf.name)
127 if statinfo.st_ino == statinfo2.st_ino:
128 return lf
129 lf.close()
130 except Exception:
131 try:
132 lf.close()
133 except Exception:
134 pass
135 pass
136 if not retry:
137 return None
138
139def unlockfile(lf):
140 """
141 Unlock a file locked using lockfile()
142 """
143 try:
144 # If we had a shared lock, we need to promote to exclusive before
145 # removing the lockfile. Attempt this, ignore failures.
146 fcntl.flock(lf.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB)
147 os.unlink(lf.name)
148 except (IOError, OSError):
149 pass
150 fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
151 lf.close()
152
153def which(path, item, direction = 0, history = False):
154 """
155 Locate a file in a PATH
156 """
157
158 hist = []
159 paths = (path or "").split(':')
160 if direction != 0:
161 paths.reverse()
162
163 for p in paths:
164 next = os.path.join(p, item)
165 hist.append(next)
166 if os.path.exists(next):
167 if not os.path.isabs(next):
168 next = os.path.abspath(next)
169 if history:
170 return next, hist
171 return next
172
173 if history:
174 return "", hist
175 return ""
176
177
178
179# this can be used by all PM backends to create the index files in parallel
180def wic_create_index(arg):
181 index_cmd = arg
182
183 try:
184 msger.info("Executing '%s' ..." % index_cmd)
185 subprocess.check_output(index_cmd, stderr=subprocess.STDOUT, shell=True)
186 except subprocess.CalledProcessError as e:
187 return("Index creation command '%s' failed with return code %d:\n%s" %
188 (e.cmd, e.returncode, e.output))
189
190 return None
191
192
193class WicIndexer(object):
194 __metaclass__ = ABCMeta
195
196 def __init__(self, d, deploy_dir):
197 self.d = d
198 self.deploy_dir = deploy_dir
199
200 @abstractmethod
201 def write_index(self):
202 pass
203
204class WicOpkgIndexer(WicIndexer):
205 def write_index(self):
206 arch_vars = ["ALL_MULTILIB_PACKAGE_ARCHS",
207 "SDK_PACKAGE_ARCHS",
208 "MULTILIB_ARCHS"]
209
210 opkg_index_cmd = which(os.getenv('PATH'), "opkg-make-index")
211
212 if not os.path.exists(os.path.join(self.deploy_dir, "Packages")):
213 open(os.path.join(self.deploy_dir, "Packages"), "w").close()
214
215 index_cmds = []
216 for arch_var in arch_vars:
217 if self.d.has_key(arch_var):
218 archs = self.d[arch_var]
219 else:
220 archs = None
221
222 if archs is None:
223 continue
224
225 for arch in archs.split():
226 pkgs_dir = os.path.join(self.deploy_dir, arch)
227 pkgs_file = os.path.join(pkgs_dir, "Packages")
228
229 if not os.path.isdir(pkgs_dir):
230 continue
231
232 if not os.path.exists(pkgs_file):
233 open(pkgs_file, "w").close()
234
235 index_cmds.append('%s -r %s -p %s -m %s' %
236 (opkg_index_cmd, pkgs_file, pkgs_file, pkgs_dir))
237
238 if len(index_cmds) == 0:
239 msger.info("There are no packages in %s!" % self.deploy_dir)
240 return
241
242 nproc = multiprocessing.cpu_count()
243 pool = multiprocessing.Pool(nproc)
244 results = list(pool.imap(wic_create_index, index_cmds))
245 pool.close()
246 pool.join()
247
248 for result in results:
249 if result is not None:
250 return(result)
251
252class WicPkgsList(object):
253 __metaclass__ = ABCMeta
254
255 def __init__(self, d, rootfs_dir):
256 self.d = d
257 self.rootfs_dir = rootfs_dir
258
259 @abstractmethod
260 def list(self, format=None):
261 pass
262
263
264class WicOpkgPkgsList(WicPkgsList):
265 def __init__(self, d, rootfs_dir, config_file):
266 super(WicOpkgPkgsList, self).__init__(d, rootfs_dir)
267
268 self.opkg_cmd = which(os.getenv('PATH'), "opkg-cl")
269 self.opkg_args = "-f %s -o %s " % (config_file, rootfs_dir)
270 if self.d.has_key("OPKG_ARGS"):
271 self.opkg_args += self.d["OPKG_ARGS"]
272
273 def list(self, format=None):
274 opkg_query_cmd = which(os.getenv('PATH'), "opkg-query-helper.py")
275
276 if format == "arch":
277 cmd = "%s %s status | %s -a" % \
278 (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
279 elif format == "file":
280 cmd = "%s %s status | %s -f" % \
281 (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
282 elif format == "ver":
283 cmd = "%s %s status | %s -v" % \
284 (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
285 elif format == "deps":
286 cmd = "%s %s status | %s" % \
287 (self.opkg_cmd, self.opkg_args, opkg_query_cmd)
288 else:
289 cmd = "%s %s list_installed | cut -d' ' -f1" % \
290 (self.opkg_cmd, self.opkg_args)
291
292 try:
293 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).strip()
294 except subprocess.CalledProcessError as e:
295 msger.error("Cannot get the installed packages list. Command '%s' "
296 "returned %d:\n%s" % (cmd, e.returncode, e.output))
297
298 if output and format == "file":
299 tmp_output = ""
300 for line in output.split('\n'):
301 pkg, pkg_file, pkg_arch = line.split()
302 full_path = os.path.join(self.rootfs_dir, pkg_arch, pkg_file)
303 if os.path.exists(full_path):
304 tmp_output += "%s %s %s\n" % (pkg, full_path, pkg_arch)
305 else:
306 tmp_output += "%s %s %s\n" % (pkg, pkg_file, pkg_arch)
307
308 output = tmp_output
309
310 return output
311
312
313class WicPackageManager(object):
314 """
315 This is an abstract class. Do not instantiate this directly.
316 """
317 __metaclass__ = ABCMeta
318
319 def __init__(self, d, pseudo, native_sysroot):
320 self.d = d
321 self.deploy_dir = None
322 self.deploy_lock = None
323 if self.d.has_key('PACKAGE_FEED_URIS'):
324 self.feed_uris = self.d['PACKAGE_FEED_URIS']
325 else:
326 self.feed_uris = ""
327 self.pseudo = pseudo
328 self.native_sysroot = native_sysroot
329
330 """
331 Update the package manager package database.
332 """
333 @abstractmethod
334 def update(self):
335 pass
336
337 """
338 Install a list of packages. 'pkgs' is a list object. If 'attempt_only' is
339 True, installation failures are ignored.
340 """
341 @abstractmethod
342 def install(self, pkgs, attempt_only=False):
343 pass
344
345 """
346 Remove a list of packages. 'pkgs' is a list object. If 'with_dependencies'
347 is False, the any dependencies are left in place.
348 """
349 @abstractmethod
350 def remove(self, pkgs, with_dependencies=True):
351 pass
352
353 """
354 This function creates the index files
355 """
356 @abstractmethod
357 def write_index(self):
358 pass
359
360 @abstractmethod
361 def remove_packaging_data(self):
362 pass
363
364 @abstractmethod
365 def list_installed(self, format=None):
366 pass
367
368 @abstractmethod
369 def insert_feeds_uris(self):
370 pass
371
372 """
373 Install complementary packages based upon the list of currently installed
374 packages e.g. locales, *-dev, *-dbg, etc. This will only attempt to install
375 these packages, if they don't exist then no error will occur. Note: every
376 backend needs to call this function explicitly after the normal package
377 installation
378 """
379 def install_complementary(self, globs=None):
380 # we need to write the list of installed packages to a file because the
381 # oe-pkgdata-util reads it from a file
382 if self.d.has_key('WORKDIR'):
383 installed_pkgs_file = os.path.join(self.d['WORKDIR'],
384 "installed_pkgs.txt")
385 else:
386 msger.error("No WORKDIR provided!")
387
388 with open(installed_pkgs_file, "w+") as installed_pkgs:
389 installed_pkgs.write(self.list_installed("arch"))
390
391 if globs is None:
392 if self.d.has_key('IMAGE_INSTALL_COMPLEMENTARY'):
393 globs = self.d['IMAGE_INSTALL_COMPLEMENTARY']
394 split_linguas = set()
395
396 if self.d.has_key('IMAGE_LINGUAS'):
397 for translation in self.d['IMAGE_LINGUAS'].split():
398 split_linguas.add(translation)
399 split_linguas.add(translation.split('-')[0])
400
401 split_linguas = sorted(split_linguas)
402
403 for lang in split_linguas:
404 globs += " *-locale-%s" % lang
405
406 if globs is None:
407 return
408
409 if not self.d.has_key('PKGDATA_DIR'):
410 msger.error("No PKGDATA_DIR provided!")
411
412 cmd = [which(os.getenv('PATH'), "oe-pkgdata-util"),
413 "glob", self.d['PKGDATA_DIR'], installed_pkgs_file,
414 globs]
415
416 rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
417 if rc != 0:
418 msger.error("Could not compute complementary packages list. Command "
419 "'%s' returned %d" %
420 (' '.join(cmd), rc))
421
422 self.install(out.split(), attempt_only=True)
423
424
425 def deploy_dir_lock(self):
426 if self.deploy_dir is None:
427 raise RuntimeError("deploy_dir is not set!")
428
429 lock_file_name = os.path.join(self.deploy_dir, "deploy.lock")
430
431 self.deploy_lock = lockfile(lock_file_name)
432
433 def deploy_dir_unlock(self):
434 if self.deploy_lock is None:
435 return
436
437 unlockfile(self.deploy_lock)
438
439 self.deploy_lock = None
440
441
442class WicOpkgPM(WicPackageManager):
443 def __init__(self, d, target_rootfs, config_file, archs, pseudo, native_sysroot, task_name='target'):
444 super(WicOpkgPM, self).__init__(d, pseudo, native_sysroot)
445
446 self.target_rootfs = target_rootfs
447 self.config_file = config_file
448 self.pkg_archs = archs
449 self.task_name = task_name
450
451 if self.d.has_key("DEPLOY_DIR_IPK"):
452 self.deploy_dir = self.d["DEPLOY_DIR_IPK"]
453
454 self.deploy_lock_file = os.path.join(self.deploy_dir, "deploy.lock")
455 self.opkg_cmd = which(os.getenv('PATH'), "opkg-cl")
456 self.opkg_args = "-f %s -o %s " % (self.config_file, target_rootfs)
457 if self.d.has_key("OPKG_ARGS"):
458 self.opkg_args += self.d["OPKG_ARGS"]
459
460 if self.d.has_key('OPKGLIBDIR'):
461 opkg_lib_dir = self.d['OPKGLIBDIR']
462 else:
463 opkg_lib_dir = ""
464
465 if opkg_lib_dir[0] == "/":
466 opkg_lib_dir = opkg_lib_dir[1:]
467
468 self.opkg_dir = os.path.join(target_rootfs, opkg_lib_dir, "opkg")
469
470 mkdirhier(self.opkg_dir)
471
472 if self.d.has_key("TMPDIR"):
473 tmp_dir = self.d["TMPDIR"]
474 else:
475 tmp_dir = ""
476
477 self.saved_opkg_dir = '%s/saved/%s' % (tmp_dir, self.task_name)
478 if not os.path.exists('%s/saved' % tmp_dir):
479 mkdirhier('%s/saved' % tmp_dir)
480
481 if self.d.has_key('BUILD_IMAGES_FROM_FEEDS') and self.d['BUILD_IMAGES_FROM_FEEDS'] != "1":
482 self._create_config()
483 else:
484 self._create_custom_config()
485
486 self.indexer = WicOpkgIndexer(self.d, self.deploy_dir)
487
488 """
489 This function will change a package's status in /var/lib/opkg/status file.
490 If 'packages' is None then the new_status will be applied to all
491 packages
492 """
493 def mark_packages(self, status_tag, packages=None):
494 status_file = os.path.join(self.opkg_dir, "status")
495
496 with open(status_file, "r") as sf:
497 with open(status_file + ".tmp", "w+") as tmp_sf:
498 if packages is None:
499 tmp_sf.write(re.sub(r"Package: (.*?)\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)",
500 r"Package: \1\n\2Status: \3%s" % status_tag,
501 sf.read()))
502 else:
503 if type(packages).__name__ != "list":
504 raise TypeError("'packages' should be a list object")
505
506 status = sf.read()
507 for pkg in packages:
508 status = re.sub(r"Package: %s\n((?:[^\n]+\n)*?)Status: (.*)(?:unpacked|installed)" % pkg,
509 r"Package: %s\n\1Status: \2%s" % (pkg, status_tag),
510 status)
511
512 tmp_sf.write(status)
513
514 os.rename(status_file + ".tmp", status_file)
515
516 def _create_custom_config(self):
517 msger.info("Building from feeds activated!")
518
519 with open(self.config_file, "w+") as config_file:
520 priority = 1
521 for arch in self.pkg_archs.split():
522 config_file.write("arch %s %d\n" % (arch, priority))
523 priority += 5
524
525 if self.d.has_key('IPK_FEED_URIS'):
526 ipk_feed_uris = self.d['IPK_FEED_URIS']
527 else:
528 ipk_feed_uris = ""
529
530 for line in ipk_feed_uris.split():
531 feed_match = re.match("^[ \t]*(.*)##([^ \t]*)[ \t]*$", line)
532
533 if feed_match is not None:
534 feed_name = feed_match.group(1)
535 feed_uri = feed_match.group(2)
536
537 msger.info("Add %s feed with URL %s" % (feed_name, feed_uri))
538
539 config_file.write("src/gz %s %s\n" % (feed_name, feed_uri))
540
541 """
542 Allow to use package deploy directory contents as quick devel-testing
543 feed. This creates individual feed configs for each arch subdir of those
544 specified as compatible for the current machine.
545 NOTE: Development-helper feature, NOT a full-fledged feed.
546 """
547 if self.d.has_key('FEED_DEPLOYDIR_BASE_URI'):
548 feed_deploydir_base_dir = self.d['FEED_DEPLOYDIR_BASE_URI']
549 else:
550 feed_deploydir_base_dir = ""
551
552 if feed_deploydir_base_dir != "":
553 for arch in self.pkg_archs.split():
554 if self.d.has_key("sysconfdir"):
555 sysconfdir = self.d["sysconfdir"]
556 else:
557 sysconfdir = None
558
559 cfg_file_name = os.path.join(self.target_rootfs,
560 sysconfdir,
561 "opkg",
562 "local-%s-feed.conf" % arch)
563
564 with open(cfg_file_name, "w+") as cfg_file:
565 cfg_file.write("src/gz local-%s %s/%s" %
566 arch,
567 feed_deploydir_base_dir,
568 arch)
569
570 def _create_config(self):
571 with open(self.config_file, "w+") as config_file:
572 priority = 1
573 for arch in self.pkg_archs.split():
574 config_file.write("arch %s %d\n" % (arch, priority))
575 priority += 5
576
577 config_file.write("src oe file:%s\n" % self.deploy_dir)
578
579 for arch in self.pkg_archs.split():
580 pkgs_dir = os.path.join(self.deploy_dir, arch)
581 if os.path.isdir(pkgs_dir):
582 config_file.write("src oe-%s file:%s\n" %
583 (arch, pkgs_dir))
584
585 def insert_feeds_uris(self):
586 if self.feed_uris == "":
587 return
588
589 rootfs_config = os.path.join('%s/etc/opkg/base-feeds.conf'
590 % self.target_rootfs)
591
592 with open(rootfs_config, "w+") as config_file:
593 uri_iterator = 0
594 for uri in self.feed_uris.split():
595 config_file.write("src/gz url-%d %s/ipk\n" %
596 (uri_iterator, uri))
597
598 for arch in self.pkg_archs.split():
599 if not os.path.exists(os.path.join(self.deploy_dir, arch)):
600 continue
601 msger.info('Note: adding opkg channel url-%s-%d (%s)' %
602 (arch, uri_iterator, uri))
603
604 config_file.write("src/gz uri-%s-%d %s/ipk/%s\n" %
605 (arch, uri_iterator, uri, arch))
606 uri_iterator += 1
607
608 def update(self):
609 self.deploy_dir_lock()
610
611 cmd = "%s %s update" % (self.opkg_cmd, self.opkg_args)
612
613 rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
614 if rc != 0:
615 self.deploy_dir_unlock()
616 msger.error("Unable to update the package index files. Command '%s' "
617 "returned %d" % (cmd, rc))
618
619 self.deploy_dir_unlock()
620
621 def install(self, pkgs, attempt_only=False):
622 if attempt_only and len(pkgs) == 0:
623 return
624
625 cmd = "%s %s install %s" % (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
626
627 os.environ['D'] = self.target_rootfs
628 os.environ['OFFLINE_ROOT'] = self.target_rootfs
629 os.environ['IPKG_OFFLINE_ROOT'] = self.target_rootfs
630 os.environ['OPKG_OFFLINE_ROOT'] = self.target_rootfs
631 if self.d.has_key('WORKDIR'):
632 os.environ['INTERCEPT_DIR'] = os.path.join(self.d['WORKDIR'],
633 "intercept_scripts")
634 else:
635 os.environ['INTERCEPT_DIR'] = "."
636 msger.warning("No WORKDIR provided!")
637
638 if self.d.has_key('STAGING_DIR_NATIVE'):
639 os.environ['NATIVE_ROOT'] = self.d['STAGING_DIR_NATIVE']
640 else:
641 msger.error("No STAGING_DIR_NATIVE provided!")
642
643 rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
644 if rc != 0:
645 msger.error("Unable to install packages. "
646 "Command '%s' returned %d" % (cmd, rc))
647
648
649 def remove(self, pkgs, with_dependencies=True):
650 if with_dependencies:
651 cmd = "%s %s --force-depends --force-remove --force-removal-of-dependent-packages remove %s" % \
652 (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
653 else:
654 cmd = "%s %s --force-depends remove %s" % \
655 (self.opkg_cmd, self.opkg_args, ' '.join(pkgs))
656
657 rc, out = exec_native_cmd(self.pseudo + cmd, self.native_sysroot)
658 if rc != 0:
659 msger.error("Unable to remove packages. Command '%s' "
660 "returned %d" % (cmd, rc))
661
662
663 def write_index(self):
664 self.deploy_dir_lock()
665
666 result = self.indexer.write_index()
667
668 self.deploy_dir_unlock()
669
670 if result is not None:
671 msger.error(result)
672
673 def remove_packaging_data(self):
674 remove(self.opkg_dir, True)
675 # create the directory back, it's needed by PM lock
676 mkdirhier(self.opkg_dir)
677
678 def list_installed(self, format=None):
679 return WicOpkgPkgsList(self.d, self.target_rootfs, self.config_file).list(format)
680
681 def handle_bad_recommendations(self):
682 if self.d.has_key("BAD_RECOMMENDATIONS"):
683 bad_recommendations = self.d["BAD_RECOMMENDATIONS"]
684 else:
685 bad_recommendations = ""
686
687 if bad_recommendations.strip() == "":
688 return
689
690 status_file = os.path.join(self.opkg_dir, "status")
691
692 # If status file existed, it means the bad recommendations has already
693 # been handled
694 if os.path.exists(status_file):
695 return
696
697 cmd = "%s %s info " % (self.opkg_cmd, self.opkg_args)
698
699 with open(status_file, "w+") as status:
700 for pkg in bad_recommendations.split():
701 pkg_info = cmd + pkg
702
703 try:
704 output = subprocess.check_output(pkg_info.split(), stderr=subprocess.STDOUT).strip()
705 except subprocess.CalledProcessError as e:
706 msger.error("Cannot get package info. Command '%s' "
707 "returned %d:\n%s" % (pkg_info, e.returncode, e.output))
708
709 if output == "":
710 msger.info("Ignored bad recommendation: '%s' is "
711 "not a package" % pkg)
712 continue
713
714 for line in output.split('\n'):
715 if line.startswith("Status:"):
716 status.write("Status: deinstall hold not-installed\n")
717 else:
718 status.write(line + "\n")
719
720 '''
721 The following function dummy installs pkgs and returns the log of output.
722 '''
723 def dummy_install(self, pkgs):
724 if len(pkgs) == 0:
725 return
726
727 # Create an temp dir as opkg root for dummy installation
728 if self.d.has_key("TMPDIR"):
729 tmp_dir = self.d["TMPDIR"]
730 else:
731 tmp_dir = "."
732 msger.warning("No TMPDIR provided!")
733
734 temp_rootfs = '%s/opkg' % tmp_dir
735 temp_opkg_dir = os.path.join(temp_rootfs, 'var/lib/opkg')
736 mkdirhier(temp_opkg_dir)
737
738 opkg_args = "-f %s -o %s " % (self.config_file, temp_rootfs)
739 if self.d.has_key("OPKG_ARGS"):
740 opkg_args += self.d["OPKG_ARGS"]
741
742 cmd = "%s %s update" % (self.opkg_cmd, opkg_args)
743 try:
744 subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
745 except subprocess.CalledProcessError as e:
746 msger.error("Unable to update. Command '%s' "
747 "returned %d:\n%s" % (cmd, e.returncode, e.output))
748
749 # Dummy installation
750 cmd = "%s %s --noaction install %s " % (self.opkg_cmd,
751 opkg_args,
752 ' '.join(pkgs))
753 try:
754 output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
755 except subprocess.CalledProcessError as e:
756 msger.error("Unable to dummy install packages. Command '%s' "
757 "returned %d:\n%s" % (cmd, e.returncode, e.output))
758
759 remove(temp_rootfs, True)
760
761 return output
762
763 def backup_packaging_data(self):
764 # Save the opkglib for increment ipk image generation
765 if os.path.exists(self.saved_opkg_dir):
766 remove(self.saved_opkg_dir, True)
767 shutil.copytree(self.opkg_dir,
768 self.saved_opkg_dir,
769 symlinks=True)
770
771 def recover_packaging_data(self):
772 # Move the opkglib back
773 if os.path.exists(self.saved_opkg_dir):
774 if os.path.exists(self.opkg_dir):
775 remove(self.opkg_dir, True)
776
777 msger.info('Recover packaging data')
778 shutil.copytree(self.saved_opkg_dir,
779 self.opkg_dir,
780 symlinks=True)
781
782
783def wic_generate_index_files(d):
784 if d.has_key('PACKAGE_CLASSES'):
785 classes = d['PACKAGE_CLASSES'].replace("package_", "").split()
786 else:
787 classes = ""
788 msger.warning("No PACKAGE_CLASSES provided!")
789
790 if d.has_key('DEPLOY_DIR_IPK'):
791 deploy_dir_ipk = d['DEPLOY_DIR_IPK']
792 else:
793 deploy_dir_ipk = None
794 msger.warning("No DEPLOY_DIR_IPK provided!")
795
796 indexer_map = {
797 "ipk": (WicOpkgIndexer, deploy_dir_ipk)
798 }
799
800 result = None
801
802 for pkg_class in classes:
803 if not pkg_class in indexer_map:
804 continue
805
806 if os.path.exists(indexer_map[pkg_class][1]):
807 result = indexer_map[pkg_class][0](d, indexer_map[pkg_class][1]).write_index()
808
809 if result is not None:
810 msger.error(result)
diff --git a/scripts/lib/mic/utils/partitionedfs.py b/scripts/lib/mic/utils/partitionedfs.py
new file mode 100644
index 0000000000..6607466a83
--- /dev/null
+++ b/scripts/lib/mic/utils/partitionedfs.py
@@ -0,0 +1,782 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4# Copyright (c) 2007, 2008 Red Hat, Inc.
5# Copyright (c) 2008 Daniel P. Berrange
6# Copyright (c) 2008 David P. Huff
7#
8# This program is free software; you can redistribute it and/or modify it
9# under the terms of the GNU General Public License as published by the Free
10# Software Foundation; version 2 of the License
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15# for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc., 59
19# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21import os
22
23from mic import msger
24from mic.utils import runner
25from mic.utils.errors import MountError
26from mic.utils.fs_related import *
27from mic.utils.gpt_parser import GptParser
28from mic.utils.oe.misc import *
29
30# Overhead of the MBR partitioning scheme (just one sector)
31MBR_OVERHEAD = 1
32# Overhead of the GPT partitioning scheme
33GPT_OVERHEAD = 34
34
35# Size of a sector in bytes
36SECTOR_SIZE = 512
37
38class PartitionedMount(Mount):
39 def __init__(self, mountdir, skipformat = False):
40 Mount.__init__(self, mountdir)
41 self.disks = {}
42 self.partitions = []
43 self.subvolumes = []
44 self.mapped = False
45 self.mountOrder = []
46 self.unmountOrder = []
47 self.parted = find_binary_path("parted")
48 self.btrfscmd=None
49 self.skipformat = skipformat
50 self.snapshot_created = self.skipformat
51 # Size of a sector used in calculations
52 self.sector_size = SECTOR_SIZE
53 self._partitions_layed_out = False
54
55 def __add_disk(self, disk_name):
56 """ Add a disk 'disk_name' to the internal list of disks. Note,
57 'disk_name' is the name of the disk in the target system
58 (e.g., sdb). """
59
60 if disk_name in self.disks:
61 # We already have this disk
62 return
63
64 assert not self._partitions_layed_out
65
66 self.disks[disk_name] = \
67 { 'disk': None, # Disk object
68 'mapped': False, # True if kpartx mapping exists
69 'numpart': 0, # Number of allocate partitions
70 'partitions': [], # Indexes to self.partitions
71 'offset': 0, # Offset of next partition (in sectors)
72 # Minimum required disk size to fit all partitions (in bytes)
73 'min_size': 0,
74 'ptable_format': "msdos" } # Partition table format
75
76 def add_disk(self, disk_name, disk_obj):
77 """ Add a disk object which have to be partitioned. More than one disk
78 can be added. In case of multiple disks, disk partitions have to be
79 added for each disk separately with 'add_partition()". """
80
81 self.__add_disk(disk_name)
82 self.disks[disk_name]['disk'] = disk_obj
83
84 def __add_partition(self, part):
85 """ This is a helper function for 'add_partition()' which adds a
86 partition to the internal list of partitions. """
87
88 assert not self._partitions_layed_out
89
90 self.partitions.append(part)
91 self.__add_disk(part['disk_name'])
92
93 def add_partition(self, size, disk_name, mountpoint, source_file = None, fstype = None,
94 label=None, fsopts = None, boot = False, align = None,
95 part_type = None):
96 """ Add the next partition. Prtitions have to be added in the
97 first-to-last order. """
98
99 ks_pnum = len(self.partitions)
100
101 # Converting MB to sectors for parted
102 size = size * 1024 * 1024 / self.sector_size
103
104 # We need to handle subvolumes for btrfs
105 if fstype == "btrfs" and fsopts and fsopts.find("subvol=") != -1:
106 self.btrfscmd=find_binary_path("btrfs")
107 subvol = None
108 opts = fsopts.split(",")
109 for opt in opts:
110 if opt.find("subvol=") != -1:
111 subvol = opt.replace("subvol=", "").strip()
112 break
113 if not subvol:
114 raise MountError("No subvolume: %s" % fsopts)
115 self.subvolumes.append({'size': size, # In sectors
116 'mountpoint': mountpoint, # Mount relative to chroot
117 'fstype': fstype, # Filesystem type
118 'fsopts': fsopts, # Filesystem mount options
119 'disk_name': disk_name, # physical disk name holding partition
120 'device': None, # kpartx device node for partition
121 'mount': None, # Mount object
122 'subvol': subvol, # Subvolume name
123 'boot': boot, # Bootable flag
124 'mounted': False # Mount flag
125 })
126
127 # We still need partition for "/" or non-subvolume
128 if mountpoint == "/" or not fsopts or fsopts.find("subvol=") == -1:
129 # Don't need subvolume for "/" because it will be set as default subvolume
130 if fsopts and fsopts.find("subvol=") != -1:
131 opts = fsopts.split(",")
132 for opt in opts:
133 if opt.strip().startswith("subvol="):
134 opts.remove(opt)
135 break
136 fsopts = ",".join(opts)
137
138 part = { 'ks_pnum' : ks_pnum, # Partition number in the KS file
139 'size': size, # In sectors
140 'mountpoint': mountpoint, # Mount relative to chroot
141 'source_file': source_file, # partition contents
142 'fstype': fstype, # Filesystem type
143 'fsopts': fsopts, # Filesystem mount options
144 'label': label, # Partition label
145 'disk_name': disk_name, # physical disk name holding partition
146 'device': None, # kpartx device node for partition
147 'mount': None, # Mount object
148 'num': None, # Partition number
149 'boot': boot, # Bootable flag
150 'align': align, # Partition alignment
151 'part_type' : part_type, # Partition type
152 'partuuid': None } # Partition UUID (GPT-only)
153
154 self.__add_partition(part)
155
156 def layout_partitions(self, ptable_format = "msdos"):
157 """ Layout the partitions, meaning calculate the position of every
158 partition on the disk. The 'ptable_format' parameter defines the
159 partition table format, and may be either "msdos" or "gpt". """
160
161 msger.debug("Assigning %s partitions to disks" % ptable_format)
162
163 if ptable_format not in ('msdos', 'gpt'):
164 raise MountError("Unknown partition table format '%s', supported " \
165 "formats are: 'msdos' and 'gpt'" % ptable_format)
166
167 if self._partitions_layed_out:
168 return
169
170 self._partitions_layed_out = True
171
172 # Go through partitions in the order they are added in .ks file
173 for n in range(len(self.partitions)):
174 p = self.partitions[n]
175
176 if not self.disks.has_key(p['disk_name']):
177 raise MountError("No disk %s for partition %s" \
178 % (p['disk_name'], p['mountpoint']))
179
180 if p['part_type'] and ptable_format != 'gpt':
181 # The --part-type can also be implemented for MBR partitions,
182 # in which case it would map to the 1-byte "partition type"
183 # filed at offset 3 of the partition entry.
184 raise MountError("setting custom partition type is only " \
185 "imlemented for GPT partitions")
186
187 # Get the disk where the partition is located
188 d = self.disks[p['disk_name']]
189 d['numpart'] += 1
190 d['ptable_format'] = ptable_format
191
192 if d['numpart'] == 1:
193 if ptable_format == "msdos":
194 overhead = MBR_OVERHEAD
195 else:
196 overhead = GPT_OVERHEAD
197
198 # Skip one sector required for the partitioning scheme overhead
199 d['offset'] += overhead
200 # Steal few sectors from the first partition to offset for the
201 # partitioning overhead
202 p['size'] -= overhead
203
204 if p['align']:
205 # If not first partition and we do have alignment set we need
206 # to align the partition.
207 # FIXME: This leaves a empty spaces to the disk. To fill the
208 # gaps we could enlargea the previous partition?
209
210 # Calc how much the alignment is off.
211 align_sectors = d['offset'] % (p['align'] * 1024 / self.sector_size)
212 # We need to move forward to the next alignment point
213 align_sectors = (p['align'] * 1024 / self.sector_size) - align_sectors
214
215 msger.debug("Realignment for %s%s with %s sectors, original"
216 " offset %s, target alignment is %sK." %
217 (p['disk_name'], d['numpart'], align_sectors,
218 d['offset'], p['align']))
219
220 # increase the offset so we actually start the partition on right alignment
221 d['offset'] += align_sectors
222
223 p['start'] = d['offset']
224 d['offset'] += p['size']
225
226 p['type'] = 'primary'
227 p['num'] = d['numpart']
228
229 if d['ptable_format'] == "msdos":
230 if d['numpart'] > 2:
231 # Every logical partition requires an additional sector for
232 # the EBR, so steal the last sector from the end of each
233 # partition starting from the 3rd one for the EBR. This
234 # will make sure the logical partitions are aligned
235 # correctly.
236 p['size'] -= 1
237
238 if d['numpart'] > 3:
239 p['type'] = 'logical'
240 p['num'] = d['numpart'] + 1
241
242 d['partitions'].append(n)
243 msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d "
244 "sectors (%d bytes)." \
245 % (p['mountpoint'], p['disk_name'], p['num'],
246 p['start'], p['start'] + p['size'] - 1,
247 p['size'], p['size'] * self.sector_size))
248
249 # Once all the partitions have been layed out, we can calculate the
250 # minumim disk sizes.
251 for disk_name, d in self.disks.items():
252 d['min_size'] = d['offset']
253 if d['ptable_format'] == 'gpt':
254 # Account for the backup partition table at the end of the disk
255 d['min_size'] += GPT_OVERHEAD
256
257 d['min_size'] *= self.sector_size
258
259 def __run_parted(self, args):
260 """ Run parted with arguments specified in the 'args' list. """
261
262 args.insert(0, self.parted)
263 msger.debug(args)
264
265 rc, out = runner.runtool(args, catch = 3)
266 out = out.strip()
267 if out:
268 msger.debug('"parted" output: %s' % out)
269
270 if rc != 0:
271 # We don't throw exception when return code is not 0, because
272 # parted always fails to reload part table with loop devices. This
273 # prevents us from distinguishing real errors based on return
274 # code.
275 msger.debug("WARNING: parted returned '%s' instead of 0" % rc)
276
277 def __create_partition(self, device, parttype, fstype, start, size):
278 """ Create a partition on an image described by the 'device' object. """
279
280 # Start is included to the size so we need to substract one from the end.
281 end = start + size - 1
282 msger.debug("Added '%s' partition, sectors %d-%d, size %d sectors" %
283 (parttype, start, end, size))
284
285 args = ["-s", device, "unit", "s", "mkpart", parttype]
286 if fstype:
287 args.extend([fstype])
288 args.extend(["%d" % start, "%d" % end])
289
290 return self.__run_parted(args)
291
292 def __format_disks(self):
293 self.layout_partitions()
294
295 if self.skipformat:
296 msger.debug("Skipping disk format, because skipformat flag is set.")
297 return
298
299 for dev in self.disks.keys():
300 d = self.disks[dev]
301 msger.debug("Initializing partition table for %s" % \
302 (d['disk'].device))
303 self.__run_parted(["-s", d['disk'].device, "mklabel",
304 d['ptable_format']])
305
306 msger.debug("Creating partitions")
307
308 for p in self.partitions:
309 d = self.disks[p['disk_name']]
310 if d['ptable_format'] == "msdos" and p['num'] == 5:
311 # The last sector of the 3rd partition was reserved for the EBR
312 # of the first _logical_ partition. This is why the extended
313 # partition should start one sector before the first logical
314 # partition.
315 self.__create_partition(d['disk'].device, "extended",
316 None, p['start'] - 1,
317 d['offset'] - p['start'])
318
319 if p['fstype'] == "swap":
320 parted_fs_type = "linux-swap"
321 elif p['fstype'] == "vfat":
322 parted_fs_type = "fat32"
323 elif p['fstype'] == "msdos":
324 parted_fs_type = "fat16"
325 else:
326 # Type for ext2/ext3/ext4/btrfs
327 parted_fs_type = "ext2"
328
329 # Boot ROM of OMAP boards require vfat boot partition to have an
330 # even number of sectors.
331 if p['mountpoint'] == "/boot" and p['fstype'] in ["vfat", "msdos"] \
332 and p['size'] % 2:
333 msger.debug("Substracting one sector from '%s' partition to " \
334 "get even number of sectors for the partition" % \
335 p['mountpoint'])
336 p['size'] -= 1
337
338 self.__create_partition(d['disk'].device, p['type'],
339 parted_fs_type, p['start'], p['size'])
340
341 if p['boot']:
342 if d['ptable_format'] == 'gpt':
343 flag_name = "legacy_boot"
344 else:
345 flag_name = "boot"
346 msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \
347 (flag_name, p['num'], d['disk'].device))
348 self.__run_parted(["-s", d['disk'].device, "set",
349 "%d" % p['num'], flag_name, "on"])
350
351 # Parted defaults to enabling the lba flag for fat16 partitions,
352 # which causes compatibility issues with some firmware (and really
353 # isn't necessary).
354 if parted_fs_type == "fat16":
355 if d['ptable_format'] == 'msdos':
356 msger.debug("Disable 'lba' flag for partition '%s' on disk '%s'" % \
357 (p['num'], d['disk'].device))
358 self.__run_parted(["-s", d['disk'].device, "set",
359 "%d" % p['num'], "lba", "off"])
360
361 # If the partition table format is "gpt", find out PARTUUIDs for all
362 # the partitions. And if users specified custom parition type UUIDs,
363 # set them.
364 for disk_name, disk in self.disks.items():
365 if disk['ptable_format'] != 'gpt':
366 continue
367
368 pnum = 0
369 gpt_parser = GptParser(d['disk'].device, SECTOR_SIZE)
370 # Iterate over all GPT partitions on this disk
371 for entry in gpt_parser.get_partitions():
372 pnum += 1
373 # Find the matching partition in the 'self.partitions' list
374 for n in d['partitions']:
375 p = self.partitions[n]
376 if p['num'] == pnum:
377 # Found, fetch PARTUUID (partition's unique ID)
378 p['partuuid'] = entry['part_uuid']
379 msger.debug("PARTUUID for partition %d on disk '%s' " \
380 "(mount point '%s') is '%s'" % (pnum, \
381 disk_name, p['mountpoint'], p['partuuid']))
382 if p['part_type']:
383 entry['type_uuid'] = p['part_type']
384 msger.debug("Change type of partition %d on disk " \
385 "'%s' (mount point '%s') to '%s'" % \
386 (pnum, disk_name, p['mountpoint'],
387 p['part_type']))
388 gpt_parser.change_partition(entry)
389
390 del gpt_parser
391
392 def __map_partitions(self):
393 """Load it if dm_snapshot isn't loaded. """
394 load_module("dm_snapshot")
395
396 for dev in self.disks.keys():
397 d = self.disks[dev]
398 if d['mapped']:
399 continue
400
401 msger.debug("Running kpartx on %s" % d['disk'].device )
402 rc, kpartxOutput = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device])
403 kpartxOutput = kpartxOutput.splitlines()
404
405 if rc != 0:
406 raise MountError("Failed to query partition mapping for '%s'" %
407 d['disk'].device)
408
409 # Strip trailing blank and mask verbose output
410 i = 0
411 while i < len(kpartxOutput) and kpartxOutput[i][0:4] != "loop":
412 i = i + 1
413 kpartxOutput = kpartxOutput[i:]
414
415 # Make sure kpartx reported the right count of partitions
416 if len(kpartxOutput) != d['numpart']:
417 # If this disk has more than 3 partitions, then in case of MBR
418 # paritions there is an extended parition. Different versions
419 # of kpartx behave differently WRT the extended partition -
420 # some map it, some ignore it. This is why we do the below hack
421 # - if kpartx reported one more partition and the partition
422 # table type is "msdos" and the amount of partitions is more
423 # than 3, we just assume kpartx mapped the extended parition
424 # and we remove it.
425 if len(kpartxOutput) == d['numpart'] + 1 \
426 and d['ptable_format'] == 'msdos' and len(kpartxOutput) > 3:
427 kpartxOutput.pop(3)
428 else:
429 raise MountError("Unexpected number of partitions from " \
430 "kpartx: %d != %d" % \
431 (len(kpartxOutput), d['numpart']))
432
433 for i in range(len(kpartxOutput)):
434 line = kpartxOutput[i]
435 newdev = line.split()[0]
436 mapperdev = "/dev/mapper/" + newdev
437 loopdev = d['disk'].device + newdev[-1]
438
439 msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev))
440 pnum = d['partitions'][i]
441 self.partitions[pnum]['device'] = loopdev
442
443 # grub's install wants partitions to be named
444 # to match their parent device + partition num
445 # kpartx doesn't work like this, so we add compat
446 # symlinks to point to /dev/mapper
447 if os.path.lexists(loopdev):
448 os.unlink(loopdev)
449 os.symlink(mapperdev, loopdev)
450
451 msger.debug("Adding partx mapping for %s" % d['disk'].device)
452 rc = runner.show([self.kpartx, "-v", "-a", d['disk'].device])
453
454 if rc != 0:
455 # Make sure that the device maps are also removed on error case.
456 # The d['mapped'] isn't set to True if the kpartx fails so
457 # failed mapping will not be cleaned on cleanup either.
458 runner.quiet([self.kpartx, "-d", d['disk'].device])
459 raise MountError("Failed to map partitions for '%s'" %
460 d['disk'].device)
461
462 # FIXME: there is a bit delay for multipath device setup,
463 # wait 10ms for the setup
464 import time
465 time.sleep(10)
466 d['mapped'] = True
467
468 def __unmap_partitions(self):
469 for dev in self.disks.keys():
470 d = self.disks[dev]
471 if not d['mapped']:
472 continue
473
474 msger.debug("Removing compat symlinks")
475 for pnum in d['partitions']:
476 if self.partitions[pnum]['device'] != None:
477 os.unlink(self.partitions[pnum]['device'])
478 self.partitions[pnum]['device'] = None
479
480 msger.debug("Unmapping %s" % d['disk'].device)
481 rc = runner.quiet([self.kpartx, "-d", d['disk'].device])
482 if rc != 0:
483 raise MountError("Failed to unmap partitions for '%s'" %
484 d['disk'].device)
485
486 d['mapped'] = False
487
488 def __calculate_mountorder(self):
489 msger.debug("Calculating mount order")
490 for p in self.partitions:
491 if p['mountpoint']:
492 self.mountOrder.append(p['mountpoint'])
493 self.unmountOrder.append(p['mountpoint'])
494
495 self.mountOrder.sort()
496 self.unmountOrder.sort()
497 self.unmountOrder.reverse()
498
499 def cleanup(self):
500 Mount.cleanup(self)
501 if self.disks:
502 self.__unmap_partitions()
503 for dev in self.disks.keys():
504 d = self.disks[dev]
505 try:
506 d['disk'].cleanup()
507 except:
508 pass
509
510 def unmount(self):
511 self.__unmount_subvolumes()
512 for mp in self.unmountOrder:
513 if mp == 'swap':
514 continue
515 p = None
516 for p1 in self.partitions:
517 if p1['mountpoint'] == mp:
518 p = p1
519 break
520
521 if p['mount'] != None:
522 try:
523 # Create subvolume snapshot here
524 if p['fstype'] == "btrfs" and p['mountpoint'] == "/" and not self.snapshot_created:
525 self.__create_subvolume_snapshots(p, p["mount"])
526 p['mount'].cleanup()
527 except:
528 pass
529 p['mount'] = None
530
531 # Only for btrfs
532 def __get_subvolume_id(self, rootpath, subvol):
533 if not self.btrfscmd:
534 self.btrfscmd=find_binary_path("btrfs")
535 argv = [ self.btrfscmd, "subvolume", "list", rootpath ]
536
537 rc, out = runner.runtool(argv)
538 msger.debug(out)
539
540 if rc != 0:
541 raise MountError("Failed to get subvolume id from %s', return code: %d." % (rootpath, rc))
542
543 subvolid = -1
544 for line in out.splitlines():
545 if line.endswith(" path %s" % subvol):
546 subvolid = line.split()[1]
547 if not subvolid.isdigit():
548 raise MountError("Invalid subvolume id: %s" % subvolid)
549 subvolid = int(subvolid)
550 break
551 return subvolid
552
553 def __create_subvolume_metadata(self, p, pdisk):
554 if len(self.subvolumes) == 0:
555 return
556
557 argv = [ self.btrfscmd, "subvolume", "list", pdisk.mountdir ]
558 rc, out = runner.runtool(argv)
559 msger.debug(out)
560
561 if rc != 0:
562 raise MountError("Failed to get subvolume id from %s', return code: %d." % (pdisk.mountdir, rc))
563
564 subvolid_items = out.splitlines()
565 subvolume_metadata = ""
566 for subvol in self.subvolumes:
567 for line in subvolid_items:
568 if line.endswith(" path %s" % subvol["subvol"]):
569 subvolid = line.split()[1]
570 if not subvolid.isdigit():
571 raise MountError("Invalid subvolume id: %s" % subvolid)
572
573 subvolid = int(subvolid)
574 opts = subvol["fsopts"].split(",")
575 for opt in opts:
576 if opt.strip().startswith("subvol="):
577 opts.remove(opt)
578 break
579 fsopts = ",".join(opts)
580 subvolume_metadata += "%d\t%s\t%s\t%s\n" % (subvolid, subvol["subvol"], subvol['mountpoint'], fsopts)
581
582 if subvolume_metadata:
583 fd = open("%s/.subvolume_metadata" % pdisk.mountdir, "w")
584 fd.write(subvolume_metadata)
585 fd.close()
586
587 def __get_subvolume_metadata(self, p, pdisk):
588 subvolume_metadata_file = "%s/.subvolume_metadata" % pdisk.mountdir
589 if not os.path.exists(subvolume_metadata_file):
590 return
591
592 fd = open(subvolume_metadata_file, "r")
593 content = fd.read()
594 fd.close()
595
596 for line in content.splitlines():
597 items = line.split("\t")
598 if items and len(items) == 4:
599 self.subvolumes.append({'size': 0, # In sectors
600 'mountpoint': items[2], # Mount relative to chroot
601 'fstype': "btrfs", # Filesystem type
602 'fsopts': items[3] + ",subvol=%s" % items[1], # Filesystem mount options
603 'disk_name': p['disk_name'], # physical disk name holding partition
604 'device': None, # kpartx device node for partition
605 'mount': None, # Mount object
606 'subvol': items[1], # Subvolume name
607 'boot': False, # Bootable flag
608 'mounted': False # Mount flag
609 })
610
611 def __create_subvolumes(self, p, pdisk):
612 """ Create all the subvolumes. """
613
614 for subvol in self.subvolumes:
615 argv = [ self.btrfscmd, "subvolume", "create", pdisk.mountdir + "/" + subvol["subvol"]]
616
617 rc = runner.show(argv)
618 if rc != 0:
619 raise MountError("Failed to create subvolume '%s', return code: %d." % (subvol["subvol"], rc))
620
621 # Set default subvolume, subvolume for "/" is default
622 subvol = None
623 for subvolume in self.subvolumes:
624 if subvolume["mountpoint"] == "/" and p['disk_name'] == subvolume['disk_name']:
625 subvol = subvolume
626 break
627
628 if subvol:
629 # Get default subvolume id
630 subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
631 # Set default subvolume
632 if subvolid != -1:
633 rc = runner.show([ self.btrfscmd, "subvolume", "set-default", "%d" % subvolid, pdisk.mountdir])
634 if rc != 0:
635 raise MountError("Failed to set default subvolume id: %d', return code: %d." % (subvolid, rc))
636
637 self.__create_subvolume_metadata(p, pdisk)
638
639 def __mount_subvolumes(self, p, pdisk):
640 if self.skipformat:
641 # Get subvolume info
642 self.__get_subvolume_metadata(p, pdisk)
643 # Set default mount options
644 if len(self.subvolumes) != 0:
645 for subvol in self.subvolumes:
646 if subvol["mountpoint"] == p["mountpoint"] == "/":
647 opts = subvol["fsopts"].split(",")
648 for opt in opts:
649 if opt.strip().startswith("subvol="):
650 opts.remove(opt)
651 break
652 pdisk.fsopts = ",".join(opts)
653 break
654
655 if len(self.subvolumes) == 0:
656 # Return directly if no subvolumes
657 return
658
659 # Remount to make default subvolume mounted
660 rc = runner.show([self.umountcmd, pdisk.mountdir])
661 if rc != 0:
662 raise MountError("Failed to umount %s" % pdisk.mountdir)
663
664 rc = runner.show([self.mountcmd, "-o", pdisk.fsopts, pdisk.disk.device, pdisk.mountdir])
665 if rc != 0:
666 raise MountError("Failed to umount %s" % pdisk.mountdir)
667
668 for subvol in self.subvolumes:
669 if subvol["mountpoint"] == "/":
670 continue
671 subvolid = self. __get_subvolume_id(pdisk.mountdir, subvol["subvol"])
672 if subvolid == -1:
673 msger.debug("WARNING: invalid subvolume %s" % subvol["subvol"])
674 continue
675 # Replace subvolume name with subvolume ID
676 opts = subvol["fsopts"].split(",")
677 for opt in opts:
678 if opt.strip().startswith("subvol="):
679 opts.remove(opt)
680 break
681
682 opts.extend(["subvolrootid=0", "subvol=%s" % subvol["subvol"]])
683 fsopts = ",".join(opts)
684 subvol['fsopts'] = fsopts
685 mountpoint = self.mountdir + subvol['mountpoint']
686 makedirs(mountpoint)
687 rc = runner.show([self.mountcmd, "-o", fsopts, pdisk.disk.device, mountpoint])
688 if rc != 0:
689 raise MountError("Failed to mount subvolume %s to %s" % (subvol["subvol"], mountpoint))
690 subvol["mounted"] = True
691
692 def __unmount_subvolumes(self):
693 """ It may be called multiple times, so we need to chekc if it is still mounted. """
694 for subvol in self.subvolumes:
695 if subvol["mountpoint"] == "/":
696 continue
697 if not subvol["mounted"]:
698 continue
699 mountpoint = self.mountdir + subvol['mountpoint']
700 rc = runner.show([self.umountcmd, mountpoint])
701 if rc != 0:
702 raise MountError("Failed to unmount subvolume %s from %s" % (subvol["subvol"], mountpoint))
703 subvol["mounted"] = False
704
705 def __create_subvolume_snapshots(self, p, pdisk):
706 import time
707
708 if self.snapshot_created:
709 return
710
711 # Remount with subvolid=0
712 rc = runner.show([self.umountcmd, pdisk.mountdir])
713 if rc != 0:
714 raise MountError("Failed to umount %s" % pdisk.mountdir)
715 if pdisk.fsopts:
716 mountopts = pdisk.fsopts + ",subvolid=0"
717 else:
718 mountopts = "subvolid=0"
719 rc = runner.show([self.mountcmd, "-o", mountopts, pdisk.disk.device, pdisk.mountdir])
720 if rc != 0:
721 raise MountError("Failed to umount %s" % pdisk.mountdir)
722
723 # Create all the subvolume snapshots
724 snapshotts = time.strftime("%Y%m%d-%H%M")
725 for subvol in self.subvolumes:
726 subvolpath = pdisk.mountdir + "/" + subvol["subvol"]
727 snapshotpath = subvolpath + "_%s-1" % snapshotts
728 rc = runner.show([ self.btrfscmd, "subvolume", "snapshot", subvolpath, snapshotpath ])
729 if rc != 0:
730 raise MountError("Failed to create subvolume snapshot '%s' for '%s', return code: %d." % (snapshotpath, subvolpath, rc))
731
732 self.snapshot_created = True
733
734 def __install_partition(self, num, source_file, start, size):
735 """
736 Install source_file contents into a partition.
737 """
738 if not source_file: # nothing to install
739 return
740
741 # Start is included in the size so need to substract one from the end.
742 end = start + size - 1
743 msger.debug("Installed %s in partition %d, sectors %d-%d, size %d sectors" % (source_file, num, start, end, size))
744
745 dd_cmd = "dd if=%s of=%s bs=%d seek=%d count=%d conv=notrunc" % \
746 (source_file, self.image_file, self.sector_size, start, size)
747 rc, out = exec_cmd(dd_cmd)
748
749
750 def install(self, image_file):
751 msger.debug("Installing partitions")
752
753 self.image_file = image_file
754
755 for p in self.partitions:
756 d = self.disks[p['disk_name']]
757 if d['ptable_format'] == "msdos" and p['num'] == 5:
758 # The last sector of the 3rd partition was reserved for the EBR
759 # of the first _logical_ partition. This is why the extended
760 # partition should start one sector before the first logical
761 # partition.
762 self.__install_partition(p['num'], p['source_file'],
763 p['start'] - 1,
764 d['offset'] - p['start'])
765
766 self.__install_partition(p['num'], p['source_file'],
767 p['start'], p['size'])
768
769 def mount(self):
770 for dev in self.disks.keys():
771 d = self.disks[dev]
772 d['disk'].create()
773
774 self.__format_disks()
775
776 self.__calculate_mountorder()
777
778 return
779
780 def resparse(self, size = None):
781 # Can't re-sparse a disk image - too hard
782 pass
diff --git a/scripts/lib/mic/utils/proxy.py b/scripts/lib/mic/utils/proxy.py
new file mode 100644
index 0000000000..91451a2d01
--- /dev/null
+++ b/scripts/lib/mic/utils/proxy.py
@@ -0,0 +1,183 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import urlparse
20
21_my_proxies = {}
22_my_noproxy = None
23_my_noproxy_list = []
24
25def set_proxy_environ():
26 global _my_noproxy, _my_proxies
27 if not _my_proxies:
28 return
29 for key in _my_proxies.keys():
30 os.environ[key + "_proxy"] = _my_proxies[key]
31 if not _my_noproxy:
32 return
33 os.environ["no_proxy"] = _my_noproxy
34
35def unset_proxy_environ():
36 for env in ('http_proxy',
37 'https_proxy',
38 'ftp_proxy',
39 'all_proxy'):
40 if env in os.environ:
41 del os.environ[env]
42
43 ENV=env.upper()
44 if ENV in os.environ:
45 del os.environ[ENV]
46
47def _set_proxies(proxy = None, no_proxy = None):
48 """Return a dictionary of scheme -> proxy server URL mappings.
49 """
50
51 global _my_noproxy, _my_proxies
52 _my_proxies = {}
53 _my_noproxy = None
54 proxies = []
55 if proxy:
56 proxies.append(("http_proxy", proxy))
57 if no_proxy:
58 proxies.append(("no_proxy", no_proxy))
59
60 # Get proxy settings from environment if not provided
61 if not proxy and not no_proxy:
62 proxies = os.environ.items()
63
64 # Remove proxy env variables, urllib2 can't handle them correctly
65 unset_proxy_environ()
66
67 for name, value in proxies:
68 name = name.lower()
69 if value and name[-6:] == '_proxy':
70 if name[0:2] != "no":
71 _my_proxies[name[:-6]] = value
72 else:
73 _my_noproxy = value
74
75def _ip_to_int(ip):
76 ipint=0
77 shift=24
78 for dec in ip.split("."):
79 ipint |= int(dec) << shift
80 shift -= 8
81 return ipint
82
83def _int_to_ip(val):
84 ipaddr=""
85 shift=0
86 for i in range(4):
87 dec = val >> shift
88 dec &= 0xff
89 ipaddr = ".%d%s" % (dec, ipaddr)
90 shift += 8
91 return ipaddr[1:]
92
93def _isip(host):
94 if host.replace(".", "").isdigit():
95 return True
96 return False
97
98def _set_noproxy_list():
99 global _my_noproxy, _my_noproxy_list
100 _my_noproxy_list = []
101 if not _my_noproxy:
102 return
103 for item in _my_noproxy.split(","):
104 item = item.strip()
105 if not item:
106 continue
107
108 if item[0] != '.' and item.find("/") == -1:
109 # Need to match it
110 _my_noproxy_list.append({"match":0,"needle":item})
111
112 elif item[0] == '.':
113 # Need to match at tail
114 _my_noproxy_list.append({"match":1,"needle":item})
115
116 elif item.find("/") > 3:
117 # IP/MASK, need to match at head
118 needle = item[0:item.find("/")].strip()
119 ip = _ip_to_int(needle)
120 netmask = 0
121 mask = item[item.find("/")+1:].strip()
122
123 if mask.isdigit():
124 netmask = int(mask)
125 netmask = ~((1<<(32-netmask)) - 1)
126 ip &= netmask
127 else:
128 shift=24
129 netmask=0
130 for dec in mask.split("."):
131 netmask |= int(dec) << shift
132 shift -= 8
133 ip &= netmask
134
135 _my_noproxy_list.append({"match":2,"needle":ip,"netmask":netmask})
136
137def _isnoproxy(url):
138 (scheme, host, path, parm, query, frag) = urlparse.urlparse(url)
139
140 if '@' in host:
141 user_pass, host = host.split('@', 1)
142
143 if ':' in host:
144 host, port = host.split(':', 1)
145
146 hostisip = _isip(host)
147 for item in _my_noproxy_list:
148 if hostisip and item["match"] <= 1:
149 continue
150
151 if item["match"] == 2 and hostisip:
152 if (_ip_to_int(host) & item["netmask"]) == item["needle"]:
153 return True
154
155 if item["match"] == 0:
156 if host == item["needle"]:
157 return True
158
159 if item["match"] == 1:
160 if host.rfind(item["needle"]) > 0:
161 return True
162
163 return False
164
165def set_proxies(proxy = None, no_proxy = None):
166 _set_proxies(proxy, no_proxy)
167 _set_noproxy_list()
168 set_proxy_environ()
169
170def get_proxy_for(url):
171 if url.startswith('file:') or _isnoproxy(url):
172 return None
173
174 type = url[0:url.index(":")]
175 proxy = None
176 if _my_proxies.has_key(type):
177 proxy = _my_proxies[type]
178 elif _my_proxies.has_key("http"):
179 proxy = _my_proxies["http"]
180 else:
181 proxy = None
182
183 return proxy
diff --git a/scripts/lib/mic/utils/rpmmisc.py b/scripts/lib/mic/utils/rpmmisc.py
new file mode 100644
index 0000000000..af15763e18
--- /dev/null
+++ b/scripts/lib/mic/utils/rpmmisc.py
@@ -0,0 +1,600 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2008, 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import sys
20import re
21import rpm
22
23from mic import msger
24from mic.utils.errors import CreatorError
25from mic.utils.proxy import get_proxy_for
26from mic.utils import runner
27
28
29class RPMInstallCallback:
30 """ Command line callback class for callbacks from the RPM library.
31 """
32
33 def __init__(self, ts, output=1):
34 self.output = output
35 self.callbackfilehandles = {}
36 self.total_actions = 0
37 self.total_installed = 0
38 self.installed_pkg_names = []
39 self.total_removed = 0
40 self.mark = "+"
41 self.marks = 40
42 self.lastmsg = None
43 self.tsInfo = None # this needs to be set for anything else to work
44 self.ts = ts
45 self.filelog = False
46 self.logString = []
47 self.headmsg = "Installing"
48
49 def _dopkgtup(self, hdr):
50 tmpepoch = hdr['epoch']
51 if tmpepoch is None: epoch = '0'
52 else: epoch = str(tmpepoch)
53
54 return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
55
56 def _makeHandle(self, hdr):
57 handle = '%s:%s.%s-%s-%s' % (hdr['epoch'], hdr['name'], hdr['version'],
58 hdr['release'], hdr['arch'])
59
60 return handle
61
62 def _localprint(self, msg):
63 if self.output:
64 msger.info(msg)
65
66 def _makefmt(self, percent, progress = True):
67 l = len(str(self.total_actions))
68 size = "%s.%s" % (l, l)
69 fmt_done = "[%" + size + "s/%" + size + "s]"
70 done = fmt_done % (self.total_installed + self.total_removed,
71 self.total_actions)
72 marks = self.marks - (2 * l)
73 width = "%s.%s" % (marks, marks)
74 fmt_bar = "%-" + width + "s"
75 if progress:
76 bar = fmt_bar % (self.mark * int(marks * (percent / 100.0)), )
77 fmt = "\r %-10.10s: %-20.20s " + bar + " " + done
78 else:
79 bar = fmt_bar % (self.mark * marks, )
80 fmt = " %-10.10s: %-20.20s " + bar + " " + done
81 return fmt
82
83 def _logPkgString(self, hdr):
84 """return nice representation of the package for the log"""
85 (n,a,e,v,r) = self._dopkgtup(hdr)
86 if e == '0':
87 pkg = '%s.%s %s-%s' % (n, a, v, r)
88 else:
89 pkg = '%s.%s %s:%s-%s' % (n, a, e, v, r)
90
91 return pkg
92
93 def callback(self, what, bytes, total, h, user):
94 if what == rpm.RPMCALLBACK_TRANS_START:
95 if bytes == 6:
96 self.total_actions = total
97
98 elif what == rpm.RPMCALLBACK_TRANS_PROGRESS:
99 pass
100
101 elif what == rpm.RPMCALLBACK_TRANS_STOP:
102 pass
103
104 elif what == rpm.RPMCALLBACK_INST_OPEN_FILE:
105 self.lastmsg = None
106 hdr = None
107 if h is not None:
108 try:
109 hdr, rpmloc = h
110 except:
111 rpmloc = h
112 hdr = readRpmHeader(self.ts, h)
113
114 handle = self._makeHandle(hdr)
115 fd = os.open(rpmloc, os.O_RDONLY)
116 self.callbackfilehandles[handle]=fd
117 if hdr['name'] not in self.installed_pkg_names:
118 self.installed_pkg_names.append(hdr['name'])
119 self.total_installed += 1
120 return fd
121 else:
122 self._localprint("No header - huh?")
123
124 elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
125 hdr = None
126 if h is not None:
127 try:
128 hdr, rpmloc = h
129 except:
130 rpmloc = h
131 hdr = readRpmHeader(self.ts, h)
132
133 handle = self._makeHandle(hdr)
134 os.close(self.callbackfilehandles[handle])
135 fd = 0
136
137 # log stuff
138 #pkgtup = self._dopkgtup(hdr)
139 self.logString.append(self._logPkgString(hdr))
140
141 elif what == rpm.RPMCALLBACK_INST_PROGRESS:
142 if h is not None:
143 percent = (self.total_installed*100L)/self.total_actions
144 if total > 0:
145 try:
146 hdr, rpmloc = h
147 except:
148 rpmloc = h
149
150 m = re.match("(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
151 if m:
152 pkgname = m.group(1)
153 else:
154 pkgname = os.path.basename(rpmloc)
155 if self.output:
156 fmt = self._makefmt(percent)
157 msg = fmt % (self.headmsg, pkgname)
158 if msg != self.lastmsg:
159 self.lastmsg = msg
160
161 msger.info(msg)
162
163 if self.total_installed == self.total_actions:
164 msger.raw('')
165 msger.verbose('\n'.join(self.logString))
166
167 elif what == rpm.RPMCALLBACK_UNINST_START:
168 pass
169
170 elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
171 pass
172
173 elif what == rpm.RPMCALLBACK_UNINST_STOP:
174 self.total_removed += 1
175
176 elif what == rpm.RPMCALLBACK_REPACKAGE_START:
177 pass
178
179 elif what == rpm.RPMCALLBACK_REPACKAGE_STOP:
180 pass
181
182 elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS:
183 pass
184
185def readRpmHeader(ts, filename):
186 """ Read an rpm header. """
187
188 fd = os.open(filename, os.O_RDONLY)
189 h = ts.hdrFromFdno(fd)
190 os.close(fd)
191 return h
192
193def splitFilename(filename):
194 """ Pass in a standard style rpm fullname
195
196 Return a name, version, release, epoch, arch, e.g.::
197 foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
198 1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64
199 """
200
201 if filename[-4:] == '.rpm':
202 filename = filename[:-4]
203
204 archIndex = filename.rfind('.')
205 arch = filename[archIndex+1:]
206
207 relIndex = filename[:archIndex].rfind('-')
208 rel = filename[relIndex+1:archIndex]
209
210 verIndex = filename[:relIndex].rfind('-')
211 ver = filename[verIndex+1:relIndex]
212
213 epochIndex = filename.find(':')
214 if epochIndex == -1:
215 epoch = ''
216 else:
217 epoch = filename[:epochIndex]
218
219 name = filename[epochIndex + 1:verIndex]
220 return name, ver, rel, epoch, arch
221
222def getCanonX86Arch(arch):
223 #
224 if arch == "i586":
225 f = open("/proc/cpuinfo", "r")
226 lines = f.readlines()
227 f.close()
228 for line in lines:
229 if line.startswith("model name") and line.find("Geode(TM)") != -1:
230 return "geode"
231 return arch
232 # only athlon vs i686 isn't handled with uname currently
233 if arch != "i686":
234 return arch
235
236 # if we're i686 and AuthenticAMD, then we should be an athlon
237 f = open("/proc/cpuinfo", "r")
238 lines = f.readlines()
239 f.close()
240 for line in lines:
241 if line.startswith("vendor") and line.find("AuthenticAMD") != -1:
242 return "athlon"
243 # i686 doesn't guarantee cmov, but we depend on it
244 elif line.startswith("flags") and line.find("cmov") == -1:
245 return "i586"
246
247 return arch
248
249def getCanonX86_64Arch(arch):
250 if arch != "x86_64":
251 return arch
252
253 vendor = None
254 f = open("/proc/cpuinfo", "r")
255 lines = f.readlines()
256 f.close()
257 for line in lines:
258 if line.startswith("vendor_id"):
259 vendor = line.split(':')[1]
260 break
261 if vendor is None:
262 return arch
263
264 if vendor.find("Authentic AMD") != -1 or vendor.find("AuthenticAMD") != -1:
265 return "amd64"
266 if vendor.find("GenuineIntel") != -1:
267 return "ia32e"
268 return arch
269
270def getCanonArch():
271 arch = os.uname()[4]
272
273 if (len(arch) == 4 and arch[0] == "i" and arch[2:4] == "86"):
274 return getCanonX86Arch(arch)
275
276 if arch == "x86_64":
277 return getCanonX86_64Arch(arch)
278
279 return arch
280
281# Copy from libsatsolver:poolarch.c, with cleanup
282archPolicies = {
283 "x86_64": "x86_64:i686:i586:i486:i386",
284 "i686": "i686:i586:i486:i386",
285 "i586": "i586:i486:i386",
286 "ia64": "ia64:i686:i586:i486:i386",
287 "armv7tnhl": "armv7tnhl:armv7thl:armv7nhl:armv7hl",
288 "armv7thl": "armv7thl:armv7hl",
289 "armv7nhl": "armv7nhl:armv7hl",
290 "armv7hl": "armv7hl",
291 "armv7l": "armv7l:armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
292 "armv6l": "armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
293 "armv5tejl": "armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
294 "armv5tel": "armv5tel:armv5l:armv4tl:armv4l:armv3l",
295 "armv5l": "armv5l:armv4tl:armv4l:armv3l",
296}
297
298# dict mapping arch -> ( multicompat, best personality, biarch personality )
299multilibArches = {
300 "x86_64": ( "athlon", "x86_64", "athlon" ),
301}
302
303# from yumUtils.py
304arches = {
305 # ia32
306 "athlon": "i686",
307 "i686": "i586",
308 "geode": "i586",
309 "i586": "i486",
310 "i486": "i386",
311 "i386": "noarch",
312
313 # amd64
314 "x86_64": "athlon",
315 "amd64": "x86_64",
316 "ia32e": "x86_64",
317
318 # arm
319 "armv7tnhl": "armv7nhl",
320 "armv7nhl": "armv7hl",
321 "armv7hl": "noarch",
322 "armv7l": "armv6l",
323 "armv6l": "armv5tejl",
324 "armv5tejl": "armv5tel",
325 "armv5tel": "noarch",
326
327 #itanium
328 "ia64": "noarch",
329}
330
331def isMultiLibArch(arch=None):
332 """returns true if arch is a multilib arch, false if not"""
333 if arch is None:
334 arch = getCanonArch()
335
336 if not arches.has_key(arch): # or we could check if it is noarch
337 return False
338
339 if multilibArches.has_key(arch):
340 return True
341
342 if multilibArches.has_key(arches[arch]):
343 return True
344
345 return False
346
347def getBaseArch():
348 myarch = getCanonArch()
349 if not arches.has_key(myarch):
350 return myarch
351
352 if isMultiLibArch(arch=myarch):
353 if multilibArches.has_key(myarch):
354 return myarch
355 else:
356 return arches[myarch]
357
358 if arches.has_key(myarch):
359 basearch = myarch
360 value = arches[basearch]
361 while value != 'noarch':
362 basearch = value
363 value = arches[basearch]
364
365 return basearch
366
367def checkRpmIntegrity(bin_rpm, package):
368 return runner.quiet([bin_rpm, "-K", "--nosignature", package])
369
370def checkSig(ts, package):
371 """ Takes a transaction set and a package, check it's sigs,
372 return 0 if they are all fine
373 return 1 if the gpg key can't be found
374 return 2 if the header is in someway damaged
375 return 3 if the key is not trusted
376 return 4 if the pkg is not gpg or pgp signed
377 """
378
379 value = 0
380 currentflags = ts.setVSFlags(0)
381 fdno = os.open(package, os.O_RDONLY)
382 try:
383 hdr = ts.hdrFromFdno(fdno)
384
385 except rpm.error, e:
386 if str(e) == "public key not availaiable":
387 value = 1
388 if str(e) == "public key not available":
389 value = 1
390 if str(e) == "public key not trusted":
391 value = 3
392 if str(e) == "error reading package header":
393 value = 2
394 else:
395 error, siginfo = getSigInfo(hdr)
396 if error == 101:
397 os.close(fdno)
398 del hdr
399 value = 4
400 else:
401 del hdr
402
403 try:
404 os.close(fdno)
405 except OSError:
406 pass
407
408 ts.setVSFlags(currentflags) # put things back like they were before
409 return value
410
411def getSigInfo(hdr):
412 """ checks signature from an hdr hand back signature information and/or
413 an error code
414 """
415
416 import locale
417 locale.setlocale(locale.LC_ALL, 'C')
418
419 string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|'
420 siginfo = hdr.sprintf(string)
421 if siginfo != '(none)':
422 error = 0
423 sigtype, sigdate, sigid = siginfo.split(',')
424 else:
425 error = 101
426 sigtype = 'MD5'
427 sigdate = 'None'
428 sigid = 'None'
429
430 infotuple = (sigtype, sigdate, sigid)
431 return error, infotuple
432
433def checkRepositoryEULA(name, repo):
434 """ This function is to check the EULA file if provided.
435 return True: no EULA or accepted
436 return False: user declined the EULA
437 """
438
439 import tempfile
440 import shutil
441 import urlparse
442 import urllib2 as u2
443 import httplib
444 from mic.utils.errors import CreatorError
445
446 def _check_and_download_url(u2opener, url, savepath):
447 try:
448 if u2opener:
449 f = u2opener.open(url)
450 else:
451 f = u2.urlopen(url)
452 except u2.HTTPError, httperror:
453 if httperror.code in (404, 503):
454 return None
455 else:
456 raise CreatorError(httperror)
457 except OSError, oserr:
458 if oserr.errno == 2:
459 return None
460 else:
461 raise CreatorError(oserr)
462 except IOError, oserr:
463 if hasattr(oserr, "reason") and oserr.reason.errno == 2:
464 return None
465 else:
466 raise CreatorError(oserr)
467 except u2.URLError, err:
468 raise CreatorError(err)
469 except httplib.HTTPException, e:
470 raise CreatorError(e)
471
472 # save to file
473 licf = open(savepath, "w")
474 licf.write(f.read())
475 licf.close()
476 f.close()
477
478 return savepath
479
480 def _pager_file(savepath):
481
482 if os.path.splitext(savepath)[1].upper() in ('.HTM', '.HTML'):
483 pagers = ('w3m', 'links', 'lynx', 'less', 'more')
484 else:
485 pagers = ('less', 'more')
486
487 file_showed = False
488 for pager in pagers:
489 cmd = "%s %s" % (pager, savepath)
490 try:
491 os.system(cmd)
492 except OSError:
493 continue
494 else:
495 file_showed = True
496 break
497
498 if not file_showed:
499 f = open(savepath)
500 msger.raw(f.read())
501 f.close()
502 msger.pause()
503
504 # when proxy needed, make urllib2 follow it
505 proxy = repo.proxy
506 proxy_username = repo.proxy_username
507 proxy_password = repo.proxy_password
508
509 if not proxy:
510 proxy = get_proxy_for(repo.baseurl[0])
511
512 handlers = []
513 auth_handler = u2.HTTPBasicAuthHandler(u2.HTTPPasswordMgrWithDefaultRealm())
514 u2opener = None
515 if proxy:
516 if proxy_username:
517 proxy_netloc = urlparse.urlsplit(proxy).netloc
518 if proxy_password:
519 proxy_url = 'http://%s:%s@%s' % (proxy_username, proxy_password, proxy_netloc)
520 else:
521 proxy_url = 'http://%s@%s' % (proxy_username, proxy_netloc)
522 else:
523 proxy_url = proxy
524
525 proxy_support = u2.ProxyHandler({'http': proxy_url,
526 'https': proxy_url,
527 'ftp': proxy_url})
528 handlers.append(proxy_support)
529
530 # download all remote files to one temp dir
531 baseurl = None
532 repo_lic_dir = tempfile.mkdtemp(prefix = 'repolic')
533
534 for url in repo.baseurl:
535 tmphandlers = handlers[:]
536
537 (scheme, host, path, parm, query, frag) = urlparse.urlparse(url.rstrip('/') + '/')
538 if scheme not in ("http", "https", "ftp", "ftps", "file"):
539 raise CreatorError("Error: invalid url %s" % url)
540
541 if '@' in host:
542 try:
543 user_pass, host = host.split('@', 1)
544 if ':' in user_pass:
545 user, password = user_pass.split(':', 1)
546 except ValueError, e:
547 raise CreatorError('Bad URL: %s' % url)
548
549 msger.verbose("adding HTTP auth: %s, XXXXXXXX" %(user))
550 auth_handler.add_password(None, host, user, password)
551 tmphandlers.append(auth_handler)
552 url = scheme + "://" + host + path + parm + query + frag
553
554 if tmphandlers:
555 u2opener = u2.build_opener(*tmphandlers)
556
557 # try to download
558 repo_eula_url = urlparse.urljoin(url, "LICENSE.txt")
559 repo_eula_path = _check_and_download_url(
560 u2opener,
561 repo_eula_url,
562 os.path.join(repo_lic_dir, repo.id + '_LICENSE.txt'))
563 if repo_eula_path:
564 # found
565 baseurl = url
566 break
567
568 if not baseurl:
569 shutil.rmtree(repo_lic_dir) #cleanup
570 return True
571
572 # show the license file
573 msger.info('For the software packages in this yum repo:')
574 msger.info(' %s: %s' % (name, baseurl))
575 msger.info('There is an "End User License Agreement" file that need to be checked.')
576 msger.info('Please read the terms and conditions outlined in it and answer the followed qustions.')
577 msger.pause()
578
579 _pager_file(repo_eula_path)
580
581 # Asking for the "Accept/Decline"
582 if not msger.ask('Would you agree to the terms and conditions outlined in the above End User License Agreement?'):
583 msger.warning('Will not install pkgs from this repo.')
584 shutil.rmtree(repo_lic_dir) #cleanup
585 return False
586
587 # try to find support_info.html for extra infomation
588 repo_info_url = urlparse.urljoin(baseurl, "support_info.html")
589 repo_info_path = _check_and_download_url(
590 u2opener,
591 repo_info_url,
592 os.path.join(repo_lic_dir, repo.id + '_support_info.html'))
593 if repo_info_path:
594 msger.info('There is one more file in the repo for additional support information, please read it')
595 msger.pause()
596 _pager_file(repo_info_path)
597
598 #cleanup
599 shutil.rmtree(repo_lic_dir)
600 return True
diff --git a/scripts/lib/mic/utils/runner.py b/scripts/lib/mic/utils/runner.py
new file mode 100644
index 0000000000..fded3c93fa
--- /dev/null
+++ b/scripts/lib/mic/utils/runner.py
@@ -0,0 +1,109 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18import os
19import subprocess
20
21from mic import msger
22
23def runtool(cmdln_or_args, catch=1):
24 """ wrapper for most of the subprocess calls
25 input:
26 cmdln_or_args: can be both args and cmdln str (shell=True)
27 catch: 0, quitely run
28 1, only STDOUT
29 2, only STDERR
30 3, both STDOUT and STDERR
31 return:
32 (rc, output)
33 if catch==0: the output will always None
34 """
35
36 if catch not in (0, 1, 2, 3):
37 # invalid catch selection, will cause exception, that's good
38 return None
39
40 if isinstance(cmdln_or_args, list):
41 cmd = cmdln_or_args[0]
42 shell = False
43 else:
44 import shlex
45 cmd = shlex.split(cmdln_or_args)[0]
46 shell = True
47
48 if catch != 3:
49 dev_null = os.open("/dev/null", os.O_WRONLY)
50
51 if catch == 0:
52 sout = dev_null
53 serr = dev_null
54 elif catch == 1:
55 sout = subprocess.PIPE
56 serr = dev_null
57 elif catch == 2:
58 sout = dev_null
59 serr = subprocess.PIPE
60 elif catch == 3:
61 sout = subprocess.PIPE
62 serr = subprocess.STDOUT
63
64 try:
65 p = subprocess.Popen(cmdln_or_args, stdout=sout,
66 stderr=serr, shell=shell)
67 (sout, serr) = p.communicate()
68 # combine stdout and stderr, filter None out
69 out = ''.join(filter(None, [sout, serr]))
70 except OSError, e:
71 if e.errno == 2:
72 # [Errno 2] No such file or directory
73 msger.error('Cannot run command: %s, lost dependency?' % cmd)
74 else:
75 raise # relay
76 finally:
77 if catch != 3:
78 os.close(dev_null)
79
80 return (p.returncode, out)
81
82def show(cmdln_or_args):
83 # show all the message using msger.verbose
84
85 rc, out = runtool(cmdln_or_args, catch=3)
86
87 if isinstance(cmdln_or_args, list):
88 cmd = ' '.join(cmdln_or_args)
89 else:
90 cmd = cmdln_or_args
91
92 msg = 'running command: "%s"' % cmd
93 if out: out = out.strip()
94 if out:
95 msg += ', with output::'
96 msg += '\n +----------------'
97 for line in out.splitlines():
98 msg += '\n | %s' % line
99 msg += '\n +----------------'
100
101 msger.verbose(msg)
102 return rc
103
104def outs(cmdln_or_args, catch=1):
105 # get the outputs of tools
106 return runtool(cmdln_or_args, catch)[1].strip()
107
108def quiet(cmdln_or_args):
109 return runtool(cmdln_or_args, catch=0)[0]
diff --git a/scripts/lnr b/scripts/lnr
new file mode 100755
index 0000000000..9dacebe095
--- /dev/null
+++ b/scripts/lnr
@@ -0,0 +1,21 @@
1#! /usr/bin/env python
2
3# Create a *relative* symlink, just like ln --relative does but without needing
4# coreutils 8.16.
5
6import sys, os
7
8if len(sys.argv) != 3:
9 print "$ lnr TARGET LINK_NAME"
10 sys.exit(1)
11
12target = sys.argv[1]
13linkname = sys.argv[2]
14
15if os.path.isabs(target):
16 if not os.path.isabs(linkname):
17 linkname = os.path.abspath(linkname)
18 start = os.path.dirname(linkname)
19 target = os.path.relpath(target, start)
20
21os.symlink(target, linkname)
diff --git a/scripts/multilib_header_wrapper.h b/scripts/multilib_header_wrapper.h
new file mode 100644
index 0000000000..5a87540884
--- /dev/null
+++ b/scripts/multilib_header_wrapper.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2005-2011 by Wind River Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 *
22 */
23
24#include <bits/wordsize.h>
25
26#ifdef __WORDSIZE
27
28#if __WORDSIZE == 32
29
30#ifdef _MIPS_SIM
31
32#if _MIPS_SIM == _ABIO32
33#include <ENTER_HEADER_FILENAME_HERE-32.h>
34#elif _MIPS_SIM == _ABIN32
35#include <ENTER_HEADER_FILENAME_HERE-n32.h>
36#else
37#error "Unknown _MIPS_SIM"
38#endif
39
40#else /* _MIPS_SIM is not defined */
41#include <ENTER_HEADER_FILENAME_HERE-32.h>
42#endif
43
44#elif __WORDSIZE == 64
45#include <ENTER_HEADER_FILENAME_HERE-64.h>
46#else
47#error "Unknown __WORDSIZE detected"
48#endif /* matches #if __WORDSIZE == 32 */
49
50#else /* __WORDSIZE is not defined */
51
52#error "__WORDSIZE is not defined"
53
54#endif
55
diff --git a/scripts/native-intercept/chown b/scripts/native-intercept/chown
new file mode 100755
index 0000000000..4f43271c2b
--- /dev/null
+++ b/scripts/native-intercept/chown
@@ -0,0 +1,2 @@
1#! /bin/sh
2echo "Intercept $0: $@ -- do nothing"
diff --git a/scripts/oe-buildenv-internal b/scripts/oe-buildenv-internal
new file mode 100755
index 0000000000..bba6f8fea3
--- /dev/null
+++ b/scripts/oe-buildenv-internal
@@ -0,0 +1,109 @@
1#!/bin/sh
2
3# OE-Core Build Environment Setup Script
4#
5# Copyright (C) 2006-2011 Linux Foundation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21# It is assumed OEROOT is already defined when this is called
22if [ -z "$OEROOT" ]; then
23 echo >&2 "Error: OEROOT is not defined!"
24 return 1
25fi
26
27if [ ! -z "$OECORE_SDK_VERSION" ]; then
28 echo >&2 "Error: The OE SDK/ADT was detected as already being present in this shell environment. Please use a clean shell when sourcing this environment script."
29 return 1
30fi
31
32# Make sure we're not using python v3.x. This check can't go into
33# sanity.bbclass because bitbake's source code doesn't even pass
34# parsing stage when used with python v3, so we catch it here so we
35# can offer a meaningful error message.
36py_v3_check=`/usr/bin/env python --version 2>&1 | grep "Python 3"`
37if [ "$py_v3_check" != "" ]; then
38 echo >&2 "Bitbake is not compatible with python v3"
39 echo >&2 "Please set up python v2 as your default python interpreter"
40 return 1
41fi
42
43# Similarly, we now have code that doesn't parse correctly with older
44# versions of Python, and rather than fixing that and being eternally
45# vigilant for any other new feature use, just check the version here.
46py_v26_check=`python -c 'import sys; print sys.version_info >= (2,7,3)'`
47if [ "$py_v26_check" != "True" ]; then
48 echo >&2 "BitBake requires Python 2.7.3 or later"
49 return 1
50fi
51
52if [ "x$BDIR" = "x" ]; then
53 if [ "x$1" = "x" ]; then
54 BDIR="build"
55 else
56 BDIR="$1"
57 if [ "$BDIR" = "/" ]; then
58 echo >&2 "Error: / is not supported as a build directory."
59 return 1
60 fi
61
62 # Remove any possible trailing slashes. This is used to work around
63 # buggy readlink in Ubuntu 10.04 that doesn't ignore trailing slashes
64 # and hence "readlink -f new_dir_to_be_created/" returns empty.
65 BDIR=`echo $BDIR | sed -re 's|/+$||'`
66
67 BDIR=`readlink -f "$BDIR"`
68 if [ -z "$BDIR" ]; then
69 PARENTDIR=`dirname "$1"`
70 echo >&2 "Error: the directory $PARENTDIR does not exist?"
71 return 1
72 fi
73 fi
74 if [ "x$2" != "x" ]; then
75 BITBAKEDIR="$2"
76 fi
77fi
78if expr "$BDIR" : '/.*' > /dev/null ; then
79 BUILDDIR="$BDIR"
80else
81 BUILDDIR="`pwd`/$BDIR"
82fi
83unset BDIR
84
85if [ "x$BITBAKEDIR" = "x" ]; then
86 BITBAKEDIR="$OEROOT/bitbake$BBEXTRA/"
87fi
88
89BITBAKEDIR=`readlink -f "$BITBAKEDIR"`
90BUILDDIR=`readlink -f "$BUILDDIR"`
91
92if ! (test -d "$BITBAKEDIR"); then
93 echo >&2 "Error: The bitbake directory ($BITBAKEDIR) does not exist! Please ensure a copy of bitbake exists at this location"
94 return 1
95fi
96
97# Make sure our paths are at the beginning of $PATH
98NEWPATHS="${OEROOT}/scripts:$BITBAKEDIR/bin:"
99PATH=$NEWPATHS$(echo $PATH | sed -e "s|:$NEWPATHS|:|g" -e "s|^$NEWPATHS||")
100unset BITBAKEDIR NEWPATHS
101
102# Used by the runqemu script
103export BUILDDIR
104export PATH
105export BB_ENV_EXTRAWHITE="MACHINE DISTRO TCMODE TCLIBC HTTP_PROXY http_proxy \
106HTTPS_PROXY https_proxy FTP_PROXY ftp_proxy FTPS_PROXY ftps_proxy ALL_PROXY \
107all_proxy NO_PROXY no_proxy SSH_AGENT_PID SSH_AUTH_SOCK BB_SRCREV_POLICY \
108SDKMACHINE BB_NUMBER_THREADS BB_NO_NETWORK PARALLEL_MAKE GIT_PROXY_COMMAND \
109SOCKS5_PASSWD SOCKS5_USER SCREENDIR STAMPS_DIR"
diff --git a/scripts/oe-find-native-sysroot b/scripts/oe-find-native-sysroot
new file mode 100755
index 0000000000..81d62b8882
--- /dev/null
+++ b/scripts/oe-find-native-sysroot
@@ -0,0 +1,81 @@
1#!/bin/bash
2#
3# Find a native sysroot to use - either from an in-tree OE build or
4# from a toolchain installation. It then ensures the variable
5# $OECORE_NATIVE_SYSROOT is set to the sysroot's base directory, and sets
6# $PSEUDO to the path of the pseudo binary.
7#
8# This script is intended to be run within other scripts by source'ing
9# it, e.g:
10#
11# SYSROOT_SETUP_SCRIPT=`which oe-find-native-sysroot`
12# . $SYSROOT_SETUP_SCRIPT
13#
14# This script will terminate execution of your calling program unless
15# you set a variable $SKIP_STRICT_SYSROOT_CHECK to a non-empty string
16# beforehand.
17#
18# Copyright (c) 2010 Linux Foundation
19#
20# This program is free software; you can redistribute it and/or modify
21# it under the terms of the GNU General Public License version 2 as
22# published by the Free Software Foundation.
23#
24# This program is distributed in the hope that it will be useful,
25# but WITHOUT ANY WARRANTY; without even the implied warranty of
26# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27# GNU General Public License for more details.
28#
29# You should have received a copy of the GNU General Public License along
30# with this program; if not, write to the Free Software Foundation, Inc.,
31# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32
33if [ "x$OECORE_NATIVE_SYSROOT" = "x" ]; then
34 BITBAKE=`which bitbake 2> /dev/null`
35 if [ "x$BITBAKE" != "x" ]; then
36 if [ "$UID" = "0" ]; then
37 # Root cannot run bitbake unless sanity checking is disabled
38 if [ ! -d "./conf" ]; then
39 echo "Error: root cannot run bitbake by default, and I cannot find a ./conf directory to be able to disable sanity checking"
40 exit 1
41 fi
42 touch conf/sanity.conf
43 OECORE_NATIVE_SYSROOT=`bitbake -e | grep ^STAGING_DIR_NATIVE | cut -d '"' -f2`
44 rm -f conf/sanity.conf
45 else
46 OECORE_NATIVE_SYSROOT=`bitbake -e | grep ^STAGING_DIR_NATIVE | cut -d '"' -f2`
47 fi
48 else
49 echo "Error: Unable to locate bitbake command."
50 echo "Did you forget to source the build environment setup script?"
51
52 if [ -z "$SKIP_STRICT_SYSROOT_CHECK" ]; then
53 exit 1
54 fi
55 fi
56fi
57
58if [ "x$OECORE_NATIVE_SYSROOT" = "x" ]; then
59 # This indicates that there was an error running bitbake -e that
60 # the user needs to be informed of
61 echo "There was an error running bitbake to determine STAGING_DIR_NATIVE"
62 echo "Here is the output from bitbake -e"
63 bitbake -e
64 exit 1
65fi
66
67# Set up pseudo command
68if [ ! -e "$OECORE_NATIVE_SYSROOT/usr/bin/pseudo" ]; then
69 echo "Error: Unable to find pseudo binary in $OECORE_NATIVE_SYSROOT/usr/bin/"
70
71 if [ "x$OECORE_DISTRO_VERSION" = "x" ]; then
72 echo "Have you run 'bitbake meta-ide-support'?"
73 else
74 echo "This shouldn't happen - something is wrong with your toolchain installation"
75 fi
76
77 if [ -z "$SKIP_STRICT_SYSROOT_CHECK" ]; then
78 exit 1
79 fi
80fi
81PSEUDO="$OECORE_NATIVE_SYSROOT/usr/bin/pseudo"
diff --git a/scripts/oe-git-proxy b/scripts/oe-git-proxy
new file mode 100755
index 0000000000..98191faadd
--- /dev/null
+++ b/scripts/oe-git-proxy
@@ -0,0 +1,133 @@
1#!/bin/bash
2
3# oe-git-proxy is a simple tool to be via GIT_PROXY_COMMAND. It uses socat
4# to make SOCKS5 or HTTPS proxy connections. It uses ALL_PROXY to determine the
5# proxy server, protocol, and port. It uses NO_PROXY to skip using the proxy for
6# a comma delimited list of hosts, host globs (*.example.com), IPs, or CIDR
7# masks (192.168.1.0/24). It is known to work with both bash and dash shells.
8#
9# Example ALL_PROXY values:
10# ALL_PROXY=socks://socks.example.com:1080
11# ALL_PROXY=https://proxy.example.com:8080
12#
13# Copyright (c) 2013, Intel Corporation.
14# All rights reserved.
15#
16# AUTHORS
17# Darren Hart <dvhart@linux.intel.com>
18
19# Locate the netcat binary
20SOCAT=$(which socat 2>/dev/null)
21if [ $? -ne 0 ]; then
22 echo "ERROR: socat binary not in PATH"
23 exit 1
24fi
25METHOD=""
26
27# Test for a valid IPV4 quad with optional bitmask
28valid_ipv4() {
29 echo $1 | egrep -q "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}(/(3[0-2]|[1-2]?[0-9]))?$"
30 return $?
31}
32
33# Convert an IPV4 address into a 32bit integer
34ipv4_val() {
35 IP="$1"
36 SHIFT=24
37 VAL=0
38 for B in ${IP//./ }; do
39 VAL=$(($VAL+$(($B<<$SHIFT))))
40 SHIFT=$(($SHIFT-8))
41 done
42 echo "$VAL"
43}
44
45# Determine if two IPs are equivalent, or if the CIDR contains the IP
46match_ipv4() {
47 CIDR=$1
48 IP=$2
49
50 if [ -z "${IP%%$CIDR}" ]; then
51 return 0
52 fi
53
54 # Determine the mask bitlength
55 BITS=${CIDR##*/}
56 if [ -z "$BITS" ]; then
57 return 1
58 fi
59
60 IPVAL=$(ipv4_val $IP)
61 IP2VAL=$(ipv4_val ${CIDR%%/*})
62
63 # OR in the unmasked bits
64 for i in $(seq 0 $((32-$BITS))); do
65 IP2VAL=$(($IP2VAL|$((1<<$i))))
66 IPVAL=$(($IPVAL|$((1<<$i))))
67 done
68
69 if [ $IPVAL -eq $IP2VAL ]; then
70 return 0
71 fi
72 return 1
73}
74
75# Test to see if GLOB matches HOST
76match_host() {
77 HOST=$1
78 GLOB=$2
79
80 if [ -z "${HOST%%$GLOB}" ]; then
81 return 0
82 fi
83
84 # Match by netmask
85 if valid_ipv4 $GLOB; then
86 HOST_IP=$(gethostip -d $HOST)
87 if valid_ipv4 $HOST_IP; then
88 match_ipv4 $GLOB $HOST_IP
89 if [ $? -eq 0 ]; then
90 return 0
91 fi
92 fi
93 fi
94
95 return 1
96}
97
98# If no proxy is set or needed, just connect directly
99METHOD="TCP:$1:$2"
100
101if [ -z "$ALL_PROXY" ]; then
102 exec $SOCAT STDIO $METHOD
103fi
104
105# Connect directly to hosts in NO_PROXY
106for H in ${NO_PROXY//,/ }; do
107 if match_host $1 $H; then
108 exec $SOCAT STDIO $METHOD
109 fi
110done
111
112# Proxy is necessary, determine protocol, server, and port
113PROTO=$(echo $ALL_PROXY | sed -e 's/\([^:]*\):\/\/.*/\1/')
114PROXY=$(echo $ALL_PROXY | sed -e 's/.*:\/\/\([^:]*\).*/\1/')
115PORT=$(echo $ALL_PROXY | sed -e 's/.*:\([0-9]*\)\/?$/\1/')
116if [ "$PORT" = "$ALL_PROXY" ]; then
117 PORT=""
118fi
119
120if [ "$PROTO" = "socks" ]; then
121 if [ -z "$PORT" ]; then
122 PORT="1080"
123 fi
124 METHOD="SOCKS4:$PROXY:$1:$2,socksport=$PORT"
125else
126 # Assume PROXY (http, https, etc)
127 if [ -z "$PORT" ]; then
128 PORT="8080"
129 fi
130 METHOD="PROXY:$PROXY:$1:$2,proxyport=$PORT"
131fi
132
133exec $SOCAT STDIO $METHOD
diff --git a/scripts/oe-pkgdata-util b/scripts/oe-pkgdata-util
new file mode 100755
index 0000000000..a373116b2c
--- /dev/null
+++ b/scripts/oe-pkgdata-util
@@ -0,0 +1,332 @@
1#!/usr/bin/env python
2
3# OpenEmbedded pkgdata utility
4#
5# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
6#
7# Copyright 2012-2013 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22
23import sys
24import os
25import os.path
26import fnmatch
27import re
28import optparse
29from collections import defaultdict
30
31def glob(args, usage, debug=False):
32 if len(args) < 3:
33 usage()
34 sys.exit(1)
35
36 pkgdata_dir = args[0]
37 pkglist_file = args[1]
38 globs = args[2].split()
39
40 if not os.path.exists(pkgdata_dir):
41 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
42 sys.exit(1)
43
44 if not os.path.exists(pkglist_file):
45 print('ERROR: Unable to find package list file %s' % pkglist_file)
46 sys.exit(1)
47
48 skipregex = re.compile("-locale-|^locale-base-|-dev$|-doc$|-dbg$|-staticdev$|^kernel-module-")
49
50 mappedpkgs = set()
51 with open(pkglist_file, 'r') as f:
52 for line in f:
53 fields = line.rstrip().split()
54 if not fields:
55 continue
56 pkg = fields[0]
57 # We don't care about other args (used to need the package architecture but the
58 # new pkgdata structure avoids the need for that)
59
60 # Skip packages for which there is no point applying globs
61 if skipregex.search(pkg):
62 if debug:
63 print("%s -> !!" % pkg)
64 continue
65
66 # Skip packages that already match the globs, so if e.g. a dev package
67 # is already installed and thus in the list, we don't process it any further
68 # Most of these will be caught by skipregex already, but just in case...
69 already = False
70 for g in globs:
71 if fnmatch.fnmatchcase(pkg, g):
72 already = True
73 break
74 if already:
75 if debug:
76 print("%s -> !" % pkg)
77 continue
78
79 # Define some functions
80 def revpkgdata(pkgn):
81 return os.path.join(pkgdata_dir, "runtime-reverse", pkgn)
82 def fwdpkgdata(pkgn):
83 return os.path.join(pkgdata_dir, "runtime", pkgn)
84 def readpn(pkgdata_file):
85 pn = ""
86 with open(pkgdata_file, 'r') as f:
87 for line in f:
88 if line.startswith("PN:"):
89 pn = line.split(': ')[1].rstrip()
90 return pn
91 def readrenamed(pkgdata_file):
92 renamed = ""
93 pn = os.path.basename(pkgdata_file)
94 with open(pkgdata_file, 'r') as f:
95 for line in f:
96 if line.startswith("PKG_%s:" % pn):
97 renamed = line.split(': ')[1].rstrip()
98 return renamed
99
100 # Main processing loop
101 for g in globs:
102 mappedpkg = ""
103 # First just try substitution (i.e. packagename -> packagename-dev)
104 newpkg = g.replace("*", pkg)
105 revlink = revpkgdata(newpkg)
106 if os.path.exists(revlink):
107 mappedpkg = os.path.basename(os.readlink(revlink))
108 fwdfile = fwdpkgdata(mappedpkg)
109 if os.path.exists(fwdfile):
110 mappedpkg = readrenamed(fwdfile)
111 if not os.path.exists(fwdfile + ".packaged"):
112 mappedpkg = ""
113 else:
114 revlink = revpkgdata(pkg)
115 if os.path.exists(revlink):
116 # Check if we can map after undoing the package renaming (by resolving the symlink)
117 origpkg = os.path.basename(os.readlink(revlink))
118 newpkg = g.replace("*", origpkg)
119 fwdfile = fwdpkgdata(newpkg)
120 if os.path.exists(fwdfile):
121 mappedpkg = readrenamed(fwdfile)
122 else:
123 # That didn't work, so now get the PN, substitute that, then map in the other direction
124 pn = readpn(revlink)
125 newpkg = g.replace("*", pn)
126 fwdfile = fwdpkgdata(newpkg)
127 if os.path.exists(fwdfile):
128 mappedpkg = readrenamed(fwdfile)
129 if not os.path.exists(fwdfile + ".packaged"):
130 mappedpkg = ""
131 else:
132 # Package doesn't even exist...
133 if debug:
134 print "%s is not a valid package!" % (pkg)
135 break
136
137 if mappedpkg:
138 if debug:
139 print "%s (%s) -> %s" % (pkg, g, mappedpkg)
140 mappedpkgs.add(mappedpkg)
141 else:
142 if debug:
143 print "%s (%s) -> ?" % (pkg, g)
144
145 if debug:
146 print "------"
147
148 print("\n".join(mappedpkgs))
149
150def read_value(args, usage, debug=False):
151 if len(args) < 3:
152 usage()
153 sys.exit(1)
154
155 pkgdata_dir = args[0]
156 var = args[1]
157 packages = args[2].split()
158
159 if not os.path.exists(pkgdata_dir):
160 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
161 sys.exit(1)
162
163 def readvar(pkgdata_file, var):
164 val = ""
165 with open(pkgdata_file, 'r') as f:
166 for line in f:
167 if line.startswith(var + ":"):
168 val = line.split(': ')[1].rstrip()
169 return val
170
171 if debug:
172 print "read-value('%s', '%s' '%s'" % (pkgdata_dir, var, packages)
173 for package in packages:
174 pkg_split = package.split('_')
175 pkg_name = pkg_split[0]
176 if debug:
177 print "package: '%s'" % pkg_name
178 revlink = os.path.join(pkgdata_dir, "runtime-reverse", pkg_name)
179 if debug:
180 print(revlink)
181 if os.path.exists(revlink):
182 mappedpkg = os.path.basename(os.readlink(revlink))
183 qvar = var
184 if qvar == "PKGSIZE":
185 # append packagename
186 qvar = "%s_%s" % (var, mappedpkg)
187 # PKGSIZE is now in bytes, but we we want it in KB
188 pkgsize = (int(readvar(revlink, qvar)) + 1024 // 2) // 1024
189 print("%d" % pkgsize)
190 else:
191 print(readvar(revlink, qvar))
192
193def lookup_pkg(args, usage, debug=False):
194 if len(args) < 2:
195 usage()
196 sys.exit(1)
197
198 pkgdata_dir = args[0]
199 pkgs = args[1].split()
200
201 if not os.path.exists(pkgdata_dir):
202 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
203 sys.exit(1)
204
205 mappings = defaultdict(list)
206 for pkg in pkgs:
207 pkgfile = os.path.join(pkgdata_dir, 'runtime', pkg)
208 if os.path.exists(pkgfile):
209 with open(pkgfile, 'r') as f:
210 for line in f:
211 fields = line.rstrip().split(': ')
212 if fields[0] == 'PKG_%s' % pkg:
213 mappings[pkg].append(fields[1])
214 break
215 if len(mappings) < len(pkgs):
216 missing = list(set(pkgs) - set(mappings.keys()))
217 sys.stderr.write("ERROR: the following packages could not be found: %s\n" % ', '.join(missing))
218 sys.exit(1)
219
220 items = []
221 for pkg in pkgs:
222 items.extend(mappings.get(pkg, []))
223 print '\n'.join(items)
224
225def lookup_recipe(args, usage, debug=False):
226 if len(args) < 2:
227 usage()
228 sys.exit(1)
229
230 pkgdata_dir = args[0]
231 pkgs = args[1].split()
232
233 if not os.path.exists(pkgdata_dir):
234 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
235 sys.exit(1)
236
237 mappings = defaultdict(list)
238 for pkg in pkgs:
239 pkgfile = os.path.join(pkgdata_dir, 'runtime-reverse', pkg)
240 if os.path.exists(pkgfile):
241 with open(pkgfile, 'r') as f:
242 for line in f:
243 fields = line.rstrip().split(': ')
244 if fields[0] == 'PN':
245 mappings[pkg].append(fields[1])
246 break
247 if len(mappings) < len(pkgs):
248 missing = list(set(pkgs) - set(mappings.keys()))
249 sys.stderr.write("ERROR: the following packages could not be found: %s\n" % ', '.join(missing))
250 sys.exit(1)
251
252 items = []
253 for pkg in pkgs:
254 items.extend(mappings.get(pkg, []))
255 print '\n'.join(items)
256
257def find_path(args, usage, debug=False):
258 if len(args) < 2:
259 usage()
260 sys.exit(1)
261
262 pkgdata_dir = args[0]
263 targetpath = args[1]
264
265 if not os.path.exists(pkgdata_dir):
266 print('ERROR: Unable to find pkgdata directory %s' % pkgdata_dir)
267 sys.exit(1)
268
269 import json
270 import fnmatch
271
272 for root, dirs, files in os.walk(os.path.join(pkgdata_dir, 'runtime')):
273 for fn in files:
274 with open(os.path.join(root,fn)) as f:
275 for line in f:
276 if line.startswith('FILES_INFO:'):
277 val = line.split(':', 1)[1].strip()
278 dictval = json.loads(val)
279 for fullpth in dictval.keys():
280 if fnmatch.fnmatchcase(fullpth, targetpath):
281 print("%s: %s" % (fn, fullpth))
282 break
283
284
285def main():
286 parser = optparse.OptionParser(
287 usage = '''%prog [options] <command> <arguments>
288
289Available commands:
290 glob <pkgdatadir> <pkglistfile> "<globs>"
291 expand one or more glob expressions over the packages listed in
292 pkglistfile (one package per line)
293 lookup-pkg <pkgdatadir> "<recipe-pkgs>"
294 look up the specified recipe-space package name(s) to see what the
295 final runtime package name is (e.g. eglibc becomes libc6)
296 lookup-recipe <pkgdatadir> "<pkgs>"
297 look up the specified package(s) to see which recipe they were
298 produced by
299 find-path <pkgdatadir> <path>
300 find the package providing the specified path (wildcards * ? allowed)
301 read-value <pkgdatadir> <value-name> "<pkgs>"
302 read the named value from the pkgdata files for the specified
303 packages''')
304
305 parser.add_option("-d", "--debug",
306 help = "Report all SRCREV values, not just ones where AUTOREV has been used",
307 action="store_true", dest="debug", default=False)
308
309 options, args = parser.parse_args(sys.argv)
310 args = args[1:]
311
312 if len(args) < 1:
313 parser.print_help()
314 sys.exit(1)
315
316 if args[0] == "glob":
317 glob(args[1:], parser.print_help, options.debug)
318 elif args[0] == "lookup-pkg":
319 lookup_pkg(args[1:], parser.print_help, options.debug)
320 elif args[0] == "lookup-recipe":
321 lookup_recipe(args[1:], parser.print_help, options.debug)
322 elif args[0] == "find-path":
323 find_path(args[1:], parser.print_help, options.debug)
324 elif args[0] == "read-value":
325 read_value(args[1:], parser.print_help, options.debug)
326 else:
327 parser.print_help()
328 sys.exit(1)
329
330
331if __name__ == "__main__":
332 main()
diff --git a/scripts/oe-selftest b/scripts/oe-selftest
new file mode 100755
index 0000000000..8c4ea92610
--- /dev/null
+++ b/scripts/oe-selftest
@@ -0,0 +1,162 @@
1#!/usr/bin/env python
2
3# Copyright (c) 2013 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18# DESCRIPTION
19# This script runs tests defined in meta/lib/selftest/
20# It's purpose is to automate the testing of different bitbake tools.
21# To use it you just need to source your build environment setup script and
22# add the meta-selftest layer to your BBLAYERS.
23# Call the script as: "oe-selftest" to run all the tests in in meta/lib/selftest/
24# Call the script as: "oe-selftest <module>.<Class>.<method>" to run just a single test
25# E.g: "oe-selftest bboutput.BitbakeLayers" will run just the BitbakeLayers class from meta/lib/selftest/bboutput.py
26
27
28import os
29import sys
30import unittest
31import logging
32
33sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'meta/lib')))
34
35import oeqa.selftest
36import oeqa.utils.ftools as ftools
37from oeqa.utils.commands import runCmd, get_bb_var, get_test_layer
38from oeqa.selftest.base import oeSelfTest
39
40def logger_create():
41 log = logging.getLogger("selftest")
42 log.setLevel(logging.DEBUG)
43
44 fh = logging.FileHandler(filename='oe-selftest.log', mode='w')
45 fh.setLevel(logging.DEBUG)
46
47 ch = logging.StreamHandler(sys.stdout)
48 ch.setLevel(logging.INFO)
49
50 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
51 fh.setFormatter(formatter)
52 ch.setFormatter(formatter)
53
54 log.addHandler(fh)
55 log.addHandler(ch)
56
57 return log
58
59log = logger_create()
60
61def preflight_check():
62
63 log.info("Checking that everything is in order before running the tests")
64
65 if not os.environ.get("BUILDDIR"):
66 log.error("BUILDDIR isn't set. Did you forget to source your build environment setup script?")
67 return False
68
69 builddir = os.environ.get("BUILDDIR")
70 if os.getcwd() != builddir:
71 log.info("Changing cwd to %s" % builddir)
72 os.chdir(builddir)
73
74 if not "meta-selftest" in get_bb_var("BBLAYERS"):
75 log.error("You don't seem to have the meta-selftest layer in BBLAYERS")
76 return False
77
78 log.info("Running bitbake -p")
79 runCmd("bitbake -p")
80
81 return True
82
83def add_include():
84 builddir = os.environ.get("BUILDDIR")
85 if "#include added by oe-selftest.py" \
86 not in ftools.read_file(os.path.join(builddir, "conf/local.conf")):
87 log.info("Adding: \"include selftest.inc\" in local.conf")
88 ftools.append_file(os.path.join(builddir, "conf/local.conf"), \
89 "\n#include added by oe-selftest.py\ninclude selftest.inc")
90
91
92def remove_include():
93 builddir = os.environ.get("BUILDDIR")
94 if "#include added by oe-selftest.py" \
95 in ftools.read_file(os.path.join(builddir, "conf/local.conf")):
96 log.info("Removing the include from local.conf")
97 ftools.remove_from_file(os.path.join(builddir, "conf/local.conf"), \
98 "#include added by oe-selftest.py\ninclude selftest.inc")
99
100
101def remove_inc_files():
102 try:
103 os.remove(os.path.join(os.environ.get("BUILDDIR"), "conf/selftest.inc"))
104 for root, _, files in os.walk(get_test_layer()):
105 for f in files:
106 if f == 'test_recipe.inc':
107 os.remove(os.path.join(root, f))
108 except OSError as e:
109 pass
110
111def get_tests():
112 testslist = []
113 for x in sys.argv[1:]:
114 testslist.append('oeqa.selftest.' + x)
115 if not testslist:
116 testpath = os.path.abspath(os.path.dirname(oeqa.selftest.__file__))
117 files = sorted([f for f in os.listdir(testpath) if f.endswith('.py') and not f.startswith('_') and f != 'base.py'])
118 for f in files:
119 module = 'oeqa.selftest.' + f[:-3]
120 testslist.append(module)
121
122 return testslist
123
124def main():
125 if not preflight_check():
126 return 1
127
128 testslist = get_tests()
129 suite = unittest.TestSuite()
130 loader = unittest.TestLoader()
131 loader.sortTestMethodsUsing = None
132 runner = unittest.TextTestRunner(verbosity=2)
133 # we need to do this here, otherwise just loading the tests
134 # will take 2 minutes (bitbake -e calls)
135 oeSelfTest.testlayer_path = get_test_layer()
136 for test in testslist:
137 log.info("Loading tests from: %s" % test)
138 try:
139 suite.addTests(loader.loadTestsFromName(test))
140 except AttributeError as e:
141 log.error("Failed to import %s" % test)
142 log.error(e)
143 return 1
144 add_include()
145 result = runner.run(suite)
146 log.info("Finished")
147 if result.wasSuccessful():
148 return 0
149 else:
150 return 1
151
152if __name__ == "__main__":
153 try:
154 ret = main()
155 except Exception:
156 ret = 1
157 import traceback
158 traceback.print_exc(5)
159 finally:
160 remove_include()
161 remove_inc_files()
162 sys.exit(ret)
diff --git a/scripts/oe-setup-builddir b/scripts/oe-setup-builddir
new file mode 100755
index 0000000000..c91e079512
--- /dev/null
+++ b/scripts/oe-setup-builddir
@@ -0,0 +1,134 @@
1#!/bin/sh
2
3# OE Build Environment Setup Script
4#
5# Copyright (C) 2006-2011 Linux Foundation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21if [ -z "$BUILDDIR" ]; then
22 echo >&2 "Error: The build directory (BUILDDIR) must be set!"
23 exit 1
24fi
25
26mkdir -p $BUILDDIR/conf
27
28if [ ! -d "$BUILDDIR" ]; then
29 echo >&2 "Error: The builddir ($BUILDDIR) does not exist!"
30 exit 1
31fi
32
33if [ ! -w "$BUILDDIR" ]; then
34 echo >&2 "Error: Cannot write to $BUILDDIR, perhaps try sourcing with a writable path? i.e. . oe-init-build-env ~/my-build"
35 exit 1
36fi
37
38cd "$BUILDDIR"
39
40if [ -f "$BUILDDIR/conf/templateconf.cfg" ]; then
41 TEMPLATECONF=$(cat $BUILDDIR/conf/templateconf.cfg)
42fi
43
44. $OEROOT/.templateconf
45
46if [ ! -f "$BUILDDIR/conf/templateconf.cfg" ]; then
47 echo "$TEMPLATECONF" >$BUILDDIR/conf/templateconf.cfg
48fi
49
50#
51# $TEMPLATECONF can point to a directory for the template local.conf & bblayers.conf
52#
53if [ -n "$TEMPLATECONF" ]; then
54 if [ ! -d "$TEMPLATECONF" ]; then
55 # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
56 if [ -d "$OEROOT/$TEMPLATECONF" ]; then
57 TEMPLATECONF="$OEROOT/$TEMPLATECONF"
58 fi
59 if [ ! -d "$TEMPLATECONF" ]; then
60 echo >&2 "Error: '$TEMPLATECONF' must be a directory containing local.conf & bblayers.conf"
61 exit 1
62 fi
63 fi
64 OECORELAYERCONF="$TEMPLATECONF/bblayers.conf.sample"
65 OECORELOCALCONF="$TEMPLATECONF/local.conf.sample"
66 OECORENOTESCONF="$TEMPLATECONF/conf-notes.txt"
67fi
68
69if [ -z "$OECORELOCALCONF" ]; then
70 OECORELOCALCONF="$OEROOT/meta/conf/local.conf.sample"
71fi
72if [ ! -r "$BUILDDIR/conf/local.conf" ]; then
73cat <<EOM
74You had no conf/local.conf file. This configuration file has therefore been
75created for you with some default values. You may wish to edit it to use a
76different MACHINE (target hardware) or enable parallel build options to take
77advantage of multiple cores for example. See the file for more information as
78common configuration options are commented.
79
80The Yocto Project has extensive documentation about OE including a reference manual
81which can be found at:
82 http://yoctoproject.org/documentation
83
84For more information about OpenEmbedded see their website:
85 http://www.openembedded.org/
86
87EOM
88 cp -f $OECORELOCALCONF $BUILDDIR/conf/local.conf
89fi
90
91if [ -z "$OECORELAYERCONF" ]; then
92 OECORELAYERCONF="$OEROOT/meta/conf/bblayers.conf.sample"
93fi
94if [ ! -r "$BUILDDIR/conf/bblayers.conf" ]; then
95 cat <<EOM
96You had no conf/bblayers.conf file. The configuration file has been created for
97you with some default values. To add additional metadata layers into your
98configuration please add entries to this file.
99
100The Yocto Project has extensive documentation about OE including a reference manual
101which can be found at:
102 http://yoctoproject.org/documentation
103
104For more information about OpenEmbedded see their website:
105 http://www.openembedded.org/
106
107
108EOM
109
110 # Put the abosolute path to the layers in bblayers.conf so we can run
111 # bitbake without the init script after the first run
112 # ##COREBASE## is deprecated as it's meaning was inconsistent, but continue
113 # to replace it for compatibility.
114 sed -e "s|##OEROOT##|$OEROOT|g" \
115 -e "s|##COREBASE##|$OEROOT|g" \
116 $OECORELAYERCONF > $BUILDDIR/conf/bblayers.conf
117fi
118
119# Prevent disturbing a new GIT clone in same console
120unset OECORELOCALCONF
121unset OECORELAYERCONF
122
123cat <<EOM
124
125### Shell environment set up for builds. ###
126
127You can now run 'bitbake <target>'
128
129EOM
130if [ -z "$OECORENOTESCONF" ]; then
131 OECORENOTESCONF="$OEROOT/meta/conf/conf-notes.txt"
132fi
133[ ! -r "$OECORENOTESCONF" ] || cat $OECORENOTESCONF
134unset OECORENOTESCONF
diff --git a/scripts/oe-setup-rpmrepo b/scripts/oe-setup-rpmrepo
new file mode 100755
index 0000000000..917b98b984
--- /dev/null
+++ b/scripts/oe-setup-rpmrepo
@@ -0,0 +1,97 @@
1#!/bin/bash
2#
3# This utility setup the necessary metadata for an rpm repo
4#
5# Copyright (c) 2011 Intel Corp.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14# See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20
21# Don't use TMPDIR from the external environment, it may be a distro
22# variable pointing to /tmp (e.g. within X on OpenSUSE)
23# Instead, use OE_TMPDIR for passing this in externally.
24TMPDIR="$OE_TMPDIR"
25
26function usage() {
27 echo "Usage: $0 <rpm-dir>"
28 echo " <rpm-dir>: default is $TMPDIR/deploy/rpm"
29}
30
31if [ $# -gt 1 ]; then
32 usage
33 exit 1
34fi
35
36setup_tmpdir() {
37 if [ -z "$TMPDIR" ]; then
38 # Try to get TMPDIR from bitbake
39 type -P bitbake &>/dev/null || {
40 echo "In order for this script to dynamically infer paths";
41 echo "to kernels or filesystem images, you either need";
42 echo "bitbake in your PATH or to source oe-init-build-env";
43 echo "before running this script" >&2;
44 exit 1; }
45
46 # We have bitbake in PATH, get TMPDIR from bitbake
47 TMPDIR=`bitbake -e | grep ^TMPDIR=\" | cut -d '=' -f2 | cut -d '"' -f2`
48 if [ -z "$TMPDIR" ]; then
49 echo "Error: this script needs to be run from your build directory,"
50 echo "or you need to explicitly set TMPDIR in your environment"
51 exit 1
52 fi
53 fi
54}
55
56setup_sysroot() {
57 # Toolchain installs set up $OECORE_NATIVE_SYSROOT in their
58 # environment script. If that variable isn't set, we're
59 # either in an in-tree poky scenario or the environment
60 # script wasn't source'd.
61 if [ -z "$OECORE_NATIVE_SYSROOT" ]; then
62 setup_tmpdir
63 BUILD_ARCH=`uname -m`
64 BUILD_OS=`uname | tr '[A-Z]' '[a-z]'`
65 BUILD_SYS="$BUILD_ARCH-$BUILD_OS"
66
67 OECORE_NATIVE_SYSROOT=$TMPDIR/sysroots/$BUILD_SYS
68 fi
69}
70
71setup_tmpdir
72setup_sysroot
73
74
75if [ -n "$1" ]; then
76 RPM_DIR="$1"
77else
78 RPM_DIR="$TMPDIR/deploy/rpm"
79fi
80
81if [ ! -d "$RPM_DIR" ]; then
82 echo "Error: rpm dir $RPM_DIR doesn't exist"
83 exit 1
84fi
85
86CREATEREPO=$OECORE_NATIVE_SYSROOT/usr/bin/createrepo
87if [ ! -e "$CREATEREPO" ]; then
88 echo "Error: can't find createrepo binary"
89 echo "please run bitbake createrepo-native first"
90 exit 1
91fi
92
93export PATH=${PATH}:${OECORE_NATIVE_SYSROOT}/usr/bin
94
95$CREATEREPO "$RPM_DIR"
96
97exit 0
diff --git a/scripts/oe-trim-schemas b/scripts/oe-trim-schemas
new file mode 100755
index 0000000000..29fb3a1b67
--- /dev/null
+++ b/scripts/oe-trim-schemas
@@ -0,0 +1,49 @@
1#! /usr/bin/env python
2
3import sys
4try:
5 import xml.etree.cElementTree as etree
6except:
7 import xml.etree.ElementTree as etree
8
9def child (elem, name):
10 for e in elem.getchildren():
11 if e.tag == name:
12 return e
13 return None
14
15def children (elem, name=None):
16 l = elem.getchildren()
17 if name:
18 l = [e for e in l if e.tag == name]
19 return l
20
21xml = etree.parse(sys.argv[1])
22
23for schema in child(xml.getroot(), "schemalist").getchildren():
24 e = child(schema, "short")
25 if e is not None:
26 schema.remove(e)
27
28 e = child(schema, "long")
29 if e is not None:
30 schema.remove(e)
31
32 for locale in children(schema, "locale"):
33 # One locale must exist so leave C locale...
34 a = locale.attrib.get("name")
35 if a == 'C':
36 continue
37 e = child(locale, "default")
38 if e is None:
39 schema.remove(locale)
40 else:
41 e = child(locale, "short")
42 if e is not None:
43 locale.remove(e)
44 e = child(locale, "long")
45 if e is not None:
46 locale.remove(e)
47
48xml.write(sys.stdout, "UTF-8")
49
diff --git a/scripts/opkg-query-helper.py b/scripts/opkg-query-helper.py
new file mode 100755
index 0000000000..2fb1a78970
--- /dev/null
+++ b/scripts/opkg-query-helper.py
@@ -0,0 +1,85 @@
1#!/usr/bin/env python
2
3# OpenEmbedded opkg query helper utility
4#
5# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
6#
7# Copyright 2012 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21#
22#
23
24
25import sys
26import fileinput
27import re
28
29archmode = False
30filemode = False
31vermode = False
32
33args = []
34for arg in sys.argv[1:]:
35 if arg == '-a':
36 archmode = True
37 elif arg == '-f':
38 filemode = True
39 elif arg == '-v':
40 vermode = True
41 else:
42 args.append(arg)
43
44# Regex for removing version specs after dependency items
45verregex = re.compile(' \([=<>]* [^ )]*\)')
46
47pkg = ""
48ver = ""
49for line in fileinput.input(args):
50 line = line.rstrip()
51 if ': ' in line:
52 if line.startswith("Package:"):
53 pkg = line.split(": ")[1]
54 ver = ""
55 else:
56 if archmode:
57 if line.startswith("Architecture:"):
58 arch = line.split(": ")[1]
59 print("%s %s" % (pkg,arch))
60 elif filemode:
61 if line.startswith("Version:"):
62 ver = line.split(": ")[1]
63 elif line.startswith("Architecture:"):
64 arch = line.split(": ")[1]
65 print("%s %s_%s_%s.ipk %s" % (pkg,pkg,ver,arch,arch))
66 elif vermode:
67 if line.startswith("Version:"):
68 ver = line.split(": ")[1]
69 elif line.startswith("Architecture:"):
70 arch = line.split(": ")[1]
71 print("%s %s %s" % (pkg,arch,ver))
72 else:
73 if line.startswith("Depends:"):
74 depval = line.split(": ")[1]
75 deps = depval.split(", ")
76 for dep in deps:
77 dep = verregex.sub('', dep)
78 print("%s|%s" % (pkg,dep))
79 elif line.startswith("Recommends:"):
80 recval = line.split(": ")[1]
81 recs = recval.split(", ")
82 for rec in recs:
83 rec = verregex.sub('', rec)
84 print("%s|%s [REC]" % (pkg, rec))
85
diff --git a/scripts/postinst-intercepts/postinst_intercept b/scripts/postinst-intercepts/postinst_intercept
new file mode 100755
index 0000000000..27c256834c
--- /dev/null
+++ b/scripts/postinst-intercepts/postinst_intercept
@@ -0,0 +1,56 @@
1#!/bin/sh
2#
3# This script is called from inside postinstall scriptlets at do_rootfs time. It
4# actually adds, at the end, the list of packages for which the intercept script
5# is valid. Also, if one wants to pass any variables to the intercept script from
6# the postinstall itself, they will be added immediately after the shebang line.
7#
8# Usage: postinst_intercept <intercept_script_name> <package_name> <mlprefix=...> <var1=...> ... <varN=...>
9# * intercept_script_name - the name of the intercept script we want to change;
10# * package_name - add the package_name to list of packages the intercept script
11# is used for;
12# * mlprefix=... - this one is needed in order to have separate hooks for multilib.
13# * var1=... - var1 will have the value we provide in the intercept script. This
14# is useful when we want to pass on variables like ${libdir} to
15# the intercept script;
16#
17[ $# -lt 3 ] && exit 1
18
19intercept_script=$INTERCEPT_DIR/$1 && shift
20package_name=$1 && shift
21mlprefix=$(echo $1 |sed -ne "s/^mlprefix=\(.*\)-/\1/p") && shift
22
23# if the hook we want to install does not exist, then there's nothing we can do
24[ -f "$intercept_script" ] || exit 1
25
26# if the postinstall wanting to install the hook belongs to a multilib package,
27# then we'd better have a separate hook for this because the default ${libdir} and
28# ${base_libdir} will point to the wrong locations
29if [ -n "$mlprefix" ]; then
30 ml_intercept_script=$intercept_script-$mlprefix
31 # if the multilib hook does not exist, create it from the default one
32 if [ ! -f "$ml_intercept_script" ]; then
33 cp $intercept_script $ml_intercept_script
34
35 # clear the ##PKGS: line and the already set variables
36 [ -x "$ml_intercept_script" ] && sed -i -e "2,$(($#+1)) {/.*/d}" -e "/^##PKGS: .*/d" $ml_intercept_script
37 fi
38
39 intercept_script=$ml_intercept_script
40fi
41
42chmod +x "$intercept_script"
43
44pkgs_line="$(cat $intercept_script|grep "##PKGS:")"
45if [ -n "$pkgs_line" ]; then
46 # line exists, add this package to the list only if it's not already there
47 if [ -z "$(echo "$pkgs_line" | grep " $package_name ")" ]; then
48 sed -i -e "s/##PKGS:.*/\0${package_name} /" $intercept_script
49 fi
50else
51 for var in $@; do
52 sed -i -e "\%^#\!/bin/.*sh%a $var" $intercept_script
53 done
54 echo "##PKGS: ${package_name} " >> $intercept_script
55fi
56
diff --git a/scripts/postinst-intercepts/update_font_cache b/scripts/postinst-intercepts/update_font_cache
new file mode 100644
index 0000000000..78f33651e9
--- /dev/null
+++ b/scripts/postinst-intercepts/update_font_cache
@@ -0,0 +1,6 @@
1#!/bin/sh
2
3PSEUDO_UNLOAD=1 qemuwrapper -L $D -E LD_LIBRARY_PATH=$D/${libdir}:$D/${base_libdir}\
4 $D${bindir}/fc-cache --sysroot=$D
5
6
diff --git a/scripts/postinst-intercepts/update_icon_cache b/scripts/postinst-intercepts/update_icon_cache
new file mode 100644
index 0000000000..8e17a6ac0c
--- /dev/null
+++ b/scripts/postinst-intercepts/update_icon_cache
@@ -0,0 +1,12 @@
1#!/bin/sh
2
3set -e
4# update native pixbuf loaders
5gdk-pixbuf-query-loaders --update-cache
6
7for icondir in $D/usr/share/icons/*/ ; do
8 if [ -d $icondir ] ; then
9 gtk-update-icon-cache -fqt $icondir
10 fi
11done
12
diff --git a/scripts/postinst-intercepts/update_pixbuf_cache b/scripts/postinst-intercepts/update_pixbuf_cache
new file mode 100644
index 0000000000..95bf4f90a3
--- /dev/null
+++ b/scripts/postinst-intercepts/update_pixbuf_cache
@@ -0,0 +1,11 @@
1#!/bin/sh
2
3export GDK_PIXBUF_MODULEDIR=$D${libdir}/gdk-pixbuf-2.0/2.10.0/loaders
4export GDK_PIXBUF_FATAL_LOADER=1
5
6PSEUDO_UNLOAD=1 qemuwrapper -L $D -E LD_LIBRARY_PATH=$D/${libdir}:$D/${base_libdir}\
7 $D${bindir}/gdk-pixbuf-query-loaders \
8 >$GDK_PIXBUF_MODULEDIR/../loaders.cache && \
9 sed -i -e "s:$D::g" $GDK_PIXBUF_MODULEDIR/../loaders.cache
10
11
diff --git a/scripts/pybootchartgui/AUTHORS b/scripts/pybootchartgui/AUTHORS
new file mode 100644
index 0000000000..672b7e9520
--- /dev/null
+++ b/scripts/pybootchartgui/AUTHORS
@@ -0,0 +1,11 @@
1Michael Meeks <michael.meeks@novell.com>
2Anders Norgaard <anders.norgaard@gmail.com>
3Scott James Remnant <scott@ubuntu.com>
4Henning Niss <henningniss@gmail.com>
5Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
6
7Contributors:
8 Brian Ewins
9
10Based on work by:
11 Ziga Mahkovec
diff --git a/scripts/pybootchartgui/COPYING b/scripts/pybootchartgui/COPYING
new file mode 100644
index 0000000000..ed87acf948
--- /dev/null
+++ b/scripts/pybootchartgui/COPYING
@@ -0,0 +1,340 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
59 GNU GENERAL PUBLIC LICENSE
60 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
62 0. This License applies to any program or other work which contains
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you may at your option offer warranty protection in exchange for a fee.
89
90 2. You may modify your copy or copies of the Program or any portion
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, provided that you also meet all of these conditions:
94
95 a) You must cause the modified files to carry prominent notices
96 stating that you changed the files and the date of any change.
97
98 b) You must cause any work that you distribute or publish, that in
99 whole or in part contains or is derived from the Program or any
100 part thereof, to be licensed as a whole at no charge to all third
101 parties under the terms of this License.
102
103 c) If the modified program normally reads commands interactively
104 when run, you must cause it, when started running for such
105 interactive use in the most ordinary way, to print or display an
106 announcement including an appropriate copyright notice and a
107 notice that there is no warranty (or else, saying that you provide
108 a warranty) and that users may redistribute the program under
109 these conditions, and telling the user how to view a copy of this
110 License. (Exception: if the Program itself is interactive but
111 does not normally print such an announcement, your work based on
112 the Program is not required to print an announcement.)
113
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 1 and 2 above provided that you also do one of the following:
137
138 a) Accompany it with the complete corresponding machine-readable
139 source code, which must be distributed under the terms of Sections
140 1 and 2 above on a medium customarily used for software interchange; or,
141
142 b) Accompany it with a written offer, valid for at least three
143 years, to give any third party, for a charge no more than your
144 cost of physically performing source distribution, a complete
145 machine-readable copy of the corresponding source code, to be
146 distributed under the terms of Sections 1 and 2 above on a medium
147 customarily used for software interchange; or,
148
149 c) Accompany it with the information you received as to the offer
150 to distribute corresponding source code. (This alternative is
151 allowed only for noncommercial distribution and only if you
152 received the program in object code or executable form with such
153 an offer, in accord with Subsection b above.)
154
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of promoting the sharing and reuse of software generally.
257
258 NO WARRANTY
259
260 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY OF SUCH DAMAGES.
279
280 END OF TERMS AND CONDITIONS
281
282 How to Apply These Terms to Your New Programs
283
284 If you develop a new program, and you want it to be of the greatest
285possible use to the public, the best way to achieve this is to make it
286free software which everyone can redistribute and change under these terms.
287
288 To do so, attach the following notices to the program. It is safest
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "copyright" line and a pointer to where the full notice is found.
292
293 <one line to give the program's name and a brief idea of what it does.>
294 Copyright (C) <year> <name of author>
295
296 This program is free software; you can redistribute it and/or modify
297 it under the terms of the GNU General Public License as published by
298 the Free Software Foundation; either version 2 of the License, or
299 (at your option) any later version.
300
301 This program is distributed in the hope that it will be useful,
302 but WITHOUT ANY WARRANTY; without even the implied warranty of
303 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 GNU General Public License for more details.
305
306 You should have received a copy of the GNU General Public License
307 along with this program; if not, write to the Free Software
308 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
309
310
311Also add information on how to contact you by electronic and paper mail.
312
313If the program is interactive, make it output a short notice like this
314when it starts in an interactive mode:
315
316 Gnomovision version 69, Copyright (C) year name of author
317 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
318 This is free software, and you are welcome to redistribute it
319 under certain conditions; type `show c' for details.
320
321The hypothetical commands `show w' and `show c' should show the appropriate
322parts of the General Public License. Of course, the commands you use may
323be called something other than `show w' and `show c'; they could even be
324mouse-clicks or menu items--whatever suits your program.
325
326You should also get your employer (if you work as a programmer) or your
327school, if any, to sign a "copyright disclaimer" for the program, if
328necessary. Here is a sample; alter the names:
329
330 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
331 `Gnomovision' (which makes passes at compilers) written by James Hacker.
332
333 <signature of Ty Coon>, 1 April 1989
334 Ty Coon, President of Vice
335
336This General Public License does not permit incorporating your program into
337proprietary programs. If your program is a subroutine library, you may
338consider it more useful to permit linking proprietary applications with the
339library. If this is what you want to do, use the GNU Library General
340Public License instead of this License.
diff --git a/scripts/pybootchartgui/MAINTAINERS b/scripts/pybootchartgui/MAINTAINERS
new file mode 100644
index 0000000000..c65e1315f1
--- /dev/null
+++ b/scripts/pybootchartgui/MAINTAINERS
@@ -0,0 +1,3 @@
1Riccardo Magliocchetti <riccardo.magliocchetti@gmail.com>
2Michael Meeks <michael.meeks@novell.com>
3Harald Hoyer <harald@redhat.com>
diff --git a/scripts/pybootchartgui/NEWS b/scripts/pybootchartgui/NEWS
new file mode 100644
index 0000000000..7c5b2fc3a1
--- /dev/null
+++ b/scripts/pybootchartgui/NEWS
@@ -0,0 +1,204 @@
1bootchart2 0.14.5:
2 + pybootchartgui (Riccardo)
3 + Fix tests with python3
4 + Fix parsing of files with non-ascii bytes
5 + Robustness fixes to taskstats and meminfo parsing
6 + More python3 fixes
7
8bootchart2 0.14.4:
9 + bootchartd
10 + Add relevant EXIT_PROC for GNOME3, XFCE4, openbox
11 (Justin Lecher, Ben Eills)
12 + pybootchartgui (Riccardo)
13 + Fix some issues in --crop-after and --annotate
14 + Fix pybootchartgui process_tree tests
15 + More python3 fixes
16
17bootchart2 0.14.2:
18 + pybootchartgui
19 + Fix some crashes in parsing.py (Jakub Czaplicki, Riccardo)
20 + speedup a bit meminfo parsing (Riccardo)
21 + Fix indentation for python3.2 (Riccardo)
22
23bootchart2 0.14.1:
24 + bootchartd
25 + Expect dmesg only if started as init (Henry Yei)
26 + look for bootchart_init in the environment (Henry Gebhardt)
27 + pybootchartgui
28 + Fixup some tests (Riccardo)
29 + Support hp smart arrays block devices (Anders Norgaard,
30 Brian Murray)
31 + Fixes for -t, -o and -f options (Mladen Kuntner, Harald, Riccardo)
32
33bootchart2 0.14.0:
34 + bootchartd
35 + Add ability to define custom commands
36 (Lucian Muresan, Peter Hjalmarsson)
37 + collector
38 + fix tmpfs mount leakage (Peter Hjalmarsson)
39 + pybootchartgui
40 + render cumulative I/O time chart (Sankar P)
41 + python3 compatibility fixes (Riccardo)
42 + Misc (Michael)
43 + remove confusing, obsolete setup.py
44 + install docs to /usr/share/
45 + lot of fixes for easier packaging (Peter Hjalmarsson)
46 + add bootchart2, bootchartd and pybootchartgui manpages
47 (Francesca Ciceri, David Paleino)
48
49bootchart2 0.12.6:
50 + bootchartd
51 + better check for initrd (Riccardo Magliocchetti)
52 + code cleanup (Riccardo)
53 + make the list of processes we are waiting for editable
54 in config file by EXIT_PROC (Riccardo)
55 + fix parsing of cmdline for alternative init system (Riccardo)
56 + fixed calling init in initramfs (Harald)
57 + exit 0 for start, if the collector is already running (Harald)
58 + collector
59 + try harder with taskstats (Michael)
60 + plug some small leaks (Riccardo)
61 + fix missing PROC_EVENTS detection (Harald)
62 + pybootchartgui (Michael)
63 + add kernel bootchart tab to interactive gui
64 + report bootchart version in cli interface
65 + improve rendering performance
66 + GUI improvements
67 + lot of cleanups
68 + Makefile
69 + do not python compile if NO_PYTHON_COMPILE is set (Harald)
70 + systemd service files
71 + added them and install (Harald, Wulf C. Krueger)
72
73bootchart2 0.12.5:
74 + administrative snafu version; pull before pushing...
75
76bootchart2 0.12.4:
77 + bootchartd
78 + reduce overhead caused by pidof (Riccardo Magliocchetti)
79 + collector
80 + attempt to retry ptrace to avoid bogus ENOSYS (Michael)
81 + add meminfo polling (Dave Martin)
82 + pybootchartgui
83 + handle dmesg timestamps with big delta (Riccardo)
84 + avoid divide by zero when rendering I/O utilization (Riccardo)
85 + add process grouping in the cumulative chart (Riccardo)
86 + fix cpu time calculation in cumulative chart (Riccardo)
87 + get i/o statistics for flash based devices (Riccardo)
88 + prettier coloring for the cumulative graphs (Michael)
89 + fix interactive CPU rendering (Michael)
90 + render memory usage graph (Dave Martin)
91
92bootchart2 0.12.3
93 + collector
94 + pclose after popen (Riccardo Magliocchetti (xrmx))
95 + fix buffer overflow (xrmx)
96 + count 'processor:' in /proc/cpuinfo for ARM (Michael)
97 + get model name from that line too for ARM (xrmx)
98 + store /proc/cpuinfo in the boot-chart archive (xrmx)
99 + try harder to detect missing TASKSTATS (Michael)
100 + sanity-check invalid domain names (Michael)
101 + detect missing PROC_EVENTS more reliably (Michael)
102 + README fixes (xrmx, Michael)
103 + pybootchartgui
104 + make num_cpu parsing robust (Michael)
105
106bootchart2 0.12.2
107 + fix pthread compile / linking bug
108
109bootchart2 0.12.1
110 + pybootchartgui
111 + pylint cleanup
112 + handle empty traces more elegantly
113 + add '-t' / '--boot-time' argument (Matthew Bauer)
114 + collector
115 + now GPLv2
116 + add rdinit support for very early initrd tracing
117 + cleanup / re-factor code into separate modules
118 + re-factor arg parsing, and parse remote process args
119 + handle missing bootchartd.conf cleanly
120 + move much of bootchartd from shell -> C
121 + drop dmesg and uname usage
122 + avoid rpm/dpkg with native version reporting
123
124bootchart2 0.12.0 (Michael Meeks)
125 + collector
126 + use netlink PROC_EVENTS to generate parentage data
127 + finally kills any need for 'acct' et. al.
128 + also removes need to poll /proc => faster
129 + cleanup code to K&R, 8 stop tabs.
130 + pybootchartgui
131 + consume thread parentage data
132
133bootchart2 0.11.4 (Michael Meeks)
134 + collector
135 + if run inside an initrd detect when /dev is writable
136 and remount ourselves into that.
137 + overflow buffers more elegantly in extremis
138 + dump full process path and command-line args
139 + calm down debugging output
140 + pybootchartgui
141 + can render logs in a directory again
142 + has a 'show more' option to show command-lines
143
144bootchart2 0.11.3 (Michael Meeks)
145 + add $$ display to the bootchart header
146 + process command-line bits
147 + fix collection code, and rename stream to match
148 + enable parsing, add check button to UI, and --show-all
149 command-line option
150 + fix parsing of directories full of files.
151
152bootchart2 0.11.2 (Michael Meeks)
153 + fix initrd sanity check to use the right proc path
154 + don't return a bogus error value when dumping state
155 + add -c to aid manual console debugging
156
157bootchart2 0.11.1 (Michael Meeks)
158 + even simpler initrd setup
159 + create a single directory: /lib/bootchart/tmpfs
160
161bootchart2 0.11 (Michael Meeks)
162 + bootchartd
163 + far, far simpler, less shell, more robustness etc.
164 + bootchart-collector
165 + remove the -p argument - we always mount proc
166 + requires /lib/bootchart (make install-chroot) to
167 be present (also in the initrd) [ with a kmsg
168 node included ]
169 + add a --probe-running mode
170 + ptrace re-write
171 + gives -much- better early-boot-time resolution
172 + unconditional chroot /lib/bootchart/chroot
173 + we mount proc there ourselves
174 + log extraction requires no common file-system view
175
176
177bootchart2 0.10.1 (Kel Modderman)
178 + collector arg -m should mount /proc
179 + remove bogus vcsid code
180 + split collector install in Makefile
181 + remove bogus debug code
182 + accept process names containing spaces
183
184bootchart2 0.10.0
185 + rendering (Anders Norgaard)
186 + fix for unknown exceptions
187 + interactive UI (Michael)
188 + much faster rendering by manual clipping
189 + horizontal scaling
190 + remove annoying page-up/down bindings
191 + initrd portability & fixes (Federic Crozat)
192 + port to Mandriva
193 + improved process waiting
194 + inittab commenting fix
195 + improved initrd detection / jail tagging
196 + fix for un-detectable accton behaviour change
197 + implement a built-in usleep to help initrd deps (Michael)
198
199bootchart2 0.0.9
200 + fix initrd bug
201
202bootchart2 0.0.8
203 + add a filename string to the window title in interactive mode
204 + add a NEWS file
diff --git a/scripts/pybootchartgui/README.pybootchart b/scripts/pybootchartgui/README.pybootchart
new file mode 100644
index 0000000000..8642e64679
--- /dev/null
+++ b/scripts/pybootchartgui/README.pybootchart
@@ -0,0 +1,37 @@
1 PYBOOTCHARTGUI
2 ----------------
3
4pybootchartgui is a tool (now included as part of bootchart2) for
5visualization and analysis of the GNU/Linux boot process. It renders
6the output of the boot-logger tool bootchart (see
7http://www.bootchart.org/) to either the screen or files of various
8formats. Bootchart collects information about the processes, their
9dependencies, and resource consumption during boot of a GNU/Linux
10system. The pybootchartgui tools visualizes the process tree and
11overall resource utilization.
12
13pybootchartgui is a port of the visualization part of bootchart from
14Java to Python and Cairo.
15
16Adapted from the bootchart-documentation:
17
18 The CPU and disk statistics are used to render stacked area and line
19 charts. The process information is used to create a Gantt chart
20 showing process dependency, states and CPU usage.
21
22 A typical boot sequence consists of several hundred processes. Since
23 it is difficult to visualize such amount of data in a comprehensible
24 way, tree pruning is utilized. Idle background processes and
25 short-lived processes are removed. Similar processes running in
26 parallel are also merged together.
27
28 Finally, the performance and dependency charts are rendered as a
29 single image to either the screen or in PNG, PDF or SVG format.
30
31
32To get help for pybootchartgui, run
33
34$ pybootchartgui --help
35
36This code was originally hosted at:
37 http://code.google.com/p/pybootchartgui/
diff --git a/scripts/pybootchartgui/pybootchartgui.py b/scripts/pybootchartgui/pybootchartgui.py
new file mode 100755
index 0000000000..947ce10338
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui.py
@@ -0,0 +1,23 @@
1#!/usr/bin/python
2#
3# This file is part of pybootchartgui.
4
5# pybootchartgui is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9
10# pybootchartgui is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14
15# You should have received a copy of the GNU General Public License
16# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
17
18
19import sys
20from pybootchartgui.main import main
21
22if __name__ == '__main__':
23 sys.exit(main())
diff --git a/scripts/pybootchartgui/pybootchartgui/__init__.py b/scripts/pybootchartgui/pybootchartgui/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/__init__.py
diff --git a/scripts/pybootchartgui/pybootchartgui/batch.py b/scripts/pybootchartgui/pybootchartgui/batch.py
new file mode 100644
index 0000000000..05c714e95e
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/batch.py
@@ -0,0 +1,46 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16import cairo
17from . import draw
18from .draw import RenderOptions
19
20def render(writer, trace, app_options, filename):
21 handlers = {
22 "png": (lambda w, h: cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h), \
23 lambda sfc: sfc.write_to_png(filename)),
24 "pdf": (lambda w, h: cairo.PDFSurface(filename, w, h), lambda sfc: 0),
25 "svg": (lambda w, h: cairo.SVGSurface(filename, w, h), lambda sfc: 0)
26 }
27
28 if app_options.format is None:
29 fmt = filename.rsplit('.', 1)[1]
30 else:
31 fmt = app_options.format
32
33 if not (fmt in handlers):
34 writer.error ("Unknown format '%s'." % fmt)
35 return 10
36
37 make_surface, write_surface = handlers[fmt]
38 options = RenderOptions (app_options)
39 (w, h) = draw.extents (options, 1.0, trace)
40 w = max (w, draw.MIN_IMG_W)
41 surface = make_surface (w, h)
42 ctx = cairo.Context (surface)
43 draw.render (ctx, options, 1.0, trace)
44 write_surface (surface)
45 writer.status ("bootchart written to '%s'" % filename)
46
diff --git a/scripts/pybootchartgui/pybootchartgui/draw.py b/scripts/pybootchartgui/pybootchartgui/draw.py
new file mode 100644
index 0000000000..8c574be50c
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/draw.py
@@ -0,0 +1,894 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16
17import cairo
18import math
19import re
20import random
21import colorsys
22from operator import itemgetter
23
24class RenderOptions:
25
26 def __init__(self, app_options):
27 # should we render a cumulative CPU time chart
28 self.cumulative = True
29 self.charts = True
30 self.kernel_only = False
31 self.app_options = app_options
32
33 def proc_tree (self, trace):
34 if self.kernel_only:
35 return trace.kernel_tree
36 else:
37 return trace.proc_tree
38
39# Process tree background color.
40BACK_COLOR = (1.0, 1.0, 1.0, 1.0)
41
42WHITE = (1.0, 1.0, 1.0, 1.0)
43# Process tree border color.
44BORDER_COLOR = (0.63, 0.63, 0.63, 1.0)
45# Second tick line color.
46TICK_COLOR = (0.92, 0.92, 0.92, 1.0)
47# 5-second tick line color.
48TICK_COLOR_BOLD = (0.86, 0.86, 0.86, 1.0)
49# Annotation colour
50ANNOTATION_COLOR = (0.63, 0.0, 0.0, 0.5)
51# Text color.
52TEXT_COLOR = (0.0, 0.0, 0.0, 1.0)
53
54# Font family
55FONT_NAME = "Bitstream Vera Sans"
56# Title text font.
57TITLE_FONT_SIZE = 18
58# Default text font.
59TEXT_FONT_SIZE = 12
60# Axis label font.
61AXIS_FONT_SIZE = 11
62# Legend font.
63LEGEND_FONT_SIZE = 12
64
65# CPU load chart color.
66CPU_COLOR = (0.40, 0.55, 0.70, 1.0)
67# IO wait chart color.
68IO_COLOR = (0.76, 0.48, 0.48, 0.5)
69# Disk throughput color.
70DISK_TPUT_COLOR = (0.20, 0.71, 0.20, 1.0)
71# CPU load chart color.
72FILE_OPEN_COLOR = (0.20, 0.71, 0.71, 1.0)
73# Mem cached color
74MEM_CACHED_COLOR = CPU_COLOR
75# Mem used color
76MEM_USED_COLOR = IO_COLOR
77# Buffers color
78MEM_BUFFERS_COLOR = (0.4, 0.4, 0.4, 0.3)
79# Swap color
80MEM_SWAP_COLOR = DISK_TPUT_COLOR
81
82# Process border color.
83PROC_BORDER_COLOR = (0.71, 0.71, 0.71, 1.0)
84# Waiting process color.
85PROC_COLOR_D = (0.76, 0.48, 0.48, 0.5)
86# Running process color.
87PROC_COLOR_R = CPU_COLOR
88# Sleeping process color.
89PROC_COLOR_S = (0.94, 0.94, 0.94, 1.0)
90# Stopped process color.
91PROC_COLOR_T = (0.94, 0.50, 0.50, 1.0)
92# Zombie process color.
93PROC_COLOR_Z = (0.71, 0.71, 0.71, 1.0)
94# Dead process color.
95PROC_COLOR_X = (0.71, 0.71, 0.71, 0.125)
96# Paging process color.
97PROC_COLOR_W = (0.71, 0.71, 0.71, 0.125)
98
99# Process label color.
100PROC_TEXT_COLOR = (0.19, 0.19, 0.19, 1.0)
101# Process label font.
102PROC_TEXT_FONT_SIZE = 12
103
104# Signature color.
105SIG_COLOR = (0.0, 0.0, 0.0, 0.3125)
106# Signature font.
107SIG_FONT_SIZE = 14
108# Signature text.
109SIGNATURE = "http://github.com/mmeeks/bootchart"
110
111# Process dependency line color.
112DEP_COLOR = (0.75, 0.75, 0.75, 1.0)
113# Process dependency line stroke.
114DEP_STROKE = 1.0
115
116# Process description date format.
117DESC_TIME_FORMAT = "mm:ss.SSS"
118
119# Cumulative coloring bits
120HSV_MAX_MOD = 31
121HSV_STEP = 7
122
123# Configure task color
124TASK_COLOR_CONFIGURE = (1.0, 1.0, 0.00, 1.0)
125# Compile task color.
126TASK_COLOR_COMPILE = (0.0, 1.00, 0.00, 1.0)
127# Install task color
128TASK_COLOR_INSTALL = (1.0, 0.00, 1.00, 1.0)
129# Sysroot task color
130TASK_COLOR_SYSROOT = (0.0, 0.00, 1.00, 1.0)
131# Package task color
132TASK_COLOR_PACKAGE = (0.0, 1.00, 1.00, 1.0)
133# Package Write RPM/DEB/IPK task color
134TASK_COLOR_PACKAGE_WRITE = (0.0, 0.50, 0.50, 1.0)
135
136# Process states
137STATE_UNDEFINED = 0
138STATE_RUNNING = 1
139STATE_SLEEPING = 2
140STATE_WAITING = 3
141STATE_STOPPED = 4
142STATE_ZOMBIE = 5
143
144STATE_COLORS = [(0, 0, 0, 0), PROC_COLOR_R, PROC_COLOR_S, PROC_COLOR_D, \
145 PROC_COLOR_T, PROC_COLOR_Z, PROC_COLOR_X, PROC_COLOR_W]
146
147# CumulativeStats Types
148STAT_TYPE_CPU = 0
149STAT_TYPE_IO = 1
150
151# Convert ps process state to an int
152def get_proc_state(flag):
153 return "RSDTZXW".find(flag) + 1
154
155def draw_text(ctx, text, color, x, y):
156 ctx.set_source_rgba(*color)
157 ctx.move_to(x, y)
158 ctx.show_text(text)
159
160def draw_fill_rect(ctx, color, rect):
161 ctx.set_source_rgba(*color)
162 ctx.rectangle(*rect)
163 ctx.fill()
164
165def draw_rect(ctx, color, rect):
166 ctx.set_source_rgba(*color)
167 ctx.rectangle(*rect)
168 ctx.stroke()
169
170def draw_legend_box(ctx, label, fill_color, x, y, s):
171 draw_fill_rect(ctx, fill_color, (x, y - s, s, s))
172 draw_rect(ctx, PROC_BORDER_COLOR, (x, y - s, s, s))
173 draw_text(ctx, label, TEXT_COLOR, x + s + 5, y)
174
175def draw_legend_line(ctx, label, fill_color, x, y, s):
176 draw_fill_rect(ctx, fill_color, (x, y - s/2, s + 1, 3))
177 ctx.arc(x + (s + 1)/2.0, y - (s - 3)/2.0, 2.5, 0, 2.0 * math.pi)
178 ctx.fill()
179 draw_text(ctx, label, TEXT_COLOR, x + s + 5, y)
180
181def draw_label_in_box(ctx, color, label, x, y, w, maxx):
182 label_w = ctx.text_extents(label)[2]
183 label_x = x + w / 2 - label_w / 2
184 if label_w + 10 > w:
185 label_x = x + w + 5
186 if label_x + label_w > maxx:
187 label_x = x - label_w - 5
188 draw_text(ctx, label, color, label_x, y)
189
190def draw_sec_labels(ctx, options, rect, sec_w, nsecs):
191 ctx.set_font_size(AXIS_FONT_SIZE)
192 prev_x = 0
193 for i in range(0, rect[2] + 1, sec_w):
194 if ((i / sec_w) % nsecs == 0) :
195 if options.app_options.as_minutes :
196 label = "%.1f" % (i / sec_w / 60.0)
197 else :
198 label = "%d" % (i / sec_w)
199 label_w = ctx.text_extents(label)[2]
200 x = rect[0] + i - label_w/2
201 if x >= prev_x:
202 draw_text(ctx, label, TEXT_COLOR, x, rect[1] - 2)
203 prev_x = x + label_w
204
205def draw_box_ticks(ctx, rect, sec_w):
206 draw_rect(ctx, BORDER_COLOR, tuple(rect))
207
208 ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
209
210 for i in range(sec_w, rect[2] + 1, sec_w):
211 if ((i / sec_w) % 10 == 0) :
212 ctx.set_line_width(1.5)
213 elif sec_w < 5 :
214 continue
215 else :
216 ctx.set_line_width(1.0)
217 if ((i / sec_w) % 30 == 0) :
218 ctx.set_source_rgba(*TICK_COLOR_BOLD)
219 else :
220 ctx.set_source_rgba(*TICK_COLOR)
221 ctx.move_to(rect[0] + i, rect[1] + 1)
222 ctx.line_to(rect[0] + i, rect[1] + rect[3] - 1)
223 ctx.stroke()
224 ctx.set_line_width(1.0)
225
226 ctx.set_line_cap(cairo.LINE_CAP_BUTT)
227
228def draw_annotations(ctx, proc_tree, times, rect):
229 ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
230 ctx.set_source_rgba(*ANNOTATION_COLOR)
231 ctx.set_dash([4, 4])
232
233 for time in times:
234 if time is not None:
235 x = ((time - proc_tree.start_time) * rect[2] / proc_tree.duration)
236
237 ctx.move_to(rect[0] + x, rect[1] + 1)
238 ctx.line_to(rect[0] + x, rect[1] + rect[3] - 1)
239 ctx.stroke()
240
241 ctx.set_line_cap(cairo.LINE_CAP_BUTT)
242 ctx.set_dash([])
243
244def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree, data_range):
245 ctx.set_line_width(0.5)
246 x_shift = proc_tree.start_time
247
248 def transform_point_coords(point, x_base, y_base, \
249 xscale, yscale, x_trans, y_trans):
250 x = (point[0] - x_base) * xscale + x_trans
251 y = (point[1] - y_base) * -yscale + y_trans + chart_bounds[3]
252 return x, y
253
254 max_x = max (x for (x, y) in data)
255 max_y = max (y for (x, y) in data)
256 # avoid divide by zero
257 if max_y == 0:
258 max_y = 1.0
259 xscale = float (chart_bounds[2]) / max_x
260 # If data_range is given, scale the chart so that the value range in
261 # data_range matches the chart bounds exactly.
262 # Otherwise, scale so that the actual data matches the chart bounds.
263 if data_range:
264 yscale = float(chart_bounds[3]) / (data_range[1] - data_range[0])
265 ybase = data_range[0]
266 else:
267 yscale = float(chart_bounds[3]) / max_y
268 ybase = 0
269
270 first = transform_point_coords (data[0], x_shift, ybase, xscale, yscale, \
271 chart_bounds[0], chart_bounds[1])
272 last = transform_point_coords (data[-1], x_shift, ybase, xscale, yscale, \
273 chart_bounds[0], chart_bounds[1])
274
275 ctx.set_source_rgba(*color)
276 ctx.move_to(*first)
277 for point in data:
278 x, y = transform_point_coords (point, x_shift, ybase, xscale, yscale, \
279 chart_bounds[0], chart_bounds[1])
280 ctx.line_to(x, y)
281 if fill:
282 ctx.stroke_preserve()
283 ctx.line_to(last[0], chart_bounds[1]+chart_bounds[3])
284 ctx.line_to(first[0], chart_bounds[1]+chart_bounds[3])
285 ctx.line_to(first[0], first[1])
286 ctx.fill()
287 else:
288 ctx.stroke()
289 ctx.set_line_width(1.0)
290
291bar_h = 55
292meminfo_bar_h = 2 * bar_h
293header_h = 60
294# offsets
295off_x, off_y = 220, 10
296sec_w_base = 1 # the width of a second
297proc_h = 16 # the height of a process
298leg_s = 10
299MIN_IMG_W = 800
300CUML_HEIGHT = 2000 # Increased value to accomodate CPU and I/O Graphs
301OPTIONS = None
302
303def extents(options, xscale, trace):
304 start = min(trace.start.keys())
305 end = start
306
307 processes = 0
308 for proc in trace.processes:
309 if not options.app_options.show_all and \
310 trace.processes[proc][1] - trace.processes[proc][0] < options.app_options.mintime:
311 continue
312
313 if trace.processes[proc][1] > end:
314 end = trace.processes[proc][1]
315 processes += 1
316
317 if trace.min is not None and trace.max is not None:
318 start = trace.min
319 end = trace.max
320
321 w = int ((end - start) * sec_w_base * xscale) + 2 * off_x
322 h = proc_h * processes + header_h + 2 * off_y
323
324 return (w, h)
325
326def clip_visible(clip, rect):
327 xmax = max (clip[0], rect[0])
328 ymax = max (clip[1], rect[1])
329 xmin = min (clip[0] + clip[2], rect[0] + rect[2])
330 ymin = min (clip[1] + clip[3], rect[1] + rect[3])
331 return (xmin > xmax and ymin > ymax)
332
333def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
334 proc_tree = options.proc_tree(trace)
335
336 # render bar legend
337 ctx.set_font_size(LEGEND_FONT_SIZE)
338
339 draw_legend_box(ctx, "CPU (user+sys)", CPU_COLOR, off_x, curr_y+20, leg_s)
340 draw_legend_box(ctx, "I/O (wait)", IO_COLOR, off_x + 120, curr_y+20, leg_s)
341
342 # render I/O wait
343 chart_rect = (off_x, curr_y+30, w, bar_h)
344 if clip_visible (clip, chart_rect):
345 draw_box_ticks (ctx, chart_rect, sec_w)
346 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
347 draw_chart (ctx, IO_COLOR, True, chart_rect, \
348 [(sample.time, sample.user + sample.sys + sample.io) for sample in trace.cpu_stats], \
349 proc_tree, None)
350 # render CPU load
351 draw_chart (ctx, CPU_COLOR, True, chart_rect, \
352 [(sample.time, sample.user + sample.sys) for sample in trace.cpu_stats], \
353 proc_tree, None)
354
355 curr_y = curr_y + 30 + bar_h
356
357 # render second chart
358 draw_legend_line(ctx, "Disk throughput", DISK_TPUT_COLOR, off_x, curr_y+20, leg_s)
359 draw_legend_box(ctx, "Disk utilization", IO_COLOR, off_x + 120, curr_y+20, leg_s)
360
361 # render I/O utilization
362 chart_rect = (off_x, curr_y+30, w, bar_h)
363 if clip_visible (clip, chart_rect):
364 draw_box_ticks (ctx, chart_rect, sec_w)
365 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
366 draw_chart (ctx, IO_COLOR, True, chart_rect, \
367 [(sample.time, sample.util) for sample in trace.disk_stats], \
368 proc_tree, None)
369
370 # render disk throughput
371 max_sample = max (trace.disk_stats, key = lambda s: s.tput)
372 if clip_visible (clip, chart_rect):
373 draw_chart (ctx, DISK_TPUT_COLOR, False, chart_rect, \
374 [(sample.time, sample.tput) for sample in trace.disk_stats], \
375 proc_tree, None)
376
377 pos_x = off_x + ((max_sample.time - proc_tree.start_time) * w / proc_tree.duration)
378
379 shift_x, shift_y = -20, 20
380 if (pos_x < off_x + 245):
381 shift_x, shift_y = 5, 40
382
383 label = "%dMB/s" % round ((max_sample.tput) / 1024.0)
384 draw_text (ctx, label, DISK_TPUT_COLOR, pos_x + shift_x, curr_y + shift_y)
385
386 curr_y = curr_y + 30 + bar_h
387
388 # render mem usage
389 chart_rect = (off_x, curr_y+30, w, meminfo_bar_h)
390 mem_stats = trace.mem_stats
391 if mem_stats and clip_visible (clip, chart_rect):
392 mem_scale = max(sample.records['MemTotal'] - sample.records['MemFree'] for sample in mem_stats)
393 draw_legend_box(ctx, "Mem cached (scale: %u MiB)" % (float(mem_scale) / 1024), MEM_CACHED_COLOR, off_x, curr_y+20, leg_s)
394 draw_legend_box(ctx, "Used", MEM_USED_COLOR, off_x + 240, curr_y+20, leg_s)
395 draw_legend_box(ctx, "Buffers", MEM_BUFFERS_COLOR, off_x + 360, curr_y+20, leg_s)
396 draw_legend_line(ctx, "Swap (scale: %u MiB)" % max([(sample.records['SwapTotal'] - sample.records['SwapFree'])/1024 for sample in mem_stats]), \
397 MEM_SWAP_COLOR, off_x + 480, curr_y+20, leg_s)
398 draw_box_ticks(ctx, chart_rect, sec_w)
399 draw_annotations(ctx, proc_tree, trace.times, chart_rect)
400 draw_chart(ctx, MEM_BUFFERS_COLOR, True, chart_rect, \
401 [(sample.time, sample.records['MemTotal'] - sample.records['MemFree']) for sample in trace.mem_stats], \
402 proc_tree, [0, mem_scale])
403 draw_chart(ctx, MEM_USED_COLOR, True, chart_rect, \
404 [(sample.time, sample.records['MemTotal'] - sample.records['MemFree'] - sample.records['Buffers']) for sample in mem_stats], \
405 proc_tree, [0, mem_scale])
406 draw_chart(ctx, MEM_CACHED_COLOR, True, chart_rect, \
407 [(sample.time, sample.records['Cached']) for sample in mem_stats], \
408 proc_tree, [0, mem_scale])
409 draw_chart(ctx, MEM_SWAP_COLOR, False, chart_rect, \
410 [(sample.time, float(sample.records['SwapTotal'] - sample.records['SwapFree'])) for sample in mem_stats], \
411 proc_tree, None)
412
413 curr_y = curr_y + meminfo_bar_h
414
415 return curr_y
416
417def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
418 chart_rect = [off_x, curr_y+header_h, w, h - 2 * off_y - (curr_y+header_h) + proc_h]
419
420 draw_legend_box (ctx, "Configure", \
421 TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s)
422 draw_legend_box (ctx, "Compile", \
423 TASK_COLOR_COMPILE, off_x+120, curr_y + 45, leg_s)
424 draw_legend_box (ctx, "Install", \
425 TASK_COLOR_INSTALL, off_x+240, curr_y + 45, leg_s)
426 draw_legend_box (ctx, "Populate Sysroot", \
427 TASK_COLOR_SYSROOT, off_x+360, curr_y + 45, leg_s)
428 draw_legend_box (ctx, "Package", \
429 TASK_COLOR_PACKAGE, off_x+480, curr_y + 45, leg_s)
430 draw_legend_box (ctx, "Package Write",
431 TASK_COLOR_PACKAGE_WRITE, off_x+600, curr_y + 45, leg_s)
432
433 ctx.set_font_size(PROC_TEXT_FONT_SIZE)
434
435 draw_box_ticks(ctx, chart_rect, sec_w)
436 draw_sec_labels(ctx, options, chart_rect, sec_w, 30)
437
438 y = curr_y+header_h
439
440 offset = trace.min or min(trace.start.keys())
441 for s in sorted(trace.start.keys()):
442 for val in sorted(trace.start[s]):
443 if not options.app_options.show_all and \
444 trace.processes[val][1] - s < options.app_options.mintime:
445 continue
446 task = val.split(":")[1]
447 #print val
448 #print trace.processes[val][1]
449 #print s
450 x = chart_rect[0] + (s - offset) * sec_w
451 w = ((trace.processes[val][1] - s) * sec_w)
452
453 #print "proc at %s %s %s %s" % (x, y, w, proc_h)
454 col = None
455 if task == "do_compile":
456 col = TASK_COLOR_COMPILE
457 elif task == "do_configure":
458 col = TASK_COLOR_CONFIGURE
459 elif task == "do_install":
460 col = TASK_COLOR_INSTALL
461 elif task == "do_populate_sysroot":
462 col = TASK_COLOR_SYSROOT
463 elif task == "do_package":
464 col = TASK_COLOR_PACKAGE
465 elif task == "do_package_write_rpm" or \
466 task == "do_package_write_deb" or \
467 task == "do_package_write_ipk":
468 col = TASK_COLOR_PACKAGE_WRITE
469 else:
470 col = WHITE
471
472 if col:
473 draw_fill_rect(ctx, col, (x, y, w, proc_h))
474 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
475
476 draw_label_in_box(ctx, PROC_TEXT_COLOR, val, x, y + proc_h - 4, w, proc_h)
477 y = y + proc_h
478
479 return curr_y
480
481#
482# Render the chart.
483#
484def render(ctx, options, xscale, trace):
485 (w, h) = extents (options, xscale, trace)
486 global OPTIONS
487 OPTIONS = options.app_options
488
489 # x, y, w, h
490 clip = ctx.clip_extents()
491
492 sec_w = int (xscale * sec_w_base)
493 ctx.set_line_width(1.0)
494 ctx.select_font_face(FONT_NAME)
495 draw_fill_rect(ctx, WHITE, (0, 0, max(w, MIN_IMG_W), h))
496 w -= 2*off_x
497 curr_y = off_y;
498
499 curr_y = render_processes_chart (ctx, options, trace, curr_y, w, h, sec_w)
500
501 return
502
503 proc_tree = options.proc_tree (trace)
504
505 # draw the title and headers
506 if proc_tree.idle:
507 duration = proc_tree.idle
508 else:
509 duration = proc_tree.duration
510
511 if not options.kernel_only:
512 curr_y = draw_header (ctx, trace.headers, duration)
513 else:
514 curr_y = off_y;
515
516 if options.charts:
517 curr_y = render_charts (ctx, options, clip, trace, curr_y, w, h, sec_w)
518
519 # draw process boxes
520 proc_height = h
521 if proc_tree.taskstats and options.cumulative:
522 proc_height -= CUML_HEIGHT
523
524 draw_process_bar_chart(ctx, clip, options, proc_tree, trace.times,
525 curr_y, w, proc_height, sec_w)
526
527 curr_y = proc_height
528 ctx.set_font_size(SIG_FONT_SIZE)
529 draw_text(ctx, SIGNATURE, SIG_COLOR, off_x + 5, proc_height - 8)
530
531 # draw a cumulative CPU-time-per-process graph
532 if proc_tree.taskstats and options.cumulative:
533 cuml_rect = (off_x, curr_y + off_y, w, CUML_HEIGHT/2 - off_y * 2)
534 if clip_visible (clip, cuml_rect):
535 draw_cuml_graph(ctx, proc_tree, cuml_rect, duration, sec_w, STAT_TYPE_CPU)
536
537 # draw a cumulative I/O-time-per-process graph
538 if proc_tree.taskstats and options.cumulative:
539 cuml_rect = (off_x, curr_y + off_y * 100, w, CUML_HEIGHT/2 - off_y * 2)
540 if clip_visible (clip, cuml_rect):
541 draw_cuml_graph(ctx, proc_tree, cuml_rect, duration, sec_w, STAT_TYPE_IO)
542
543def draw_process_bar_chart(ctx, clip, options, proc_tree, times, curr_y, w, h, sec_w):
544 header_size = 0
545 if not options.kernel_only:
546 draw_legend_box (ctx, "Running (%cpu)",
547 PROC_COLOR_R, off_x , curr_y + 45, leg_s)
548 draw_legend_box (ctx, "Unint.sleep (I/O)",
549 PROC_COLOR_D, off_x+120, curr_y + 45, leg_s)
550 draw_legend_box (ctx, "Sleeping",
551 PROC_COLOR_S, off_x+240, curr_y + 45, leg_s)
552 draw_legend_box (ctx, "Zombie",
553 PROC_COLOR_Z, off_x+360, curr_y + 45, leg_s)
554 header_size = 45
555
556 chart_rect = [off_x, curr_y + header_size + 15,
557 w, h - 2 * off_y - (curr_y + header_size + 15) + proc_h]
558 ctx.set_font_size (PROC_TEXT_FONT_SIZE)
559
560 draw_box_ticks (ctx, chart_rect, sec_w)
561 if sec_w > 100:
562 nsec = 1
563 else:
564 nsec = 5
565 draw_sec_labels (ctx, options, chart_rect, sec_w, nsec)
566 draw_annotations (ctx, proc_tree, times, chart_rect)
567
568 y = curr_y + 60
569 for root in proc_tree.process_tree:
570 draw_processes_recursively(ctx, root, proc_tree, y, proc_h, chart_rect, clip)
571 y = y + proc_h * proc_tree.num_nodes([root])
572
573
574def draw_header (ctx, headers, duration):
575 toshow = [
576 ('system.uname', 'uname', lambda s: s),
577 ('system.release', 'release', lambda s: s),
578 ('system.cpu', 'CPU', lambda s: re.sub('model name\s*:\s*', '', s, 1)),
579 ('system.kernel.options', 'kernel options', lambda s: s),
580 ]
581
582 header_y = ctx.font_extents()[2] + 10
583 ctx.set_font_size(TITLE_FONT_SIZE)
584 draw_text(ctx, headers['title'], TEXT_COLOR, off_x, header_y)
585 ctx.set_font_size(TEXT_FONT_SIZE)
586
587 for (headerkey, headertitle, mangle) in toshow:
588 header_y += ctx.font_extents()[2]
589 if headerkey in headers:
590 value = headers.get(headerkey)
591 else:
592 value = ""
593 txt = headertitle + ': ' + mangle(value)
594 draw_text(ctx, txt, TEXT_COLOR, off_x, header_y)
595
596 dur = duration / 100.0
597 txt = 'time : %02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60))
598 if headers.get('system.maxpid') is not None:
599 txt = txt + ' max pid: %s' % (headers.get('system.maxpid'))
600
601 header_y += ctx.font_extents()[2]
602 draw_text (ctx, txt, TEXT_COLOR, off_x, header_y)
603
604 return header_y
605
606def draw_processes_recursively(ctx, proc, proc_tree, y, proc_h, rect, clip) :
607 x = rect[0] + ((proc.start_time - proc_tree.start_time) * rect[2] / proc_tree.duration)
608 w = ((proc.duration) * rect[2] / proc_tree.duration)
609
610 draw_process_activity_colors(ctx, proc, proc_tree, x, y, w, proc_h, rect, clip)
611 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
612 ipid = int(proc.pid)
613 if not OPTIONS.show_all:
614 cmdString = proc.cmd
615 else:
616 cmdString = ''
617 if (OPTIONS.show_pid or OPTIONS.show_all) and ipid is not 0:
618 cmdString = cmdString + " [" + str(ipid // 1000) + "]"
619 if OPTIONS.show_all:
620 if proc.args:
621 cmdString = cmdString + " '" + "' '".join(proc.args) + "'"
622 else:
623 cmdString = cmdString + " " + proc.exe
624
625 draw_label_in_box(ctx, PROC_TEXT_COLOR, cmdString, x, y + proc_h - 4, w, rect[0] + rect[2])
626
627 next_y = y + proc_h
628 for child in proc.child_list:
629 if next_y > clip[1] + clip[3]:
630 break
631 child_x, child_y = draw_processes_recursively(ctx, child, proc_tree, next_y, proc_h, rect, clip)
632 draw_process_connecting_lines(ctx, x, y, child_x, child_y, proc_h)
633 next_y = next_y + proc_h * proc_tree.num_nodes([child])
634
635 return x, y
636
637
638def draw_process_activity_colors(ctx, proc, proc_tree, x, y, w, proc_h, rect, clip):
639
640 if y > clip[1] + clip[3] or y + proc_h + 2 < clip[1]:
641 return
642
643 draw_fill_rect(ctx, PROC_COLOR_S, (x, y, w, proc_h))
644
645 last_tx = -1
646 for sample in proc.samples :
647 tx = rect[0] + round(((sample.time - proc_tree.start_time) * rect[2] / proc_tree.duration))
648
649 # samples are sorted chronologically
650 if tx < clip[0]:
651 continue
652 if tx > clip[0] + clip[2]:
653 break
654
655 tw = round(proc_tree.sample_period * rect[2] / float(proc_tree.duration))
656 if last_tx != -1 and abs(last_tx - tx) <= tw:
657 tw -= last_tx - tx
658 tx = last_tx
659 tw = max (tw, 1) # nice to see at least something
660
661 last_tx = tx + tw
662 state = get_proc_state( sample.state )
663
664 color = STATE_COLORS[state]
665 if state == STATE_RUNNING:
666 alpha = min (sample.cpu_sample.user + sample.cpu_sample.sys, 1.0)
667 color = tuple(list(PROC_COLOR_R[0:3]) + [alpha])
668# print "render time %d [ tx %d tw %d ], sample state %s color %s alpha %g" % (sample.time, tx, tw, state, color, alpha)
669 elif state == STATE_SLEEPING:
670 continue
671
672 draw_fill_rect(ctx, color, (tx, y, tw, proc_h))
673
674def draw_process_connecting_lines(ctx, px, py, x, y, proc_h):
675 ctx.set_source_rgba(*DEP_COLOR)
676 ctx.set_dash([2, 2])
677 if abs(px - x) < 3:
678 dep_off_x = 3
679 dep_off_y = proc_h / 4
680 ctx.move_to(x, y + proc_h / 2)
681 ctx.line_to(px - dep_off_x, y + proc_h / 2)
682 ctx.line_to(px - dep_off_x, py - dep_off_y)
683 ctx.line_to(px, py - dep_off_y)
684 else:
685 ctx.move_to(x, y + proc_h / 2)
686 ctx.line_to(px, y + proc_h / 2)
687 ctx.line_to(px, py)
688 ctx.stroke()
689 ctx.set_dash([])
690
691# elide the bootchart collector - it is quite distorting
692def elide_bootchart(proc):
693 return proc.cmd == 'bootchartd' or proc.cmd == 'bootchart-colle'
694
695class CumlSample:
696 def __init__(self, proc):
697 self.cmd = proc.cmd
698 self.samples = []
699 self.merge_samples (proc)
700 self.color = None
701
702 def merge_samples(self, proc):
703 self.samples.extend (proc.samples)
704 self.samples.sort (key = lambda p: p.time)
705
706 def next(self):
707 global palette_idx
708 palette_idx += HSV_STEP
709 return palette_idx
710
711 def get_color(self):
712 if self.color is None:
713 i = self.next() % HSV_MAX_MOD
714 h = 0.0
715 if i is not 0:
716 h = (1.0 * i) / HSV_MAX_MOD
717 s = 0.5
718 v = 1.0
719 c = colorsys.hsv_to_rgb (h, s, v)
720 self.color = (c[0], c[1], c[2], 1.0)
721 return self.color
722
723
724def draw_cuml_graph(ctx, proc_tree, chart_bounds, duration, sec_w, stat_type):
725 global palette_idx
726 palette_idx = 0
727
728 time_hash = {}
729 total_time = 0.0
730 m_proc_list = {}
731
732 if stat_type is STAT_TYPE_CPU:
733 sample_value = 'cpu'
734 else:
735 sample_value = 'io'
736 for proc in proc_tree.process_list:
737 if elide_bootchart(proc):
738 continue
739
740 for sample in proc.samples:
741 total_time += getattr(sample.cpu_sample, sample_value)
742 if not sample.time in time_hash:
743 time_hash[sample.time] = 1
744
745 # merge pids with the same cmd
746 if not proc.cmd in m_proc_list:
747 m_proc_list[proc.cmd] = CumlSample (proc)
748 continue
749 s = m_proc_list[proc.cmd]
750 s.merge_samples (proc)
751
752 # all the sample times
753 times = sorted(time_hash)
754 if len (times) < 2:
755 print("degenerate boot chart")
756 return
757
758 pix_per_ns = chart_bounds[3] / total_time
759# print "total time: %g pix-per-ns %g" % (total_time, pix_per_ns)
760
761 # FIXME: we have duplicates in the process list too [!] - why !?
762
763 # Render bottom up, left to right
764 below = {}
765 for time in times:
766 below[time] = chart_bounds[1] + chart_bounds[3]
767
768 # same colors each time we render
769 random.seed (0)
770
771 ctx.set_line_width(1)
772
773 legends = []
774 labels = []
775
776 # render each pid in order
777 for cs in m_proc_list.values():
778 row = {}
779 cuml = 0.0
780
781 # print "pid : %s -> %g samples %d" % (proc.cmd, cuml, len (cs.samples))
782 for sample in cs.samples:
783 cuml += getattr(sample.cpu_sample, sample_value)
784 row[sample.time] = cuml
785
786 process_total_time = cuml
787
788 # hide really tiny processes
789 if cuml * pix_per_ns <= 2:
790 continue
791
792 last_time = times[0]
793 y = last_below = below[last_time]
794 last_cuml = cuml = 0.0
795
796 ctx.set_source_rgba(*cs.get_color())
797 for time in times:
798 render_seg = False
799
800 # did the underlying trend increase ?
801 if below[time] != last_below:
802 last_below = below[last_time]
803 last_cuml = cuml
804 render_seg = True
805
806 # did we move up a pixel increase ?
807 if time in row:
808 nc = round (row[time] * pix_per_ns)
809 if nc != cuml:
810 last_cuml = cuml
811 cuml = nc
812 render_seg = True
813
814# if last_cuml > cuml:
815# assert fail ... - un-sorted process samples
816
817 # draw the trailing rectangle from the last time to
818 # before now, at the height of the last segment.
819 if render_seg:
820 w = math.ceil ((time - last_time) * chart_bounds[2] / proc_tree.duration) + 1
821 x = chart_bounds[0] + round((last_time - proc_tree.start_time) * chart_bounds[2] / proc_tree.duration)
822 ctx.rectangle (x, below[last_time] - last_cuml, w, last_cuml)
823 ctx.fill()
824# ctx.stroke()
825 last_time = time
826 y = below [time] - cuml
827
828 row[time] = y
829
830 # render the last segment
831 x = chart_bounds[0] + round((last_time - proc_tree.start_time) * chart_bounds[2] / proc_tree.duration)
832 y = below[last_time] - cuml
833 ctx.rectangle (x, y, chart_bounds[2] - x, cuml)
834 ctx.fill()
835# ctx.stroke()
836
837 # render legend if it will fit
838 if cuml > 8:
839 label = cs.cmd
840 extnts = ctx.text_extents(label)
841 label_w = extnts[2]
842 label_h = extnts[3]
843# print "Text extents %g by %g" % (label_w, label_h)
844 labels.append((label,
845 chart_bounds[0] + chart_bounds[2] - label_w - off_x * 2,
846 y + (cuml + label_h) / 2))
847 if cs in legends:
848 print("ARGH - duplicate process in list !")
849
850 legends.append ((cs, process_total_time))
851
852 below = row
853
854 # render grid-lines over the top
855 draw_box_ticks(ctx, chart_bounds, sec_w)
856
857 # render labels
858 for l in labels:
859 draw_text(ctx, l[0], TEXT_COLOR, l[1], l[2])
860
861 # Render legends
862 font_height = 20
863 label_width = 300
864 LEGENDS_PER_COL = 15
865 LEGENDS_TOTAL = 45
866 ctx.set_font_size (TITLE_FONT_SIZE)
867 dur_secs = duration / 100
868 cpu_secs = total_time / 1000000000
869
870 # misleading - with multiple CPUs ...
871# idle = ((dur_secs - cpu_secs) / dur_secs) * 100.0
872 if stat_type is STAT_TYPE_CPU:
873 label = "Cumulative CPU usage, by process; total CPU: " \
874 " %.5g(s) time: %.3g(s)" % (cpu_secs, dur_secs)
875 else:
876 label = "Cumulative I/O usage, by process; total I/O: " \
877 " %.5g(s) time: %.3g(s)" % (cpu_secs, dur_secs)
878
879 draw_text(ctx, label, TEXT_COLOR, chart_bounds[0] + off_x,
880 chart_bounds[1] + font_height)
881
882 i = 0
883 legends = sorted(legends, key=itemgetter(1), reverse=True)
884 ctx.set_font_size(TEXT_FONT_SIZE)
885 for t in legends:
886 cs = t[0]
887 time = t[1]
888 x = chart_bounds[0] + off_x + int (i/LEGENDS_PER_COL) * label_width
889 y = chart_bounds[1] + font_height * ((i % LEGENDS_PER_COL) + 2)
890 str = "%s - %.0f(ms) (%2.2f%%)" % (cs.cmd, time/1000000, (time/total_time) * 100.0)
891 draw_legend_box(ctx, str, cs.color, x, y, leg_s)
892 i = i + 1
893 if i >= LEGENDS_TOTAL:
894 break
diff --git a/scripts/pybootchartgui/pybootchartgui/gui.py b/scripts/pybootchartgui/pybootchartgui/gui.py
new file mode 100644
index 0000000000..7fedd232df
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/gui.py
@@ -0,0 +1,350 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16import gobject
17import gtk
18import gtk.gdk
19import gtk.keysyms
20from . import draw
21from .draw import RenderOptions
22
23class PyBootchartWidget(gtk.DrawingArea):
24 __gsignals__ = {
25 'expose-event': 'override',
26 'clicked' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, gtk.gdk.Event)),
27 'position-changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_INT)),
28 'set-scroll-adjustments' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gtk.Adjustment, gtk.Adjustment))
29 }
30
31 def __init__(self, trace, options, xscale):
32 gtk.DrawingArea.__init__(self)
33
34 self.trace = trace
35 self.options = options
36
37 self.set_flags(gtk.CAN_FOCUS)
38
39 self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
40 self.connect("button-press-event", self.on_area_button_press)
41 self.connect("button-release-event", self.on_area_button_release)
42 self.add_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
43 self.connect("motion-notify-event", self.on_area_motion_notify)
44 self.connect("scroll-event", self.on_area_scroll_event)
45 self.connect('key-press-event', self.on_key_press_event)
46
47 self.connect('set-scroll-adjustments', self.on_set_scroll_adjustments)
48 self.connect("size-allocate", self.on_allocation_size_changed)
49 self.connect("position-changed", self.on_position_changed)
50
51 self.zoom_ratio = 1.0
52 self.xscale = xscale
53 self.x, self.y = 0.0, 0.0
54
55 self.chart_width, self.chart_height = draw.extents(self.options, self.xscale, self.trace)
56 self.hadj = None
57 self.vadj = None
58 self.hadj_changed_signal_id = None
59 self.vadj_changed_signal_id = None
60
61 def do_expose_event(self, event):
62 cr = self.window.cairo_create()
63
64 # set a clip region for the expose event
65 cr.rectangle(
66 event.area.x, event.area.y,
67 event.area.width, event.area.height
68 )
69 cr.clip()
70 self.draw(cr, self.get_allocation())
71 return False
72
73 def draw(self, cr, rect):
74 cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
75 cr.paint()
76 cr.scale(self.zoom_ratio, self.zoom_ratio)
77 cr.translate(-self.x, -self.y)
78 draw.render(cr, self.options, self.xscale, self.trace)
79
80 def position_changed(self):
81 self.emit("position-changed", self.x, self.y)
82
83 ZOOM_INCREMENT = 1.25
84
85 def zoom_image (self, zoom_ratio):
86 self.zoom_ratio = zoom_ratio
87 self._set_scroll_adjustments (self.hadj, self.vadj)
88 self.queue_draw()
89
90 def zoom_to_rect (self, rect):
91 zoom_ratio = float(rect.width)/float(self.chart_width)
92 self.zoom_image(zoom_ratio)
93 self.x = 0
94 self.position_changed()
95
96 def set_xscale(self, xscale):
97 old_mid_x = self.x + self.hadj.page_size / 2
98 self.xscale = xscale
99 self.chart_width, self.chart_height = draw.extents(self.options, self.xscale, self.trace)
100 new_x = old_mid_x
101 self.zoom_image (self.zoom_ratio)
102
103 def on_expand(self, action):
104 self.set_xscale (int(self.xscale * 1.5 + 0.5))
105
106 def on_contract(self, action):
107 self.set_xscale (max(int(self.xscale / 1.5), 1))
108
109 def on_zoom_in(self, action):
110 self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT)
111
112 def on_zoom_out(self, action):
113 self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT)
114
115 def on_zoom_fit(self, action):
116 self.zoom_to_rect(self.get_allocation())
117
118 def on_zoom_100(self, action):
119 self.zoom_image(1.0)
120 self.set_xscale(1.0)
121
122 def show_toggled(self, button):
123 self.options.app_options.show_all = button.get_property ('active')
124 self.chart_width, self.chart_height = draw.extents(self.options, self.xscale, self.trace)
125 self._set_scroll_adjustments(self.hadj, self.vadj)
126 self.queue_draw()
127
128 POS_INCREMENT = 100
129
130 def on_key_press_event(self, widget, event):
131 if event.keyval == gtk.keysyms.Left:
132 self.x -= self.POS_INCREMENT/self.zoom_ratio
133 elif event.keyval == gtk.keysyms.Right:
134 self.x += self.POS_INCREMENT/self.zoom_ratio
135 elif event.keyval == gtk.keysyms.Up:
136 self.y -= self.POS_INCREMENT/self.zoom_ratio
137 elif event.keyval == gtk.keysyms.Down:
138 self.y += self.POS_INCREMENT/self.zoom_ratio
139 else:
140 return False
141 self.queue_draw()
142 self.position_changed()
143 return True
144
145 def on_area_button_press(self, area, event):
146 if event.button == 2 or event.button == 1:
147 area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
148 self.prevmousex = event.x
149 self.prevmousey = event.y
150 if event.type not in (gtk.gdk.BUTTON_PRESS, gtk.gdk.BUTTON_RELEASE):
151 return False
152 return False
153
154 def on_area_button_release(self, area, event):
155 if event.button == 2 or event.button == 1:
156 area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
157 self.prevmousex = None
158 self.prevmousey = None
159 return True
160 return False
161
162 def on_area_scroll_event(self, area, event):
163 if event.state & gtk.gdk.CONTROL_MASK:
164 if event.direction == gtk.gdk.SCROLL_UP:
165 self.zoom_image(self.zoom_ratio * self.ZOOM_INCREMENT)
166 return True
167 if event.direction == gtk.gdk.SCROLL_DOWN:
168 self.zoom_image(self.zoom_ratio / self.ZOOM_INCREMENT)
169 return True
170 return False
171
172 def on_area_motion_notify(self, area, event):
173 state = event.state
174 if state & gtk.gdk.BUTTON2_MASK or state & gtk.gdk.BUTTON1_MASK:
175 x, y = int(event.x), int(event.y)
176 # pan the image
177 self.x += (self.prevmousex - x)/self.zoom_ratio
178 self.y += (self.prevmousey - y)/self.zoom_ratio
179 self.queue_draw()
180 self.prevmousex = x
181 self.prevmousey = y
182 self.position_changed()
183 return True
184
185 def on_set_scroll_adjustments(self, area, hadj, vadj):
186 self._set_scroll_adjustments (hadj, vadj)
187
188 def on_allocation_size_changed(self, widget, allocation):
189 self.hadj.page_size = allocation.width
190 self.hadj.page_increment = allocation.width * 0.9
191 self.vadj.page_size = allocation.height
192 self.vadj.page_increment = allocation.height * 0.9
193
194 def _set_adj_upper(self, adj, upper):
195 changed = False
196 value_changed = False
197
198 if adj.upper != upper:
199 adj.upper = upper
200 changed = True
201
202 max_value = max(0.0, upper - adj.page_size)
203 if adj.value > max_value:
204 adj.value = max_value
205 value_changed = True
206
207 if changed:
208 adj.changed()
209 if value_changed:
210 adj.value_changed()
211
212 def _set_scroll_adjustments(self, hadj, vadj):
213 if hadj == None:
214 hadj = gtk.Adjustment(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
215 if vadj == None:
216 vadj = gtk.Adjustment(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
217
218 if self.hadj_changed_signal_id != None and \
219 self.hadj != None and hadj != self.hadj:
220 self.hadj.disconnect (self.hadj_changed_signal_id)
221 if self.vadj_changed_signal_id != None and \
222 self.vadj != None and vadj != self.vadj:
223 self.vadj.disconnect (self.vadj_changed_signal_id)
224
225 if hadj != None:
226 self.hadj = hadj
227 self._set_adj_upper (self.hadj, self.zoom_ratio * self.chart_width)
228 self.hadj_changed_signal_id = self.hadj.connect('value-changed', self.on_adjustments_changed)
229
230 if vadj != None:
231 self.vadj = vadj
232 self._set_adj_upper (self.vadj, self.zoom_ratio * self.chart_height)
233 self.vadj_changed_signal_id = self.vadj.connect('value-changed', self.on_adjustments_changed)
234
235 def on_adjustments_changed(self, adj):
236 self.x = self.hadj.value / self.zoom_ratio
237 self.y = self.vadj.value / self.zoom_ratio
238 self.queue_draw()
239
240 def on_position_changed(self, widget, x, y):
241 self.hadj.value = x * self.zoom_ratio
242 self.vadj.value = y * self.zoom_ratio
243
244PyBootchartWidget.set_set_scroll_adjustments_signal('set-scroll-adjustments')
245
246class PyBootchartShell(gtk.VBox):
247 ui = '''
248 <ui>
249 <toolbar name="ToolBar">
250 <toolitem action="Expand"/>
251 <toolitem action="Contract"/>
252 <separator/>
253 <toolitem action="ZoomIn"/>
254 <toolitem action="ZoomOut"/>
255 <toolitem action="ZoomFit"/>
256 <toolitem action="Zoom100"/>
257 </toolbar>
258 </ui>
259 '''
260 def __init__(self, window, trace, options, xscale):
261 gtk.VBox.__init__(self)
262
263 self.widget = PyBootchartWidget(trace, options, xscale)
264
265 # Create a UIManager instance
266 uimanager = self.uimanager = gtk.UIManager()
267
268 # Add the accelerator group to the toplevel window
269 accelgroup = uimanager.get_accel_group()
270 window.add_accel_group(accelgroup)
271
272 # Create an ActionGroup
273 actiongroup = gtk.ActionGroup('Actions')
274 self.actiongroup = actiongroup
275
276 # Create actions
277 actiongroup.add_actions((
278 ('Expand', gtk.STOCK_ADD, None, None, None, self.widget.on_expand),
279 ('Contract', gtk.STOCK_REMOVE, None, None, None, self.widget.on_contract),
280 ('ZoomIn', gtk.STOCK_ZOOM_IN, None, None, None, self.widget.on_zoom_in),
281 ('ZoomOut', gtk.STOCK_ZOOM_OUT, None, None, None, self.widget.on_zoom_out),
282 ('ZoomFit', gtk.STOCK_ZOOM_FIT, 'Fit Width', None, None, self.widget.on_zoom_fit),
283 ('Zoom100', gtk.STOCK_ZOOM_100, None, None, None, self.widget.on_zoom_100),
284 ))
285
286 # Add the actiongroup to the uimanager
287 uimanager.insert_action_group(actiongroup, 0)
288
289 # Add a UI description
290 uimanager.add_ui_from_string(self.ui)
291
292 # Scrolled window
293 scrolled = gtk.ScrolledWindow()
294 scrolled.add(self.widget)
295
296 # toolbar / h-box
297 hbox = gtk.HBox(False, 8)
298
299 # Create a Toolbar
300 toolbar = uimanager.get_widget('/ToolBar')
301 hbox.pack_start(toolbar, True, True)
302
303 if not options.kernel_only:
304 # Misc. options
305 button = gtk.CheckButton("Show more")
306 button.connect ('toggled', self.widget.show_toggled)
307 button.set_active(options.app_options.show_all)
308 hbox.pack_start (button, False, True)
309
310 self.pack_start(hbox, False)
311 self.pack_start(scrolled)
312 self.show_all()
313
314 def grab_focus(self, window):
315 window.set_focus(self.widget)
316
317
318class PyBootchartWindow(gtk.Window):
319
320 def __init__(self, trace, app_options):
321 gtk.Window.__init__(self)
322
323 window = self
324 window.set_title("Bootchart %s" % trace.filename)
325 window.set_default_size(750, 550)
326
327 tab_page = gtk.Notebook()
328 tab_page.show()
329 window.add(tab_page)
330
331 full_opts = RenderOptions(app_options)
332 full_tree = PyBootchartShell(window, trace, full_opts, 1.0)
333 tab_page.append_page (full_tree, gtk.Label("Full tree"))
334
335 if trace.kernel is not None and len (trace.kernel) > 2:
336 kernel_opts = RenderOptions(app_options)
337 kernel_opts.cumulative = False
338 kernel_opts.charts = False
339 kernel_opts.kernel_only = True
340 kernel_tree = PyBootchartShell(window, trace, kernel_opts, 5.0)
341 tab_page.append_page (kernel_tree, gtk.Label("Kernel boot"))
342
343 full_tree.grab_focus(self)
344 self.show()
345
346
347def show(trace, options):
348 win = PyBootchartWindow(trace, options)
349 win.connect('destroy', gtk.main_quit)
350 gtk.main()
diff --git a/scripts/pybootchartgui/pybootchartgui/main.py b/scripts/pybootchartgui/pybootchartgui/main.py
new file mode 120000
index 0000000000..b45ae0a3d2
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/main.py
@@ -0,0 +1 @@
main.py.in \ No newline at end of file
diff --git a/scripts/pybootchartgui/pybootchartgui/main.py.in b/scripts/pybootchartgui/pybootchartgui/main.py.in
new file mode 100644
index 0000000000..21bb0be3a7
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/main.py.in
@@ -0,0 +1,187 @@
1#
2# ***********************************************************************
3# Warning: This file is auto-generated from main.py.in - edit it there.
4# ***********************************************************************
5#
6# pybootchartgui is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# pybootchartgui is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
18
19from __future__ import print_function
20
21import sys
22import os
23import optparse
24
25from . import parsing
26from . import batch
27
28def _mk_options_parser():
29 """Make an options parser."""
30 usage = "%prog [options] /path/to/tmp/buildstats/<recipe-machine>/<BUILDNAME>/"
31 version = "%prog v1.0.0"
32 parser = optparse.OptionParser(usage, version=version)
33 parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False,
34 help="start in active mode")
35 parser.add_option("-f", "--format", dest="format", default="png", choices=["png", "svg", "pdf"],
36 help="image format (png, svg, pdf); default format png")
37 parser.add_option("-o", "--output", dest="output", metavar="PATH", default=None,
38 help="output path (file or directory) where charts are stored")
39 parser.add_option("-s", "--split", dest="num", type=int, default=1,
40 help="split the output chart into <NUM> charts, only works with \"-o PATH\"")
41 parser.add_option("-m", "--mintime", dest="mintime", type=int, default=8,
42 help="only tasks longer than this time will be displayed")
43 parser.add_option("-M", "--minutes", action="store_true", dest="as_minutes", default=False,
44 help="display time in minutes instead of seconds")
45# parser.add_option("-n", "--no-prune", action="store_false", dest="prune", default=True,
46# help="do not prune the process tree")
47 parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False,
48 help="suppress informational messages")
49# parser.add_option("-t", "--boot-time", action="store_true", dest="boottime", default=False,
50# help="only display the boot time of the boot in text format (stdout)")
51 parser.add_option("--very-quiet", action="store_true", dest="veryquiet", default=False,
52 help="suppress all messages except errors")
53 parser.add_option("--verbose", action="store_true", dest="verbose", default=False,
54 help="print all messages")
55# parser.add_option("--profile", action="store_true", dest="profile", default=False,
56# help="profile rendering of chart (only useful when in batch mode indicated by -f)")
57# parser.add_option("--show-pid", action="store_true", dest="show_pid", default=False,
58# help="show process ids in the bootchart as 'processname [pid]'")
59 parser.add_option("--show-all", action="store_true", dest="show_all", default=False,
60 help="show all processes in the chart")
61# parser.add_option("--crop-after", dest="crop_after", metavar="PROCESS", default=None,
62# help="crop chart when idle after PROCESS is started")
63# parser.add_option("--annotate", action="append", dest="annotate", metavar="PROCESS", default=None,
64# help="annotate position where PROCESS is started; can be specified multiple times. " +
65# "To create a single annotation when any one of a set of processes is started, use commas to separate the names")
66# parser.add_option("--annotate-file", dest="annotate_file", metavar="FILENAME", default=None,
67# help="filename to write annotation points to")
68 parser.add_option("-T", "--full-time", action="store_true", dest="full_time", default=False,
69 help="display the full time regardless of which processes are currently shown")
70 return parser
71
72class Writer:
73 def __init__(self, write, options):
74 self.write = write
75 self.options = options
76
77 def error(self, msg):
78 self.write(msg)
79
80 def warn(self, msg):
81 if not self.options.quiet:
82 self.write(msg)
83
84 def info(self, msg):
85 if self.options.verbose:
86 self.write(msg)
87
88 def status(self, msg):
89 if not self.options.quiet:
90 self.write(msg)
91
92def _mk_writer(options):
93 def write(s):
94 print(s)
95 return Writer(write, options)
96
97def _get_filename(path):
98 """Construct a usable filename for outputs"""
99 dname = "."
100 fname = "bootchart"
101 if path != None:
102 if os.path.isdir(path):
103 dname = path
104 else:
105 fname = path
106 return os.path.join(dname, fname)
107
108def main(argv=None):
109 try:
110 if argv is None:
111 argv = sys.argv[1:]
112
113 parser = _mk_options_parser()
114 options, args = parser.parse_args(argv)
115
116 # Default values for disabled options
117 options.prune = True
118 options.boottime = False
119 options.profile = False
120 options.show_pid = False
121 options.crop_after = None
122 options.annotate = None
123 options.annotate_file = None
124
125 writer = _mk_writer(options)
126
127 if len(args) == 0:
128 print("No path given, trying /var/log/bootchart.tgz")
129 args = [ "/var/log/bootchart.tgz" ]
130
131 res = parsing.Trace(writer, args, options)
132
133 if options.interactive or options.output == None:
134 from . import gui
135 gui.show(res, options)
136 elif options.boottime:
137 import math
138 proc_tree = res.proc_tree
139 if proc_tree.idle:
140 duration = proc_tree.idle
141 else:
142 duration = proc_tree.duration
143 dur = duration / 100.0
144 print('%02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60)))
145 else:
146 if options.annotate_file:
147 f = open (options.annotate_file, "w")
148 try:
149 for time in res[4]:
150 if time is not None:
151 # output as ms
152 print(time * 10, file=f)
153 else:
154 print(file=f)
155 finally:
156 f.close()
157 filename = _get_filename(options.output)
158 res_list = parsing.split_res(res, options)
159 n = 1
160 width = len(str(len(res_list)))
161 s = "_%%0%dd." % width
162 for r in res_list:
163 if len(res_list) == 1:
164 f = filename + "." + options.format
165 else:
166 f = filename + s % n + options.format
167 n = n + 1
168 def render():
169 batch.render(writer, r, options, f)
170 if options.profile:
171 import cProfile
172 import pstats
173 profile = '%s.prof' % os.path.splitext(filename)[0]
174 cProfile.runctx('render()', globals(), locals(), profile)
175 p = pstats.Stats(profile)
176 p.strip_dirs().sort_stats('time').print_stats(20)
177 else:
178 render()
179
180 return 0
181 except parsing.ParseError as ex:
182 print(("Parse error: %s" % ex))
183 return 2
184
185
186if __name__ == '__main__':
187 sys.exit(main())
diff --git a/scripts/pybootchartgui/pybootchartgui/parsing.py b/scripts/pybootchartgui/pybootchartgui/parsing.py
new file mode 100644
index 0000000000..d423b9f77c
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/parsing.py
@@ -0,0 +1,740 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16
17from __future__ import with_statement
18
19import os
20import string
21import re
22import sys
23import tarfile
24from time import clock
25from collections import defaultdict
26from functools import reduce
27
28from .samples import *
29from .process_tree import ProcessTree
30
31if sys.version_info >= (3, 0):
32 long = int
33
34# Parsing produces as its end result a 'Trace'
35
36class Trace:
37 def __init__(self, writer, paths, options):
38 self.processes = {}
39 self.start = {}
40 self.end = {}
41 self.min = None
42 self.max = None
43 self.headers = None
44 self.disk_stats = None
45 self.ps_stats = None
46 self.taskstats = None
47 self.cpu_stats = None
48 self.cmdline = None
49 self.kernel = None
50 self.kernel_tree = None
51 self.filename = None
52 self.parent_map = None
53 self.mem_stats = None
54
55 if len(paths):
56 parse_paths (writer, self, paths)
57 if not self.valid():
58 raise ParseError("empty state: '%s' does not contain a valid bootchart" % ", ".join(paths))
59
60 if options.full_time:
61 self.min = min(self.start.keys())
62 self.max = max(self.end.keys())
63
64 return
65
66 # Turn that parsed information into something more useful
67 # link processes into a tree of pointers, calculate statistics
68 self.compile(writer)
69
70 # Crop the chart to the end of the first idle period after the given
71 # process
72 if options.crop_after:
73 idle = self.crop (writer, options.crop_after)
74 else:
75 idle = None
76
77 # Annotate other times as the first start point of given process lists
78 self.times = [ idle ]
79 if options.annotate:
80 for procnames in options.annotate:
81 names = [x[:15] for x in procnames.split(",")]
82 for proc in self.ps_stats.process_map.values():
83 if proc.cmd in names:
84 self.times.append(proc.start_time)
85 break
86 else:
87 self.times.append(None)
88
89 self.proc_tree = ProcessTree(writer, self.kernel, self.ps_stats,
90 self.ps_stats.sample_period,
91 self.headers.get("profile.process"),
92 options.prune, idle, self.taskstats,
93 self.parent_map is not None)
94
95 if self.kernel is not None:
96 self.kernel_tree = ProcessTree(writer, self.kernel, None, 0,
97 self.headers.get("profile.process"),
98 False, None, None, True)
99
100 def valid(self):
101 return len(self.processes) != 0
102 return self.headers != None and self.disk_stats != None and \
103 self.ps_stats != None and self.cpu_stats != None
104
105 def add_process(self, process, start, end):
106 self.processes[process] = [start, end]
107 if start not in self.start:
108 self.start[start] = []
109 if process not in self.start[start]:
110 self.start[start].append(process)
111 if end not in self.end:
112 self.end[end] = []
113 if process not in self.end[end]:
114 self.end[end].append(process)
115
116 def compile(self, writer):
117
118 def find_parent_id_for(pid):
119 if pid is 0:
120 return 0
121 ppid = self.parent_map.get(pid)
122 if ppid:
123 # many of these double forks are so short lived
124 # that we have no samples, or process info for them
125 # so climb the parent hierarcy to find one
126 if int (ppid * 1000) not in self.ps_stats.process_map:
127# print "Pid '%d' short lived with no process" % ppid
128 ppid = find_parent_id_for (ppid)
129# else:
130# print "Pid '%d' has an entry" % ppid
131 else:
132# print "Pid '%d' missing from pid map" % pid
133 return 0
134 return ppid
135
136 # merge in the cmdline data
137 if self.cmdline is not None:
138 for proc in self.ps_stats.process_map.values():
139 rpid = int (proc.pid // 1000)
140 if rpid in self.cmdline:
141 cmd = self.cmdline[rpid]
142 proc.exe = cmd['exe']
143 proc.args = cmd['args']
144# else:
145# print "proc %d '%s' not in cmdline" % (rpid, proc.exe)
146
147 # re-parent any stray orphans if we can
148 if self.parent_map is not None:
149 for process in self.ps_stats.process_map.values():
150 ppid = find_parent_id_for (int(process.pid // 1000))
151 if ppid:
152 process.ppid = ppid * 1000
153
154 # stitch the tree together with pointers
155 for process in self.ps_stats.process_map.values():
156 process.set_parent (self.ps_stats.process_map)
157
158 # count on fingers variously
159 for process in self.ps_stats.process_map.values():
160 process.calc_stats (self.ps_stats.sample_period)
161
162 def crop(self, writer, crop_after):
163
164 def is_idle_at(util, start, j):
165 k = j + 1
166 while k < len(util) and util[k][0] < start + 300:
167 k += 1
168 k = min(k, len(util)-1)
169
170 if util[j][1] >= 0.25:
171 return False
172
173 avgload = sum(u[1] for u in util[j:k+1]) / (k-j+1)
174 if avgload < 0.25:
175 return True
176 else:
177 return False
178 def is_idle(util, start):
179 for j in range(0, len(util)):
180 if util[j][0] < start:
181 continue
182 return is_idle_at(util, start, j)
183 else:
184 return False
185
186 names = [x[:15] for x in crop_after.split(",")]
187 for proc in self.ps_stats.process_map.values():
188 if proc.cmd in names or proc.exe in names:
189 writer.info("selected proc '%s' from list (start %d)"
190 % (proc.cmd, proc.start_time))
191 break
192 if proc is None:
193 writer.warn("no selected crop proc '%s' in list" % crop_after)
194
195
196 cpu_util = [(sample.time, sample.user + sample.sys + sample.io) for sample in self.cpu_stats]
197 disk_util = [(sample.time, sample.util) for sample in self.disk_stats]
198
199 idle = None
200 for i in range(0, len(cpu_util)):
201 if cpu_util[i][0] < proc.start_time:
202 continue
203 if is_idle_at(cpu_util, cpu_util[i][0], i) \
204 and is_idle(disk_util, cpu_util[i][0]):
205 idle = cpu_util[i][0]
206 break
207
208 if idle is None:
209 writer.warn ("not idle after proc '%s'" % crop_after)
210 return None
211
212 crop_at = idle + 300
213 writer.info ("cropping at time %d" % crop_at)
214 while len (self.cpu_stats) \
215 and self.cpu_stats[-1].time > crop_at:
216 self.cpu_stats.pop()
217 while len (self.disk_stats) \
218 and self.disk_stats[-1].time > crop_at:
219 self.disk_stats.pop()
220
221 self.ps_stats.end_time = crop_at
222
223 cropped_map = {}
224 for key, value in self.ps_stats.process_map.items():
225 if (value.start_time <= crop_at):
226 cropped_map[key] = value
227
228 for proc in cropped_map.values():
229 proc.duration = min (proc.duration, crop_at - proc.start_time)
230 while len (proc.samples) \
231 and proc.samples[-1].time > crop_at:
232 proc.samples.pop()
233
234 self.ps_stats.process_map = cropped_map
235
236 return idle
237
238
239
240class ParseError(Exception):
241 """Represents errors during parse of the bootchart."""
242 def __init__(self, value):
243 self.value = value
244
245 def __str__(self):
246 return self.value
247
248def _parse_headers(file):
249 """Parses the headers of the bootchart."""
250 def parse(acc, line):
251 (headers, last) = acc
252 if '=' in line:
253 last, value = map (lambda x: x.strip(), line.split('=', 1))
254 else:
255 value = line.strip()
256 headers[last] += value
257 return headers, last
258 return reduce(parse, file.read().decode('utf-8').split('\n'), (defaultdict(str),''))[0]
259
260def _parse_timed_blocks(file):
261 """Parses (ie., splits) a file into so-called timed-blocks. A
262 timed-block consists of a timestamp on a line by itself followed
263 by zero or more lines of data for that point in time."""
264 def parse(block):
265 lines = block.split('\n')
266 if not lines:
267 raise ParseError('expected a timed-block consisting a timestamp followed by data lines')
268 try:
269 return (int(lines[0]), lines[1:])
270 except ValueError:
271 raise ParseError("expected a timed-block, but timestamp '%s' is not an integer" % lines[0])
272 blocks = file.read().decode('utf-8').split('\n\n')
273 return [parse(block) for block in blocks if block.strip() and not block.endswith(' not running\n')]
274
275def _parse_proc_ps_log(writer, file):
276 """
277 * See proc(5) for details.
278 *
279 * {pid, comm, state, ppid, pgrp, session, tty_nr, tpgid, flags, minflt, cminflt, majflt, cmajflt, utime, stime,
280 * cutime, cstime, priority, nice, 0, itrealvalue, starttime, vsize, rss, rlim, startcode, endcode, startstack,
281 * kstkesp, kstkeip}
282 """
283 processMap = {}
284 ltime = 0
285 timed_blocks = _parse_timed_blocks(file)
286 for time, lines in timed_blocks:
287 for line in lines:
288 if not line: continue
289 tokens = line.split(' ')
290 if len(tokens) < 21:
291 continue
292
293 offset = [index for index, token in enumerate(tokens[1:]) if token[-1] == ')'][0]
294 pid, cmd, state, ppid = int(tokens[0]), ' '.join(tokens[1:2+offset]), tokens[2+offset], int(tokens[3+offset])
295 userCpu, sysCpu, stime = int(tokens[13+offset]), int(tokens[14+offset]), int(tokens[21+offset])
296
297 # magic fixed point-ness ...
298 pid *= 1000
299 ppid *= 1000
300 if pid in processMap:
301 process = processMap[pid]
302 process.cmd = cmd.strip('()') # why rename after latest name??
303 else:
304 process = Process(writer, pid, cmd.strip('()'), ppid, min(time, stime))
305 processMap[pid] = process
306
307 if process.last_user_cpu_time is not None and process.last_sys_cpu_time is not None and ltime is not None:
308 userCpuLoad, sysCpuLoad = process.calc_load(userCpu, sysCpu, max(1, time - ltime))
309 cpuSample = CPUSample('null', userCpuLoad, sysCpuLoad, 0.0)
310 process.samples.append(ProcessSample(time, state, cpuSample))
311
312 process.last_user_cpu_time = userCpu
313 process.last_sys_cpu_time = sysCpu
314 ltime = time
315
316 if len (timed_blocks) < 2:
317 return None
318
319 startTime = timed_blocks[0][0]
320 avgSampleLength = (ltime - startTime)/(len (timed_blocks) - 1)
321
322 return ProcessStats (writer, processMap, len (timed_blocks), avgSampleLength, startTime, ltime)
323
324def _parse_taskstats_log(writer, file):
325 """
326 * See bootchart-collector.c for details.
327 *
328 * { pid, ppid, comm, cpu_run_real_total, blkio_delay_total, swapin_delay_total }
329 *
330 """
331 processMap = {}
332 pidRewrites = {}
333 ltime = None
334 timed_blocks = _parse_timed_blocks(file)
335 for time, lines in timed_blocks:
336 # we have no 'stime' from taskstats, so prep 'init'
337 if ltime is None:
338 process = Process(writer, 1, '[init]', 0, 0)
339 processMap[1000] = process
340 ltime = time
341# continue
342 for line in lines:
343 if not line: continue
344 tokens = line.split(' ')
345 if len(tokens) != 6:
346 continue
347
348 opid, ppid, cmd = int(tokens[0]), int(tokens[1]), tokens[2]
349 cpu_ns, blkio_delay_ns, swapin_delay_ns = long(tokens[-3]), long(tokens[-2]), long(tokens[-1]),
350
351 # make space for trees of pids
352 opid *= 1000
353 ppid *= 1000
354
355 # when the process name changes, we re-write the pid.
356 if opid in pidRewrites:
357 pid = pidRewrites[opid]
358 else:
359 pid = opid
360
361 cmd = cmd.strip('(').strip(')')
362 if pid in processMap:
363 process = processMap[pid]
364 if process.cmd != cmd:
365 pid += 1
366 pidRewrites[opid] = pid
367# print "process mutation ! '%s' vs '%s' pid %s -> pid %s\n" % (process.cmd, cmd, opid, pid)
368 process = process.split (writer, pid, cmd, ppid, time)
369 processMap[pid] = process
370 else:
371 process.cmd = cmd;
372 else:
373 process = Process(writer, pid, cmd, ppid, time)
374 processMap[pid] = process
375
376 delta_cpu_ns = (float) (cpu_ns - process.last_cpu_ns)
377 delta_blkio_delay_ns = (float) (blkio_delay_ns - process.last_blkio_delay_ns)
378 delta_swapin_delay_ns = (float) (swapin_delay_ns - process.last_swapin_delay_ns)
379
380 # make up some state data ...
381 if delta_cpu_ns > 0:
382 state = "R"
383 elif delta_blkio_delay_ns + delta_swapin_delay_ns > 0:
384 state = "D"
385 else:
386 state = "S"
387
388 # retain the ns timing information into a CPUSample - that tries
389 # with the old-style to be a %age of CPU used in this time-slice.
390 if delta_cpu_ns + delta_blkio_delay_ns + delta_swapin_delay_ns > 0:
391# print "proc %s cpu_ns %g delta_cpu %g" % (cmd, cpu_ns, delta_cpu_ns)
392 cpuSample = CPUSample('null', delta_cpu_ns, 0.0,
393 delta_blkio_delay_ns,
394 delta_swapin_delay_ns)
395 process.samples.append(ProcessSample(time, state, cpuSample))
396
397 process.last_cpu_ns = cpu_ns
398 process.last_blkio_delay_ns = blkio_delay_ns
399 process.last_swapin_delay_ns = swapin_delay_ns
400 ltime = time
401
402 if len (timed_blocks) < 2:
403 return None
404
405 startTime = timed_blocks[0][0]
406 avgSampleLength = (ltime - startTime)/(len(timed_blocks)-1)
407
408 return ProcessStats (writer, processMap, len (timed_blocks), avgSampleLength, startTime, ltime)
409
410def _parse_proc_stat_log(file):
411 samples = []
412 ltimes = None
413 for time, lines in _parse_timed_blocks(file):
414 # skip emtpy lines
415 if not lines:
416 continue
417 # CPU times {user, nice, system, idle, io_wait, irq, softirq}
418 tokens = lines[0].split()
419 times = [ int(token) for token in tokens[1:] ]
420 if ltimes:
421 user = float((times[0] + times[1]) - (ltimes[0] + ltimes[1]))
422 system = float((times[2] + times[5] + times[6]) - (ltimes[2] + ltimes[5] + ltimes[6]))
423 idle = float(times[3] - ltimes[3])
424 iowait = float(times[4] - ltimes[4])
425
426 aSum = max(user + system + idle + iowait, 1)
427 samples.append( CPUSample(time, user/aSum, system/aSum, iowait/aSum) )
428
429 ltimes = times
430 # skip the rest of statistics lines
431 return samples
432
433def _parse_proc_disk_stat_log(file, numCpu):
434 """
435 Parse file for disk stats, but only look at the whole device, eg. sda,
436 not sda1, sda2 etc. The format of relevant lines should be:
437 {major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq}
438 """
439 disk_regex_re = re.compile ('^([hsv]d.|mtdblock\d|mmcblk\d|cciss/c\d+d\d+.*)$')
440
441 # this gets called an awful lot.
442 def is_relevant_line(linetokens):
443 if len(linetokens) != 14:
444 return False
445 disk = linetokens[2]
446 return disk_regex_re.match(disk)
447
448 disk_stat_samples = []
449
450 for time, lines in _parse_timed_blocks(file):
451 sample = DiskStatSample(time)
452 relevant_tokens = [linetokens for linetokens in map (lambda x: x.split(),lines) if is_relevant_line(linetokens)]
453
454 for tokens in relevant_tokens:
455 disk, rsect, wsect, use = tokens[2], int(tokens[5]), int(tokens[9]), int(tokens[12])
456 sample.add_diskdata([rsect, wsect, use])
457
458 disk_stat_samples.append(sample)
459
460 disk_stats = []
461 for sample1, sample2 in zip(disk_stat_samples[:-1], disk_stat_samples[1:]):
462 interval = sample1.time - sample2.time
463 if interval == 0:
464 interval = 1
465 sums = [ a - b for a, b in zip(sample1.diskdata, sample2.diskdata) ]
466 readTput = sums[0] / 2.0 * 100.0 / interval
467 writeTput = sums[1] / 2.0 * 100.0 / interval
468 util = float( sums[2] ) / 10 / interval / numCpu
469 util = max(0.0, min(1.0, util))
470 disk_stats.append(DiskSample(sample2.time, readTput, writeTput, util))
471
472 return disk_stats
473
474def _parse_proc_meminfo_log(file):
475 """
476 Parse file for global memory statistics.
477 The format of relevant lines should be: ^key: value( unit)?
478 """
479 used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)
480
481 mem_stats = []
482 meminfo_re = re.compile(r'([^ \t:]+):\s*(\d+).*')
483
484 for time, lines in _parse_timed_blocks(file):
485 sample = MemSample(time)
486
487 for line in lines:
488 match = meminfo_re.match(line)
489 if not match:
490 raise ParseError("Invalid meminfo line \"%s\"" % match.groups(0))
491 sample.add_value(match.group(1), int(match.group(2)))
492
493 if sample.valid():
494 mem_stats.append(sample)
495
496 return mem_stats
497
498# if we boot the kernel with: initcall_debug printk.time=1 we can
499# get all manner of interesting data from the dmesg output
500# We turn this into a pseudo-process tree: each event is
501# characterised by a
502# we don't try to detect a "kernel finished" state - since the kernel
503# continues to do interesting things after init is called.
504#
505# sample input:
506# [ 0.000000] ACPI: FACP 3f4fc000 000F4 (v04 INTEL Napa 00000001 MSFT 01000013)
507# ...
508# [ 0.039993] calling migration_init+0x0/0x6b @ 1
509# [ 0.039993] initcall migration_init+0x0/0x6b returned 1 after 0 usecs
510def _parse_dmesg(writer, file):
511 timestamp_re = re.compile ("^\[\s*(\d+\.\d+)\s*]\s+(.*)$")
512 split_re = re.compile ("^(\S+)\s+([\S\+_-]+) (.*)$")
513 processMap = {}
514 idx = 0
515 inc = 1.0 / 1000000
516 kernel = Process(writer, idx, "k-boot", 0, 0.1)
517 processMap['k-boot'] = kernel
518 base_ts = False
519 max_ts = 0
520 for line in file.read().decode('utf-8').split('\n'):
521 t = timestamp_re.match (line)
522 if t is None:
523# print "duff timestamp " + line
524 continue
525
526 time_ms = float (t.group(1)) * 1000
527 # looks like we may have a huge diff after the clock
528 # has been set up. This could lead to huge graph:
529 # so huge we will be killed by the OOM.
530 # So instead of using the plain timestamp we will
531 # use a delta to first one and skip the first one
532 # for convenience
533 if max_ts == 0 and not base_ts and time_ms > 1000:
534 base_ts = time_ms
535 continue
536 max_ts = max(time_ms, max_ts)
537 if base_ts:
538# print "fscked clock: used %f instead of %f" % (time_ms - base_ts, time_ms)
539 time_ms -= base_ts
540 m = split_re.match (t.group(2))
541
542 if m is None:
543 continue
544# print "match: '%s'" % (m.group(1))
545 type = m.group(1)
546 func = m.group(2)
547 rest = m.group(3)
548
549 if t.group(2).startswith ('Write protecting the') or \
550 t.group(2).startswith ('Freeing unused kernel memory'):
551 kernel.duration = time_ms / 10
552 continue
553
554# print "foo: '%s' '%s' '%s'" % (type, func, rest)
555 if type == "calling":
556 ppid = kernel.pid
557 p = re.match ("\@ (\d+)", rest)
558 if p is not None:
559 ppid = float (p.group(1)) // 1000
560# print "match: '%s' ('%g') at '%s'" % (func, ppid, time_ms)
561 name = func.split ('+', 1) [0]
562 idx += inc
563 processMap[func] = Process(writer, ppid + idx, name, ppid, time_ms / 10)
564 elif type == "initcall":
565# print "finished: '%s' at '%s'" % (func, time_ms)
566 if func in processMap:
567 process = processMap[func]
568 process.duration = (time_ms / 10) - process.start_time
569 else:
570 print("corrupted init call for %s" % (func))
571
572 elif type == "async_waiting" or type == "async_continuing":
573 continue # ignore
574
575 return processMap.values()
576
577#
578# Parse binary pacct accounting file output if we have one
579# cf. /usr/include/linux/acct.h
580#
581def _parse_pacct(writer, file):
582 # read LE int32
583 def _read_le_int32(file):
584 byts = file.read(4)
585 return (ord(byts[0])) | (ord(byts[1]) << 8) | \
586 (ord(byts[2]) << 16) | (ord(byts[3]) << 24)
587
588 parent_map = {}
589 parent_map[0] = 0
590 while file.read(1) != "": # ignore flags
591 ver = file.read(1)
592 if ord(ver) < 3:
593 print("Invalid version 0x%x" % (ord(ver)))
594 return None
595
596 file.seek (14, 1) # user, group etc.
597 pid = _read_le_int32 (file)
598 ppid = _read_le_int32 (file)
599# print "Parent of %d is %d" % (pid, ppid)
600 parent_map[pid] = ppid
601 file.seek (4 + 4 + 16, 1) # timings
602 file.seek (16, 1) # acct_comm
603 return parent_map
604
605def _parse_paternity_log(writer, file):
606 parent_map = {}
607 parent_map[0] = 0
608 for line in file.read().decode('utf-8').split('\n'):
609 if not line:
610 continue
611 elems = line.split(' ') # <Child> <Parent>
612 if len (elems) >= 2:
613# print "paternity of %d is %d" % (int(elems[0]), int(elems[1]))
614 parent_map[int(elems[0])] = int(elems[1])
615 else:
616 print("Odd paternity line '%s'" % (line))
617 return parent_map
618
619def _parse_cmdline_log(writer, file):
620 cmdLines = {}
621 for block in file.read().decode('utf-8').split('\n\n'):
622 lines = block.split('\n')
623 if len (lines) >= 3:
624# print "Lines '%s'" % (lines[0])
625 pid = int (lines[0])
626 values = {}
627 values['exe'] = lines[1].lstrip(':')
628 args = lines[2].lstrip(':').split('\0')
629 args.pop()
630 values['args'] = args
631 cmdLines[pid] = values
632 return cmdLines
633
634def get_num_cpus(headers):
635 """Get the number of CPUs from the system.cpu header property. As the
636 CPU utilization graphs are relative, the number of CPUs currently makes
637 no difference."""
638 if headers is None:
639 return 1
640 if headers.get("system.cpu.num"):
641 return max (int (headers.get("system.cpu.num")), 1)
642 cpu_model = headers.get("system.cpu")
643 if cpu_model is None:
644 return 1
645 mat = re.match(".*\\((\\d+)\\)", cpu_model)
646 if mat is None:
647 return 1
648 return max (int(mat.group(1)), 1)
649
650def _do_parse(writer, state, filename, file):
651 writer.info("parsing '%s'" % filename)
652 t1 = clock()
653 paths = filename.split("/")
654 task = paths[-1]
655 pn = paths[-2]
656 start = None
657 end = None
658 for line in file:
659 if line.startswith("Started:"):
660 start = int(float(line.split()[-1]))
661 elif line.startswith("Ended:"):
662 end = int(float(line.split()[-1]))
663 if start and end:
664 state.add_process(pn + ":" + task, start, end)
665 t2 = clock()
666 writer.info(" %s seconds" % str(t2-t1))
667 return state
668
669def parse_file(writer, state, filename):
670 if state.filename is None:
671 state.filename = filename
672 basename = os.path.basename(filename)
673 with open(filename, "rb") as file:
674 return _do_parse(writer, state, filename, file)
675
676def parse_paths(writer, state, paths):
677 for path in paths:
678 if state.filename is None:
679 state.filename = path
680 root, extension = os.path.splitext(path)
681 if not(os.path.exists(path)):
682 writer.warn("warning: path '%s' does not exist, ignoring." % path)
683 continue
684 #state.filename = path
685 if os.path.isdir(path):
686 files = sorted([os.path.join(path, f) for f in os.listdir(path)])
687 state = parse_paths(writer, state, files)
688 elif extension in [".tar", ".tgz", ".gz"]:
689 if extension == ".gz":
690 root, extension = os.path.splitext(root)
691 if extension != ".tar":
692 writer.warn("warning: can only handle zipped tar files, not zipped '%s'-files; ignoring" % extension)
693 continue
694 tf = None
695 try:
696 writer.status("parsing '%s'" % path)
697 tf = tarfile.open(path, 'r:*')
698 for name in tf.getnames():
699 state = _do_parse(writer, state, name, tf.extractfile(name))
700 except tarfile.ReadError as error:
701 raise ParseError("error: could not read tarfile '%s': %s." % (path, error))
702 finally:
703 if tf != None:
704 tf.close()
705 else:
706 state = parse_file(writer, state, path)
707 return state
708
709def split_res(res, options):
710 """ Split the res into n pieces """
711 res_list = []
712 if options.num > 1:
713 s_list = sorted(res.start.keys())
714 frag_size = len(s_list) / float(options.num)
715 # Need the top value
716 if frag_size > int(frag_size):
717 frag_size = int(frag_size + 1)
718 else:
719 frag_size = int(frag_size)
720
721 start = 0
722 end = frag_size
723 while start < end:
724 state = Trace(None, [], None)
725 if options.full_time:
726 state.min = min(res.start.keys())
727 state.max = max(res.end.keys())
728 for i in range(start, end):
729 # Add this line for reference
730 #state.add_process(pn + ":" + task, start, end)
731 for p in res.start[s_list[i]]:
732 state.add_process(p, s_list[i], res.processes[p][1])
733 start = end
734 end = end + frag_size
735 if end > len(s_list):
736 end = len(s_list)
737 res_list.append(state)
738 else:
739 res_list.append(res)
740 return res_list
diff --git a/scripts/pybootchartgui/pybootchartgui/process_tree.py b/scripts/pybootchartgui/pybootchartgui/process_tree.py
new file mode 100644
index 0000000000..cf88110b1c
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/process_tree.py
@@ -0,0 +1,292 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16class ProcessTree:
17 """ProcessTree encapsulates a process tree. The tree is built from log files
18 retrieved during the boot process. When building the process tree, it is
19 pruned and merged in order to be able to visualize it in a comprehensible
20 manner.
21
22 The following pruning techniques are used:
23
24 * idle processes that keep running during the last process sample
25 (which is a heuristic for a background processes) are removed,
26 * short-lived processes (i.e. processes that only live for the
27 duration of two samples or less) are removed,
28 * the processes used by the boot logger are removed,
29 * exploders (i.e. processes that are known to spawn huge meaningless
30 process subtrees) have their subtrees merged together,
31 * siblings (i.e. processes with the same command line living
32 concurrently -- thread heuristic) are merged together,
33 * process runs (unary trees with processes sharing the command line)
34 are merged together.
35
36 """
37 LOGGER_PROC = 'bootchart-colle'
38 EXPLODER_PROCESSES = set(['hwup'])
39
40 def __init__(self, writer, kernel, psstats, sample_period,
41 monitoredApp, prune, idle, taskstats,
42 accurate_parentage, for_testing = False):
43 self.writer = writer
44 self.process_tree = []
45 self.taskstats = taskstats
46 if psstats is None:
47 process_list = kernel
48 elif kernel is None:
49 process_list = psstats.process_map.values()
50 else:
51 process_list = list(kernel) + list(psstats.process_map.values())
52 self.process_list = sorted(process_list, key = lambda p: p.pid)
53 self.sample_period = sample_period
54
55 self.build()
56 if not accurate_parentage:
57 self.update_ppids_for_daemons(self.process_list)
58
59 self.start_time = self.get_start_time(self.process_tree)
60 self.end_time = self.get_end_time(self.process_tree)
61 self.duration = self.end_time - self.start_time
62 self.idle = idle
63
64 if for_testing:
65 return
66
67 removed = self.merge_logger(self.process_tree, self.LOGGER_PROC, monitoredApp, False)
68 writer.status("merged %i logger processes" % removed)
69
70 if prune:
71 p_processes = self.prune(self.process_tree, None)
72 p_exploders = self.merge_exploders(self.process_tree, self.EXPLODER_PROCESSES)
73 p_threads = self.merge_siblings(self.process_tree)
74 p_runs = self.merge_runs(self.process_tree)
75 writer.status("pruned %i process, %i exploders, %i threads, and %i runs" % (p_processes, p_exploders, p_threads, p_runs))
76
77 self.sort(self.process_tree)
78
79 self.start_time = self.get_start_time(self.process_tree)
80 self.end_time = self.get_end_time(self.process_tree)
81 self.duration = self.end_time - self.start_time
82
83 self.num_proc = self.num_nodes(self.process_tree)
84
85 def build(self):
86 """Build the process tree from the list of top samples."""
87 self.process_tree = []
88 for proc in self.process_list:
89 if not proc.parent:
90 self.process_tree.append(proc)
91 else:
92 proc.parent.child_list.append(proc)
93
94 def sort(self, process_subtree):
95 """Sort process tree."""
96 for p in process_subtree:
97 p.child_list.sort(key = lambda p: p.pid)
98 self.sort(p.child_list)
99
100 def num_nodes(self, process_list):
101 "Counts the number of nodes in the specified process tree."""
102 nodes = 0
103 for proc in process_list:
104 nodes = nodes + self.num_nodes(proc.child_list)
105 return nodes + len(process_list)
106
107 def get_start_time(self, process_subtree):
108 """Returns the start time of the process subtree. This is the start
109 time of the earliest process.
110
111 """
112 if not process_subtree:
113 return 100000000
114 return min( [min(proc.start_time, self.get_start_time(proc.child_list)) for proc in process_subtree] )
115
116 def get_end_time(self, process_subtree):
117 """Returns the end time of the process subtree. This is the end time
118 of the last collected sample.
119
120 """
121 if not process_subtree:
122 return -100000000
123 return max( [max(proc.start_time + proc.duration, self.get_end_time(proc.child_list)) for proc in process_subtree] )
124
125 def get_max_pid(self, process_subtree):
126 """Returns the max PID found in the process tree."""
127 if not process_subtree:
128 return -100000000
129 return max( [max(proc.pid, self.get_max_pid(proc.child_list)) for proc in process_subtree] )
130
131 def update_ppids_for_daemons(self, process_list):
132 """Fedora hack: when loading the system services from rc, runuser(1)
133 is used. This sets the PPID of all daemons to 1, skewing
134 the process tree. Try to detect this and set the PPID of
135 these processes the PID of rc.
136
137 """
138 rcstartpid = -1
139 rcendpid = -1
140 rcproc = None
141 for p in process_list:
142 if p.cmd == "rc" and p.ppid // 1000 == 1:
143 rcproc = p
144 rcstartpid = p.pid
145 rcendpid = self.get_max_pid(p.child_list)
146 if rcstartpid != -1 and rcendpid != -1:
147 for p in process_list:
148 if p.pid > rcstartpid and p.pid < rcendpid and p.ppid // 1000 == 1:
149 p.ppid = rcstartpid
150 p.parent = rcproc
151 for p in process_list:
152 p.child_list = []
153 self.build()
154
155 def prune(self, process_subtree, parent):
156 """Prunes the process tree by removing idle processes and processes
157 that only live for the duration of a single top sample. Sibling
158 processes with the same command line (i.e. threads) are merged
159 together. This filters out sleepy background processes, short-lived
160 processes and bootcharts' analysis tools.
161 """
162 def is_idle_background_process_without_children(p):
163 process_end = p.start_time + p.duration
164 return not p.active and \
165 process_end >= self.start_time + self.duration and \
166 p.start_time > self.start_time and \
167 p.duration > 0.9 * self.duration and \
168 self.num_nodes(p.child_list) == 0
169
170 num_removed = 0
171 idx = 0
172 while idx < len(process_subtree):
173 p = process_subtree[idx]
174 if parent != None or len(p.child_list) == 0:
175
176 prune = False
177 if is_idle_background_process_without_children(p):
178 prune = True
179 elif p.duration <= 2 * self.sample_period:
180 # short-lived process
181 prune = True
182
183 if prune:
184 process_subtree.pop(idx)
185 for c in p.child_list:
186 process_subtree.insert(idx, c)
187 num_removed += 1
188 continue
189 else:
190 num_removed += self.prune(p.child_list, p)
191 else:
192 num_removed += self.prune(p.child_list, p)
193 idx += 1
194
195 return num_removed
196
197 def merge_logger(self, process_subtree, logger_proc, monitored_app, app_tree):
198 """Merges the logger's process subtree. The logger will typically
199 spawn lots of sleep and cat processes, thus polluting the
200 process tree.
201
202 """
203 num_removed = 0
204 for p in process_subtree:
205 is_app_tree = app_tree
206 if logger_proc == p.cmd and not app_tree:
207 is_app_tree = True
208 num_removed += self.merge_logger(p.child_list, logger_proc, monitored_app, is_app_tree)
209 # don't remove the logger itself
210 continue
211
212 if app_tree and monitored_app != None and monitored_app == p.cmd:
213 is_app_tree = False
214
215 if is_app_tree:
216 for child in p.child_list:
217 self.merge_processes(p, child)
218 num_removed += 1
219 p.child_list = []
220 else:
221 num_removed += self.merge_logger(p.child_list, logger_proc, monitored_app, is_app_tree)
222 return num_removed
223
224 def merge_exploders(self, process_subtree, processes):
225 """Merges specific process subtrees (used for processes which usually
226 spawn huge meaningless process trees).
227
228 """
229 num_removed = 0
230 for p in process_subtree:
231 if processes in processes and len(p.child_list) > 0:
232 subtreemap = self.getProcessMap(p.child_list)
233 for child in subtreemap.values():
234 self.merge_processes(p, child)
235 num_removed += len(subtreemap)
236 p.child_list = []
237 p.cmd += " (+)"
238 else:
239 num_removed += self.merge_exploders(p.child_list, processes)
240 return num_removed
241
242 def merge_siblings(self, process_subtree):
243 """Merges thread processes. Sibling processes with the same command
244 line are merged together.
245
246 """
247 num_removed = 0
248 idx = 0
249 while idx < len(process_subtree)-1:
250 p = process_subtree[idx]
251 nextp = process_subtree[idx+1]
252 if nextp.cmd == p.cmd:
253 process_subtree.pop(idx+1)
254 idx -= 1
255 num_removed += 1
256 p.child_list.extend(nextp.child_list)
257 self.merge_processes(p, nextp)
258 num_removed += self.merge_siblings(p.child_list)
259 idx += 1
260 if len(process_subtree) > 0:
261 p = process_subtree[-1]
262 num_removed += self.merge_siblings(p.child_list)
263 return num_removed
264
265 def merge_runs(self, process_subtree):
266 """Merges process runs. Single child processes which share the same
267 command line with the parent are merged.
268
269 """
270 num_removed = 0
271 idx = 0
272 while idx < len(process_subtree):
273 p = process_subtree[idx]
274 if len(p.child_list) == 1 and p.child_list[0].cmd == p.cmd:
275 child = p.child_list[0]
276 p.child_list = list(child.child_list)
277 self.merge_processes(p, child)
278 num_removed += 1
279 continue
280 num_removed += self.merge_runs(p.child_list)
281 idx += 1
282 return num_removed
283
284 def merge_processes(self, p1, p2):
285 """Merges two process' samples."""
286 p1.samples.extend(p2.samples)
287 p1.samples.sort( key = lambda p: p.time )
288 p1time = p1.start_time
289 p2time = p2.start_time
290 p1.start_time = min(p1time, p2time)
291 pendtime = max(p1time + p1.duration, p2time + p2.duration)
292 p1.duration = pendtime - p1.start_time
diff --git a/scripts/pybootchartgui/pybootchartgui/samples.py b/scripts/pybootchartgui/pybootchartgui/samples.py
new file mode 100644
index 0000000000..015d743aa0
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/samples.py
@@ -0,0 +1,151 @@
1# This file is part of pybootchartgui.
2
3# pybootchartgui is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7
8# pybootchartgui is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12
13# You should have received a copy of the GNU General Public License
14# along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.
15
16
17class DiskStatSample:
18 def __init__(self, time):
19 self.time = time
20 self.diskdata = [0, 0, 0]
21 def add_diskdata(self, new_diskdata):
22 self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ]
23
24class CPUSample:
25 def __init__(self, time, user, sys, io = 0.0, swap = 0.0):
26 self.time = time
27 self.user = user
28 self.sys = sys
29 self.io = io
30 self.swap = swap
31
32 @property
33 def cpu(self):
34 return self.user + self.sys
35
36 def __str__(self):
37 return str(self.time) + "\t" + str(self.user) + "\t" + \
38 str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap)
39
40class MemSample:
41 used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)
42
43 def __init__(self, time):
44 self.time = time
45 self.records = {}
46
47 def add_value(self, name, value):
48 if name in MemSample.used_values:
49 self.records[name] = value
50
51 def valid(self):
52 keys = self.records.keys()
53 # discard incomplete samples
54 return [v for v in MemSample.used_values if v not in keys] == []
55
56class ProcessSample:
57 def __init__(self, time, state, cpu_sample):
58 self.time = time
59 self.state = state
60 self.cpu_sample = cpu_sample
61
62 def __str__(self):
63 return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample)
64
65class ProcessStats:
66 def __init__(self, writer, process_map, sample_count, sample_period, start_time, end_time):
67 self.process_map = process_map
68 self.sample_count = sample_count
69 self.sample_period = sample_period
70 self.start_time = start_time
71 self.end_time = end_time
72 writer.info ("%d samples, avg. sample length %f" % (self.sample_count, self.sample_period))
73 writer.info ("process list size: %d" % len (self.process_map.values()))
74
75class Process:
76 def __init__(self, writer, pid, cmd, ppid, start_time):
77 self.writer = writer
78 self.pid = pid
79 self.cmd = cmd
80 self.exe = cmd
81 self.args = []
82 self.ppid = ppid
83 self.start_time = start_time
84 self.duration = 0
85 self.samples = []
86 self.parent = None
87 self.child_list = []
88
89 self.active = None
90 self.last_user_cpu_time = None
91 self.last_sys_cpu_time = None
92
93 self.last_cpu_ns = 0
94 self.last_blkio_delay_ns = 0
95 self.last_swapin_delay_ns = 0
96
97 # split this process' run - triggered by a name change
98 def split(self, writer, pid, cmd, ppid, start_time):
99 split = Process (writer, pid, cmd, ppid, start_time)
100
101 split.last_cpu_ns = self.last_cpu_ns
102 split.last_blkio_delay_ns = self.last_blkio_delay_ns
103 split.last_swapin_delay_ns = self.last_swapin_delay_ns
104
105 return split
106
107 def __str__(self):
108 return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ])
109
110 def calc_stats(self, samplePeriod):
111 if self.samples:
112 firstSample = self.samples[0]
113 lastSample = self.samples[-1]
114 self.start_time = min(firstSample.time, self.start_time)
115 self.duration = lastSample.time - self.start_time + samplePeriod
116
117 activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] )
118 activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] )
119 self.active = (activeCount>2)
120
121 def calc_load(self, userCpu, sysCpu, interval):
122 userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval
123 sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval
124 cpuLoad = userCpuLoad + sysCpuLoad
125 # normalize
126 if cpuLoad > 1.0:
127 userCpuLoad = userCpuLoad / cpuLoad
128 sysCpuLoad = sysCpuLoad / cpuLoad
129 return (userCpuLoad, sysCpuLoad)
130
131 def set_parent(self, processMap):
132 if self.ppid != None:
133 self.parent = processMap.get (self.ppid)
134 if self.parent == None and self.pid // 1000 > 1 and \
135 not (self.ppid == 2000 or self.pid == 2000): # kernel threads: ppid=2
136 self.writer.warn("Missing CONFIG_PROC_EVENTS: no parent for pid '%i' ('%s') with ppid '%i'" \
137 % (self.pid,self.cmd,self.ppid))
138
139 def get_end_time(self):
140 return self.start_time + self.duration
141
142class DiskSample:
143 def __init__(self, time, read, write, util):
144 self.time = time
145 self.read = read
146 self.write = write
147 self.util = util
148 self.tput = read + write
149
150 def __str__(self):
151 return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)])
diff --git a/scripts/pybootchartgui/pybootchartgui/tests/parser_test.py b/scripts/pybootchartgui/pybootchartgui/tests/parser_test.py
new file mode 100644
index 0000000000..00fb3bf797
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/tests/parser_test.py
@@ -0,0 +1,105 @@
1import sys, os, re, struct, operator, math
2from collections import defaultdict
3import unittest
4
5sys.path.insert(0, os.getcwd())
6
7import pybootchartgui.parsing as parsing
8import pybootchartgui.main as main
9
10debug = False
11
12def floatEq(f1, f2):
13 return math.fabs(f1-f2) < 0.00001
14
15bootchart_dir = os.path.join(os.path.dirname(sys.argv[0]), '../../examples/1/')
16parser = main._mk_options_parser()
17options, args = parser.parse_args(['--q', bootchart_dir])
18writer = main._mk_writer(options)
19
20class TestBCParser(unittest.TestCase):
21
22 def setUp(self):
23 self.name = "My first unittest"
24 self.rootdir = bootchart_dir
25
26 def mk_fname(self,f):
27 return os.path.join(self.rootdir, f)
28
29 def testParseHeader(self):
30 trace = parsing.Trace(writer, args, options)
31 state = parsing.parse_file(writer, trace, self.mk_fname('header'))
32 self.assertEqual(6, len(state.headers))
33 self.assertEqual(2, parsing.get_num_cpus(state.headers))
34
35 def test_parseTimedBlocks(self):
36 trace = parsing.Trace(writer, args, options)
37 state = parsing.parse_file(writer, trace, self.mk_fname('proc_diskstats.log'))
38 self.assertEqual(141, len(state.disk_stats))
39
40 def testParseProcPsLog(self):
41 trace = parsing.Trace(writer, args, options)
42 state = parsing.parse_file(writer, trace, self.mk_fname('proc_ps.log'))
43 samples = state.ps_stats
44 processes = samples.process_map
45 sorted_processes = [processes[k] for k in sorted(processes.keys())]
46
47 ps_data = open(self.mk_fname('extract2.proc_ps.log'))
48 for index, line in enumerate(ps_data):
49 tokens = line.split();
50 process = sorted_processes[index]
51 if debug:
52 print(tokens[0:4])
53 print(process.pid / 1000, process.cmd, process.ppid, len(process.samples))
54 print('-------------------')
55
56 self.assertEqual(tokens[0], str(process.pid // 1000))
57 self.assertEqual(tokens[1], str(process.cmd))
58 self.assertEqual(tokens[2], str(process.ppid // 1000))
59 self.assertEqual(tokens[3], str(len(process.samples)))
60 ps_data.close()
61
62 def testparseProcDiskStatLog(self):
63 trace = parsing.Trace(writer, args, options)
64 state_with_headers = parsing.parse_file(writer, trace, self.mk_fname('header'))
65 state_with_headers.headers['system.cpu'] = 'xxx (2)'
66 samples = parsing.parse_file(writer, state_with_headers, self.mk_fname('proc_diskstats.log')).disk_stats
67 self.assertEqual(141, len(samples))
68
69 diskstats_data = open(self.mk_fname('extract.proc_diskstats.log'))
70 for index, line in enumerate(diskstats_data):
71 tokens = line.split('\t')
72 sample = samples[index]
73 if debug:
74 print(line.rstrip())
75 print(sample)
76 print('-------------------')
77
78 self.assertEqual(tokens[0], str(sample.time))
79 self.assert_(floatEq(float(tokens[1]), sample.read))
80 self.assert_(floatEq(float(tokens[2]), sample.write))
81 self.assert_(floatEq(float(tokens[3]), sample.util))
82 diskstats_data.close()
83
84 def testparseProcStatLog(self):
85 trace = parsing.Trace(writer, args, options)
86 samples = parsing.parse_file(writer, trace, self.mk_fname('proc_stat.log')).cpu_stats
87 self.assertEqual(141, len(samples))
88
89 stat_data = open(self.mk_fname('extract.proc_stat.log'))
90 for index, line in enumerate(stat_data):
91 tokens = line.split('\t')
92 sample = samples[index]
93 if debug:
94 print(line.rstrip())
95 print(sample)
96 print('-------------------')
97 self.assert_(floatEq(float(tokens[0]), sample.time))
98 self.assert_(floatEq(float(tokens[1]), sample.user))
99 self.assert_(floatEq(float(tokens[2]), sample.sys))
100 self.assert_(floatEq(float(tokens[3]), sample.io))
101 stat_data.close()
102
103if __name__ == '__main__':
104 unittest.main()
105
diff --git a/scripts/pybootchartgui/pybootchartgui/tests/process_tree_test.py b/scripts/pybootchartgui/pybootchartgui/tests/process_tree_test.py
new file mode 100644
index 0000000000..6f46a1c03d
--- /dev/null
+++ b/scripts/pybootchartgui/pybootchartgui/tests/process_tree_test.py
@@ -0,0 +1,92 @@
1import sys
2import os
3import unittest
4
5sys.path.insert(0, os.getcwd())
6
7import pybootchartgui.parsing as parsing
8import pybootchartgui.process_tree as process_tree
9import pybootchartgui.main as main
10
11if sys.version_info >= (3, 0):
12 long = int
13
14class TestProcessTree(unittest.TestCase):
15
16 def setUp(self):
17 self.name = "Process tree unittest"
18 self.rootdir = os.path.join(os.path.dirname(sys.argv[0]), '../../examples/1/')
19
20 parser = main._mk_options_parser()
21 options, args = parser.parse_args(['--q', self.rootdir])
22 writer = main._mk_writer(options)
23 trace = parsing.Trace(writer, args, options)
24
25 parsing.parse_file(writer, trace, self.mk_fname('proc_ps.log'))
26 trace.compile(writer)
27 self.processtree = process_tree.ProcessTree(writer, None, trace.ps_stats, \
28 trace.ps_stats.sample_period, None, options.prune, None, None, False, for_testing = True)
29
30 def mk_fname(self,f):
31 return os.path.join(self.rootdir, f)
32
33 def flatten(self, process_tree):
34 flattened = []
35 for p in process_tree:
36 flattened.append(p)
37 flattened.extend(self.flatten(p.child_list))
38 return flattened
39
40 def checkAgainstJavaExtract(self, filename, process_tree):
41 test_data = open(filename)
42 for expected, actual in zip(test_data, self.flatten(process_tree)):
43 tokens = expected.split('\t')
44 self.assertEqual(int(tokens[0]), actual.pid // 1000)
45 self.assertEqual(tokens[1], actual.cmd)
46 self.assertEqual(long(tokens[2]), 10 * actual.start_time)
47 self.assert_(long(tokens[3]) - 10 * actual.duration < 5, "duration")
48 self.assertEqual(int(tokens[4]), len(actual.child_list))
49 self.assertEqual(int(tokens[5]), len(actual.samples))
50 test_data.close()
51
52 def testBuild(self):
53 process_tree = self.processtree.process_tree
54 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.1.log'), process_tree)
55
56 def testMergeLogger(self):
57 self.processtree.merge_logger(self.processtree.process_tree, 'bootchartd', None, False)
58 process_tree = self.processtree.process_tree
59 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.2.log'), process_tree)
60
61 def testPrune(self):
62 self.processtree.merge_logger(self.processtree.process_tree, 'bootchartd', None, False)
63 self.processtree.prune(self.processtree.process_tree, None)
64 process_tree = self.processtree.process_tree
65 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.3b.log'), process_tree)
66
67 def testMergeExploders(self):
68 self.processtree.merge_logger(self.processtree.process_tree, 'bootchartd', None, False)
69 self.processtree.prune(self.processtree.process_tree, None)
70 self.processtree.merge_exploders(self.processtree.process_tree, set(['hwup']))
71 process_tree = self.processtree.process_tree
72 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.3c.log'), process_tree)
73
74 def testMergeSiblings(self):
75 self.processtree.merge_logger(self.processtree.process_tree, 'bootchartd', None, False)
76 self.processtree.prune(self.processtree.process_tree, None)
77 self.processtree.merge_exploders(self.processtree.process_tree, set(['hwup']))
78 self.processtree.merge_siblings(self.processtree.process_tree)
79 process_tree = self.processtree.process_tree
80 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.3d.log'), process_tree)
81
82 def testMergeRuns(self):
83 self.processtree.merge_logger(self.processtree.process_tree, 'bootchartd', None, False)
84 self.processtree.prune(self.processtree.process_tree, None)
85 self.processtree.merge_exploders(self.processtree.process_tree, set(['hwup']))
86 self.processtree.merge_siblings(self.processtree.process_tree)
87 self.processtree.merge_runs(self.processtree.process_tree)
88 process_tree = self.processtree.process_tree
89 self.checkAgainstJavaExtract(self.mk_fname('extract.processtree.3e.log'), process_tree)
90
91if __name__ == '__main__':
92 unittest.main()
diff --git a/scripts/relocate_sdk.py b/scripts/relocate_sdk.py
new file mode 100755
index 0000000000..05d9fd65ed
--- /dev/null
+++ b/scripts/relocate_sdk.py
@@ -0,0 +1,243 @@
1#!/usr/bin/env python
2#
3# Copyright (c) 2012 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#
18# DESCRIPTION
19# This script is called by the SDK installer script. It replaces the dynamic
20# loader path in all binaries and also fixes the SYSDIR paths/lengths and the
21# location of ld.so.cache in the dynamic loader binary
22#
23# AUTHORS
24# Laurentiu Palcu <laurentiu.palcu@intel.com>
25#
26
27import struct
28import sys
29import stat
30import os
31import re
32import errno
33
34if sys.version < '3':
35 def b(x):
36 return x
37else:
38 def b(x):
39 return x.encode(sys.getfilesystemencoding())
40
41old_prefix = re.compile(b("##DEFAULT_INSTALL_DIR##"))
42
43def get_arch():
44 f.seek(0)
45 e_ident =f.read(16)
46 ei_mag0,ei_mag1_3,ei_class = struct.unpack("<B3sB11x", e_ident)
47
48 if (ei_mag0 != 0x7f and ei_mag1_3 != "ELF") or ei_class == 0:
49 return 0
50
51 if ei_class == 1:
52 return 32
53 elif ei_class == 2:
54 return 64
55
56def parse_elf_header():
57 global e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\
58 e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx
59
60 f.seek(0)
61 elf_header = f.read(64)
62
63 if arch == 32:
64 # 32bit
65 hdr_fmt = "<HHILLLIHHHHHH"
66 hdr_size = 52
67 else:
68 # 64bit
69 hdr_fmt = "<HHIQQQIHHHHHH"
70 hdr_size = 64
71
72 e_type, e_machine, e_version, e_entry, e_phoff, e_shoff, e_flags,\
73 e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx =\
74 struct.unpack(hdr_fmt, elf_header[16:hdr_size])
75
76def change_interpreter(elf_file_name):
77 if arch == 32:
78 ph_fmt = "<IIIIIIII"
79 else:
80 ph_fmt = "<IIQQQQQQ"
81
82 """ look for PT_INTERP section """
83 for i in range(0,e_phnum):
84 f.seek(e_phoff + i * e_phentsize)
85 ph_hdr = f.read(e_phentsize)
86 if arch == 32:
87 # 32bit
88 p_type, p_offset, p_vaddr, p_paddr, p_filesz,\
89 p_memsz, p_flags, p_align = struct.unpack(ph_fmt, ph_hdr)
90 else:
91 # 64bit
92 p_type, p_flags, p_offset, p_vaddr, p_paddr, \
93 p_filesz, p_memsz, p_align = struct.unpack(ph_fmt, ph_hdr)
94
95 """ change interpreter """
96 if p_type == 3:
97 # PT_INTERP section
98 f.seek(p_offset)
99 # External SDKs with mixed pre-compiled binaries should not get
100 # relocated so look for some variant of /lib
101 fname = f.read(11)
102 if fname.startswith(b("/lib/")) or fname.startswith(b("/lib64/")) or \
103 fname.startswith(b("/lib32/")) or fname.startswith(b("/usr/lib32/")) or \
104 fname.startswith(b("/usr/lib32/")) or fname.startswith(b("/usr/lib64/")):
105 break
106 if (len(new_dl_path) >= p_filesz):
107 print("ERROR: could not relocate %s, interp size = %i and %i is needed." \
108 % (elf_file_name, p_memsz, len(new_dl_path) + 1))
109 break
110 dl_path = new_dl_path + b("\0") * (p_filesz - len(new_dl_path))
111 f.seek(p_offset)
112 f.write(dl_path)
113 break
114
115def change_dl_sysdirs():
116 if arch == 32:
117 sh_fmt = "<IIIIIIIIII"
118 else:
119 sh_fmt = "<IIQQQQIIQQ"
120
121 """ read section string table """
122 f.seek(e_shoff + e_shstrndx * e_shentsize)
123 sh_hdr = f.read(e_shentsize)
124 if arch == 32:
125 sh_offset, sh_size = struct.unpack("<16xII16x", sh_hdr)
126 else:
127 sh_offset, sh_size = struct.unpack("<24xQQ24x", sh_hdr)
128
129 f.seek(sh_offset)
130 sh_strtab = f.read(sh_size)
131
132 sysdirs = sysdirs_len = ""
133
134 """ change ld.so.cache path and default libs path for dynamic loader """
135 for i in range(0,e_shnum):
136 f.seek(e_shoff + i * e_shentsize)
137 sh_hdr = f.read(e_shentsize)
138
139 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size, sh_link,\
140 sh_info, sh_addralign, sh_entsize = struct.unpack(sh_fmt, sh_hdr)
141
142 name = sh_strtab[sh_name:sh_strtab.find(b("\0"), sh_name)]
143
144 """ look only into SHT_PROGBITS sections """
145 if sh_type == 1:
146 f.seek(sh_offset)
147 """ default library paths cannot be changed on the fly because """
148 """ the string lengths have to be changed too. """
149 if name == b(".sysdirs"):
150 sysdirs = f.read(sh_size)
151 sysdirs_off = sh_offset
152 sysdirs_sect_size = sh_size
153 elif name == b(".sysdirslen"):
154 sysdirslen = f.read(sh_size)
155 sysdirslen_off = sh_offset
156 elif name == b(".ldsocache"):
157 ldsocache_path = f.read(sh_size)
158 new_ldsocache_path = old_prefix.sub(new_prefix, ldsocache_path)
159 # pad with zeros
160 new_ldsocache_path += b("\0") * (sh_size - len(new_ldsocache_path))
161 # write it back
162 f.seek(sh_offset)
163 f.write(new_ldsocache_path)
164
165 if sysdirs != "" and sysdirslen != "":
166 paths = sysdirs.split(b("\0"))
167 sysdirs = b("")
168 sysdirslen = b("")
169 for path in paths:
170 """ exit the loop when we encounter first empty string """
171 if path == b(""):
172 break
173
174 new_path = old_prefix.sub(new_prefix, path)
175 sysdirs += new_path + b("\0")
176
177 if arch == 32:
178 sysdirslen += struct.pack("<L", len(new_path))
179 else:
180 sysdirslen += struct.pack("<Q", len(new_path))
181
182 """ pad with zeros """
183 sysdirs += b("\0") * (sysdirs_sect_size - len(sysdirs))
184
185 """ write the sections back """
186 f.seek(sysdirs_off)
187 f.write(sysdirs)
188 f.seek(sysdirslen_off)
189 f.write(sysdirslen)
190
191# MAIN
192if len(sys.argv) < 4:
193 sys.exit(-1)
194
195# In python > 3, strings may also contain Unicode characters. So, convert
196# them to bytes
197if sys.version_info < (3,):
198 new_prefix = sys.argv[1]
199 new_dl_path = sys.argv[2]
200else:
201 new_prefix = sys.argv[1].encode()
202 new_dl_path = sys.argv[2].encode()
203
204executables_list = sys.argv[3:]
205
206for e in executables_list:
207 perms = os.stat(e)[stat.ST_MODE]
208 if os.access(e, os.W_OK|os.R_OK):
209 perms = None
210 else:
211 os.chmod(e, perms|stat.S_IRWXU)
212
213 try:
214 f = open(e, "r+b")
215 except IOError:
216 exctype, ioex = sys.exc_info()[:2]
217 if ioex.errno == errno.ETXTBSY:
218 print("Could not open %s. File used by another process.\nPlease "\
219 "make sure you exit all processes that might use any SDK "\
220 "binaries." % e)
221 else:
222 print("Could not open %s: %s(%d)" % (e, ioex.strerror, ioex.errno))
223 sys.exit(-1)
224
225 # Save old size and do a size check at the end. Just a safety measure.
226 old_size = os.path.getsize(e)
227
228 arch = get_arch()
229 if arch:
230 parse_elf_header()
231 change_interpreter(e)
232 change_dl_sysdirs()
233
234 """ change permissions back """
235 if perms:
236 os.chmod(e, perms)
237
238 f.close()
239
240 if old_size != os.path.getsize(e):
241 print("New file size for %s is different. Looks like a relocation error!", e)
242 sys.exit(-1)
243
diff --git a/scripts/rootfs_rpm-extract-postinst.awk b/scripts/rootfs_rpm-extract-postinst.awk
new file mode 100644
index 0000000000..8f2836b32c
--- /dev/null
+++ b/scripts/rootfs_rpm-extract-postinst.awk
@@ -0,0 +1,11 @@
1/Name:.*/ {
2 package = substr($0, 7)
3 next
4}
5/postinstall.*scriptlet .*/ {
6 next
7}
8{
9 print $0 >> ENVIRON["D"] "/etc/rpm-postinsts/" package ".sh"
10}
11
diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh
new file mode 100755
index 0000000000..5df8c0f705
--- /dev/null
+++ b/scripts/rpm2cpio.sh
@@ -0,0 +1,53 @@
1#!/bin/sh
2
3# This comes from the RPM5 5.4.0 distribution.
4
5pkg=$1
6if [ "$pkg" = "" -o ! -e "$pkg" ]; then
7 echo "no package supplied" 1>&2
8 exit 1
9fi
10
11leadsize=96
12o=`expr $leadsize + 8`
13set `od -j $o -N 8 -t u1 $pkg`
14il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
15dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
16# echo "sig il: $il dl: $dl"
17
18sigsize=`expr 8 + 16 \* $il + $dl`
19o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
20set `od -j $o -N 8 -t u1 $pkg`
21il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
22dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
23# echo "hdr il: $il dl: $dl"
24
25hdrsize=`expr 8 + 16 \* $il + $dl`
26o=`expr $o + $hdrsize`
27EXTRACTOR="dd if=$pkg ibs=$o skip=1"
28
29COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
30if echo $COMPRESSION |grep -iq gzip; then
31 DECOMPRESSOR=gunzip
32elif echo $COMPRESSION |grep -iq bzip2; then
33 DECOMPRESSOR=bunzip2
34elif echo $COMPRESSION |grep -iq xz; then
35 DECOMPRESSOR=unxz
36elif echo $COMPRESSION |grep -iq cpio; then
37 DECOMPRESSOR=cat
38else
39 # Most versions of file don't support LZMA, therefore we assume
40 # anything not detected is LZMA
41 DECOMPRESSOR=`which unlzma 2>/dev/null`
42 case "$DECOMPRESSOR" in
43 /* ) ;;
44 * ) DECOMPRESSOR=`which lzmash 2>/dev/null`
45 case "$DECOMPRESSOR" in
46 /* ) DECOMPRESSOR="lzmash -d -c" ;;
47 * ) DECOMPRESSOR=cat ;;
48 esac
49 ;;
50 esac
51fi
52
53$EXTRACTOR 2>/dev/null | $DECOMPRESSOR
diff --git a/scripts/runqemu b/scripts/runqemu
new file mode 100755
index 0000000000..e270274a97
--- /dev/null
+++ b/scripts/runqemu
@@ -0,0 +1,507 @@
1#!/bin/bash
2#
3# Handle running OE images standalone with QEMU
4#
5# Copyright (C) 2006-2011 Linux Foundation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20usage() {
21 MYNAME=`basename $0`
22 echo ""
23 echo "Usage: you can run this script with any valid combination"
24 echo "of the following options (in any order):"
25 echo " QEMUARCH - the qemu machine architecture to use"
26 echo " KERNEL - the kernel image file to use"
27 echo " ROOTFS - the rootfs image file or nfsroot directory to use"
28 echo " MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)"
29 echo " RAMFS - boot a ramfs-based image"
30 echo " ISO - boot an ISO image"
31 echo " VM - boot a vmdk image"
32 echo " Simplified QEMU command-line options can be passed with:"
33 echo " nographic - disables video console"
34 echo " serial - enables a serial console on /dev/ttyS0"
35 echo " kvm - enables KVM when running qemux86/qemux86-64 (VT-capable CPU required)"
36 echo " publicvnc - enable a VNC server open to all hosts"
37 echo " qemuparams=\"xyz\" - specify custom parameters to QEMU"
38 echo " bootparams=\"xyz\" - specify custom kernel parameters during boot"
39 echo ""
40 echo "Examples:"
41 echo " $MYNAME qemuarm"
42 echo " $MYNAME qemux86-64 core-image-sato ext3"
43 echo " $MYNAME path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial"
44 echo " $MYNAME qemux86 ramfs"
45 echo " $MYNAME qemux86 iso"
46 echo " $MYNAME qemux86 qemuparams=\"-m 256\""
47 echo " $MYNAME qemux86 bootparams=\"psplash=false\""
48 echo " $MYNAME path/to/<image>-<machine>.vmdk"
49 exit 1
50}
51
52if [ "x$1" = "x" ]; then
53 usage
54fi
55
56error() {
57 echo "Error: "$*
58 usage
59}
60
61MACHINE=${MACHINE:=""}
62KERNEL=${KERNEL:=""}
63ROOTFS=${ROOTFS:=""}
64VM=${VM:=""}
65FSTYPE=""
66LAZY_ROOTFS=""
67SCRIPT_QEMU_OPT=""
68SCRIPT_QEMU_EXTRA_OPT=""
69SCRIPT_KERNEL_OPT=""
70SERIALSTDIO=""
71KVM_ENABLED="no"
72KVM_ACTIVE="no"
73
74# Determine whether the file is a kernel or QEMU image, and set the
75# appropriate variables
76process_filename() {
77 filename=$1
78
79 # Extract the filename extension
80 EXT=`echo $filename | awk -F . '{ print \$NF }'`
81 case /$EXT/ in
82 /bin/)
83 # A file ending in .bin is a kernel
84 [ -z "$KERNEL" ] && KERNEL=$filename || \
85 error "conflicting KERNEL args [$KERNEL] and [$filename]"
86 ;;
87 /ext[234]/|/jffs2/|/btrfs/)
88 # A file ending in a supportted fs type is a rootfs image
89 if [ -z "$FSTYPE" -o "$FSTYPE" = "$EXT" ]; then
90 FSTYPE=$EXT
91 ROOTFS=$filename
92 else
93 error "conflicting FSTYPE types [$FSTYPE] and [$EXT]"
94 fi
95 ;;
96 /vmdk/)
97 FSTYPE=$EXT
98 VM=$filename
99 ;;
100 *)
101 error "unknown file arg [$filename]"
102 ;;
103 esac
104}
105
106# Parse command line args without requiring specific ordering. It's a
107# bit more complex, but offers a great user experience.
108while true; do
109 arg=${1}
110 case "$arg" in
111 "qemux86" | "qemux86-64" | "qemuarm" | "qemumips" | "qemumipsel" | \
112 "qemumips64" | "qemush4" | "qemuppc" | "qemumicroblaze" | "qemuzynq")
113 [ -z "$MACHINE" ] && MACHINE=$arg || \
114 error "conflicting MACHINE types [$MACHINE] and [$arg]"
115 ;;
116 "ext2" | "ext3" | "ext4" | "jffs2" | "nfs" | "btrfs")
117 [ -z "$FSTYPE" -o "$FSTYPE" = "$arg" ] && FSTYPE=$arg || \
118 error "conflicting FSTYPE types [$FSTYPE] and [$arg]"
119 ;;
120 *-image*)
121 [ -z "$ROOTFS" ] || \
122 error "conflicting ROOTFS args [$ROOTFS] and [$arg]"
123 if [ -f "$arg" ]; then
124 process_filename $arg
125 elif [ -d "$arg" ]; then
126 # Handle the case where the nfsroot dir has -image-
127 # in the pathname
128 echo "Assuming $arg is an nfs rootfs"
129 FSTYPE=nfs
130 ROOTFS=$arg
131 else
132 ROOTFS=$arg
133 LAZY_ROOTFS="true"
134 fi
135 ;;
136 "ramfs")
137 FSTYPE=cpio.gz
138 RAMFS=true
139 ;;
140 "iso")
141 FSTYPE=iso
142 ISOFS=true
143 ;;
144 "nographic")
145 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -nographic"
146 SCRIPT_KERNEL_OPT="$SCRIPT_KERNEL_OPT console=ttyS0"
147 ;;
148 "serial")
149 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -serial stdio"
150 SCRIPT_KERNEL_OPT="$SCRIPT_KERNEL_OPT console=ttyS0"
151 SERIALSTDIO="1"
152 ;;
153 "biosdir="*)
154 CUSTOMBIOSDIR="${arg##biosdir=}"
155 ;;
156 "qemuparams="*)
157 SCRIPT_QEMU_EXTRA_OPT="${arg##qemuparams=}"
158
159 # Warn user if they try to specify serial or kvm options
160 # to use simplified options instead
161 serial_option=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-serial\)'`
162 kvm_option=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-enable-kvm\)'`
163 vga_option=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-vga\)'`
164 [ ! -z "$serial_option" -o ! -z "$kvm_option" ] && \
165 echo "Please use simplified serial or kvm options instead"
166 ;;
167 "bootparams="*)
168 SCRIPT_KERNEL_OPT="$SCRIPT_KERNEL_OPT ${arg##bootparams=}"
169 ;;
170 "audio")
171 if [ "x$MACHINE" = "xqemux86" -o "x$MACHINE" = "xqemux86-64" ]; then
172 echo "Enabling audio in qemu."
173 echo "Please install snd_intel8x0 or snd_ens1370 driver in linux guest."
174 QEMU_AUDIO_DRV="alsa"
175 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -soundhw ac97,es1370"
176 fi
177 ;;
178 "kvm")
179 KVM_ENABLED="yes"
180 KVM_CAPABLE=`grep -q 'vmx\|svm' /proc/cpuinfo && echo 1`
181 ;;
182 "slirp")
183 SLIRP_ENABLED="yes"
184 ;;
185 "publicvnc")
186 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -vnc 0.0.0.0:0"
187 ;;
188 "") break ;;
189 *)
190 # A directory name is an nfs rootfs
191 if [ -d "$arg" ]; then
192 echo "Assuming $arg is an nfs rootfs"
193 if [ -z "$FSTYPE" -o "$FSTYPE" = "nfs" ]; then
194 FSTYPE=nfs
195 else
196 error "conflicting FSTYPE types [$arg] and nfs"
197 fi
198
199 if [ -z "$ROOTFS" ]; then
200 ROOTFS=$arg
201 else
202 error "conflicting ROOTFS args [$ROOTFS] and [$arg]"
203 fi
204 elif [ -f "$arg" ]; then
205 process_filename $arg
206 else
207 error "unable to classify arg [$arg]"
208 fi
209 ;;
210 esac
211 shift
212done
213
214if [ ! -c /dev/net/tun ] ; then
215 echo "TUN control device /dev/net/tun is unavailable; you may need to enable TUN (e.g. sudo modprobe tun)"
216 exit 1
217elif [ ! -w /dev/net/tun ] ; then
218 echo "TUN control device /dev/net/tun is not writable, please fix (e.g. sudo chmod 666 /dev/net/tun)"
219 exit 1
220fi
221
222# Report errors for missing combinations of options
223if [ -z "$MACHINE" -a -z "$KERNEL" -a -z "$VM" ]; then
224 error "you must specify at least a MACHINE, VM, or KERNEL argument"
225fi
226if [ "$FSTYPE" = "nfs" -a -z "$ROOTFS" ]; then
227 error "NFS booting without an explicit ROOTFS path is not yet supported"
228fi
229
230if [ -z "$MACHINE" ]; then
231 if [ "x$FSTYPE" = "xvmdk" ]; then
232 MACHINE=`basename $VM | sed -n 's/.*\(qemux86-64\|qemux86\|qemuarm\|qemumips64\|qemumips\|qemuppc\|qemush4\).*/\1/p'`
233 if [ -z "$MACHINE" ]; then
234 error "Unable to set MACHINE from vmdk filename [$VM]"
235 fi
236 echo "Set MACHINE to [$MACHINE] based on vmdk [$VM]"
237 else
238 MACHINE=`basename $KERNEL | sed -n 's/.*\(qemux86-64\|qemux86\|qemuarm\|qemumips64\|qemumips\|qemuppc\|qemush4\).*/\1/p'`
239 if [ -z "$MACHINE" ]; then
240 error "Unable to set MACHINE from kernel filename [$KERNEL]"
241 fi
242 echo "Set MACHINE to [$MACHINE] based on kernel [$KERNEL]"
243 fi
244fi
245
246YOCTO_KVM_WIKI="https://wiki.yoctoproject.org/wiki/How_to_enable_KVM_for_Poky_qemu"
247YOCTO_PARAVIRT_KVM_WIKI="https://wiki.yoctoproject.org/wiki/Running_an_x86_Yocto_Linux_image_under_QEMU_KVM"
248# Detect KVM configuration
249if [ "x$KVM_ENABLED" = "xyes" ]; then
250 if [ -z "$KVM_CAPABLE" ]; then
251 echo "You are trying to enable KVM on a cpu without VT support."
252 echo "Remove kvm from the command-line, or refer"
253 echo "$YOCTO_KVM_WIKI";
254 exit 1;
255 fi
256 if [ "x$MACHINE" != "xqemux86" -a "x$MACHINE" != "xqemux86-64" ]; then
257 echo "KVM only support x86 & x86-64. Remove kvm from the command-line";
258 exit 1;
259 fi
260 if [ ! -e /dev/kvm ]; then
261 echo "Missing KVM device. Have you inserted kvm modules?"
262 echo "For further help see:"
263 echo "$YOCTO_KVM_WIKI";
264 exit 1;
265 fi
266 if [ ! -e /dev/vhost-net ]; then
267 echo "Missing virtio net device. Have you inserted vhost-net module?"
268 echo "For further help see:"
269 echo "$YOCTO_PARAVIRT_KVM_WIKI";
270 exit 1;
271 fi
272 if [ -w /dev/kvm -a -r /dev/kvm ]; then
273 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -enable-kvm"
274 KVM_ACTIVE="yes"
275 else
276 echo "You have no rights on /dev/kvm."
277 echo "Please change the ownership of this file as described at:"
278 echo "$YOCTO_KVM_WIKI";
279 exit 1;
280 fi
281 if [ ! -w /dev/vhost-net -o ! -r /dev/vhost-net ]; then
282 if [ "$SLIRP_ENABLED" != "yes" ] ; then
283 echo "You have no rights on /dev/vhost-net."
284 echo "Please change the ownership of this file as described at:"
285 echo "$YOCTO_PARAVIRT_KVM_WIKI";
286 exit 1;
287 fi
288 fi
289fi
290
291machine2=`echo $MACHINE | tr 'a-z' 'A-Z' | sed 's/-/_/'`
292# MACHINE is now set for all cases
293
294# Defaults used when these vars need to be inferred
295QEMUX86_DEFAULT_KERNEL=bzImage-qemux86.bin
296QEMUX86_DEFAULT_FSTYPE=ext3
297
298QEMUX86_64_DEFAULT_KERNEL=bzImage-qemux86-64.bin
299QEMUX86_64_DEFAULT_FSTYPE=ext3
300
301QEMUARM_DEFAULT_KERNEL=zImage-qemuarm.bin
302QEMUARM_DEFAULT_FSTYPE=ext3
303
304QEMUMIPS_DEFAULT_KERNEL=vmlinux-qemumips.bin
305QEMUMIPS_DEFAULT_FSTYPE=ext3
306
307QEMUMIPSEL_DEFAULT_KERNEL=vmlinux-qemumipsel.bin
308QEMUMIPSEL_DEFAULT_FSTYPE=ext3
309
310QEMUMIPS64_DEFAULT_KERNEL=vmlinux-qemumips64.bin
311QEMUMIPS64_DEFAULT_FSTYPE=ext3
312
313QEMUSH4_DEFAULT_KERNEL=vmlinux-qemumips.bin
314QEMUSH4_DEFAULT_FSTYPE=ext3
315
316QEMUPPC_DEFAULT_KERNEL=vmlinux-qemuppc.bin
317QEMUPPC_DEFAULT_FSTYPE=ext3
318
319QEMUMICROBLAZE_DEFAULT_KERNEL=linux.bin.ub
320QEMUMICROBLAZE_DEFAULT_FSTYPE=cpio
321
322QEMUZYNQ_DEFAULT_KERNEL=uImage
323QEMUZYNQ_DEFAULT_FSTYPE=cpio
324
325AKITA_DEFAULT_KERNEL=zImage-akita.bin
326AKITA_DEFAULT_FSTYPE=jffs2
327
328SPITZ_DEFAULT_KERNEL=zImage-spitz.bin
329SPITZ_DEFAULT_FSTYPE=ext3
330
331setup_path_vars() {
332 if [ -z "$OE_TMPDIR" ] ; then
333 PATHS_REQUIRED=true
334 elif [ "$1" = "1" -a -z "$DEPLOY_DIR_IMAGE" ] ; then
335 PATHS_REQUIRED=true
336 else
337 PATHS_REQUIRED=false
338 fi
339
340 if [ "$PATHS_REQUIRED" = "true" ]; then
341 # Try to get the variable values from bitbake
342 type -P bitbake &>/dev/null || {
343 echo "In order for this script to dynamically infer paths";
344 echo "to kernels or filesystem images, you either need";
345 echo "bitbake in your PATH or to source oe-init-build-env";
346 echo "before running this script" >&2;
347 exit 1; }
348
349 # We have bitbake in PATH, get the variable values from bitbake
350 BITBAKE_ENV_TMPFILE=`mktemp --tmpdir runqemu.XXXXXXXXXX`
351 if [ "$?" != "0" ] ; then
352 echo "Error: mktemp failed for bitbake environment output"
353 exit 1
354 fi
355
356 MACHINE=$MACHINE bitbake -e > $BITBAKE_ENV_TMPFILE
357 if [ -z "$OE_TMPDIR" ] ; then
358 OE_TMPDIR=`cat $BITBAKE_ENV_TMPFILE | sed -n 's/^TMPDIR=\"\(.*\)\"/\1/p'`
359 fi
360 if [ -z "$DEPLOY_DIR_IMAGE" ] ; then
361 DEPLOY_DIR_IMAGE=`cat $BITBAKE_ENV_TMPFILE | sed -n 's/^DEPLOY_DIR_IMAGE=\"\(.*\)\"/\1/p'`
362 fi
363 if [ -z "$OE_TMPDIR" ]; then
364 # Check for errors from bitbake that the user needs to know about
365 BITBAKE_OUTPUT=`cat $BITBAKE_ENV_TMPFILE | wc -l`
366 if [ "$BITBAKE_OUTPUT" -eq "0" ]; then
367 echo "Error: this script needs to be run from your build directory, or you need"
368 echo "to explicitly set OE_TMPDIR and DEPLOY_DIR_IMAGE in your environment"
369 else
370 echo "There was an error running bitbake to determine TMPDIR"
371 echo "Here is the output from 'bitbake -e':"
372 cat $BITBAKE_ENV_TMPFILE
373 fi
374 rm $BITBAKE_ENV_TMPFILE
375 exit 1
376 fi
377 rm $BITBAKE_ENV_TMPFILE
378 fi
379}
380
381setup_sysroot() {
382 # Toolchain installs set up $OECORE_NATIVE_SYSROOT in their
383 # environment script. If that variable isn't set, we're
384 # either in an in-tree build scenario or the environment
385 # script wasn't source'd.
386 if [ -z "$OECORE_NATIVE_SYSROOT" ]; then
387 setup_path_vars
388 BUILD_ARCH=`uname -m`
389 BUILD_OS=`uname | tr '[A-Z]' '[a-z]'`
390 BUILD_SYS="$BUILD_ARCH-$BUILD_OS"
391
392 OECORE_NATIVE_SYSROOT=$OE_TMPDIR/sysroots/$BUILD_SYS
393 fi
394}
395
396# Locate a rootfs image to boot which matches our expected
397# machine and fstype.
398findimage() {
399 where=$1
400 machine=$2
401 extension=$3
402
403 # Sort rootfs candidates by modification time - the most
404 # recently created one is the one we most likely want to boot.
405 filename=`ls -t1 $where/*-image*$machine.$extension 2>/dev/null | head -n1`
406 if [ "x$filename" != "x" ]; then
407 ROOTFS=$filename
408 return
409 fi
410
411 echo "Couldn't find a $machine rootfs image in $where."
412 exit 1
413}
414
415if [ -e "$ROOTFS" -a -z "$FSTYPE" ]; then
416 # Extract the filename extension
417 EXT=`echo $ROOTFS | awk -F . '{ print \$NF }'`
418 if [ "x$EXT" = "xext2" -o "x$EXT" = "xext3" -o \
419 "x$EXT" = "xjffs2" -o "x$EXT" = "xbtrfs" -o \
420 "x$EXT" = "xext4" ]; then
421 FSTYPE=$EXT
422 else
423 echo "Note: Unable to determine filesystem extension for $ROOTFS"
424 echo "We will use the default FSTYPE for $MACHINE"
425 # ...which is done further below...
426 fi
427fi
428
429if [ -z "$KERNEL" -a "x$FSTYPE" != "xvmdk" ]; then
430 setup_path_vars 1
431 eval kernel_file=\$${machine2}_DEFAULT_KERNEL
432 KERNEL=$DEPLOY_DIR_IMAGE/$kernel_file
433
434 if [ -z "$KERNEL" ]; then
435 error "Unable to determine default kernel for MACHINE [$MACHINE]"
436 fi
437fi
438# KERNEL is now set for all cases
439
440if [ -z "$FSTYPE" ]; then
441 eval FSTYPE=\$${machine2}_DEFAULT_FSTYPE
442
443 if [ -z "$FSTYPE" ]; then
444 error "Unable to determine default fstype for MACHINE [$MACHINE]"
445 fi
446fi
447
448# FSTYPE is now set for all cases
449
450# Handle cases where a ROOTFS type is given instead of a filename, e.g.
451# core-image-sato
452if [ "$LAZY_ROOTFS" = "true" ]; then
453 setup_path_vars 1
454 echo "Assuming $ROOTFS really means $DEPLOY_DIR_IMAGE/$ROOTFS-$MACHINE.$FSTYPE"
455 ROOTFS=$DEPLOY_DIR_IMAGE/$ROOTFS-$MACHINE.$FSTYPE
456fi
457
458if [ -z "$ROOTFS" -a "x$FSTYPE" != "xvmdk" ]; then
459 setup_path_vars 1
460 T=$DEPLOY_DIR_IMAGE
461 eval rootfs_list=\$${machine2}_DEFAULT_ROOTFS
462 findimage $T $MACHINE $FSTYPE
463
464 if [ -z "$ROOTFS" ]; then
465 error "Unable to determine default rootfs for MACHINE [$MACHINE]"
466 fi
467fi
468# ROOTFS is now set for all cases, now expand it to be an absolute path, it should exist at this point
469
470ROOTFS=`readlink -f $ROOTFS`
471
472echo ""
473echo "Continuing with the following parameters:"
474if [ "x$FSTYPE" != "xvmdk" ]; then
475 echo "KERNEL: [$KERNEL]"
476 echo "ROOTFS: [$ROOTFS]"
477else
478 echo "VMDK: [$VM]"
479fi
480echo "FSTYPE: [$FSTYPE]"
481
482setup_sysroot
483# OECORE_NATIVE_SYSROOT is now set for all cases
484
485INTERNAL_SCRIPT="$0-internal"
486if [ ! -f "$INTERNAL_SCRIPT" -o ! -r "$INTERNAL_SCRIPT" ]; then
487INTERNAL_SCRIPT=`which runqemu-internal`
488fi
489
490# Specify directory for BIOS, VGA BIOS and keymaps
491if [ ! -z "$CUSTOMBIOSDIR" ]; then
492 if [ -d "$OECORE_NATIVE_SYSROOT/$CUSTOMBIOSDIR" ]; then
493 echo "Assuming biosdir is $OECORE_NATIVE_SYSROOT/$CUSTOMBIOSDIR"
494 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -L $OECORE_NATIVE_SYSROOT/$CUSTOMBIOSDIR"
495 else
496 if [ ! -d "$CUSTOMBIOSDIR" ]; then
497 echo "Custom BIOS directory not found. Tried: $CUSTOMBIOSDIR"
498 echo "and $OECORE_NATIVE_SYSROOT/$CUSTOMBIOSDIR"
499 exit 1;
500 fi
501 echo "Assuming biosdir is $CUSTOMBIOSDIR"
502 SCRIPT_QEMU_OPT="$SCRIPT_QEMU_OPT -L $CUSTOMBIOSDIR"
503 fi
504fi
505
506. $INTERNAL_SCRIPT
507exit $?
diff --git a/scripts/runqemu-addptable2image b/scripts/runqemu-addptable2image
new file mode 100755
index 0000000000..f0195ad8a3
--- /dev/null
+++ b/scripts/runqemu-addptable2image
@@ -0,0 +1,51 @@
1#!/bin/sh
2
3# Add a partion table to an ext2 image file
4#
5# Copyright (C) 2006-2007 OpenedHand Ltd.
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21
22IMAGE=$1
23IMAGEOUT=$2
24
25echo $IMAGE
26echo $IMAGEOUT
27
28size=`ls -l $IMAGE | awk '{ print $5}'`
29size2=`expr $size / 512 / 16 / 63`
30
31echo $size
32echo $size2
33
34# MBR Size = 512 * 63 bytes
35dd if=/dev/zero of=$IMAGEOUT count=63
36
37echo "x" > /tmp/fdisk.cmds
38echo "c" >> /tmp/fdisk.cmds
39echo "1024" >> /tmp/fdisk.cmds
40echo "h" >> /tmp/fdisk.cmds
41echo "16" >> /tmp/fdisk.cmds
42echo "r" >> /tmp/fdisk.cmds
43echo "n" >> /tmp/fdisk.cmds
44echo "p" >> /tmp/fdisk.cmds
45echo "1" >> /tmp/fdisk.cmds
46echo "1" >> /tmp/fdisk.cmds
47echo "$size2" >> /tmp/fdisk.cmds
48echo "w" >> /tmp/fdisk.cmds
49
50/sbin/fdisk $IMAGEOUT < /tmp/fdisk.cmds
51cat $IMAGE >> $IMAGEOUT
diff --git a/scripts/runqemu-export-rootfs b/scripts/runqemu-export-rootfs
new file mode 100755
index 0000000000..40ab20143f
--- /dev/null
+++ b/scripts/runqemu-export-rootfs
@@ -0,0 +1,163 @@
1#!/bin/bash
2#
3# Copyright (c) 2005-2009 Wind River Systems, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18usage() {
19 echo "Usage: $0 {start|stop|restart} <nfs-export-dir>"
20}
21
22if [ $# != 2 ]; then
23 usage
24 exit 1
25fi
26
27if [[ "$1" != "start" && "$1" != "stop" && "$1" != "restart" ]]; then
28 echo "Unknown command '$1'"
29 usage
30 exit 1
31fi
32
33if [ ! -d "$2" ]; then
34 echo "Error: '$2' does not exist"
35 usage
36 exit 1
37fi
38# Ensure the nfs-export-dir is an absolute path
39NFS_EXPORT_DIR=$(cd "$2" && pwd)
40
41SYSROOT_SETUP_SCRIPT=`which oe-find-native-sysroot 2> /dev/null`
42if [ -z "$SYSROOT_SETUP_SCRIPT" ]; then
43 echo "Error: Unable to find the oe-find-native-sysroot script"
44 echo "Did you forget to source your build environment setup script?"
45 exit 1
46fi
47. $SYSROOT_SETUP_SCRIPT
48
49if [ ! -e "$OECORE_NATIVE_SYSROOT/usr/sbin/unfsd" ]; then
50 echo "Error: Unable to find unfsd binary in $OECORE_NATIVE_SYSROOT/usr/sbin/"
51
52 if [ "x$OECORE_DISTRO_VERSION" = "x" ]; then
53 echo "Have you run 'bitbake meta-ide-support'?"
54 else
55 echo "This shouldn't happen - something is missing from your toolchain installation"
56 fi
57 exit 1
58fi
59
60if [ ! -d ~/.runqemu-sdk ]; then
61 mkdir -p ~/.runqemu-sdk
62fi
63
64NFS_INSTANCE=${NFS_INSTANCE:=0}
65EXPORTS=~/.runqemu-sdk/exports$NFS_INSTANCE
66RMTAB=~/.runqemu-sdk/rmtab$NFS_INSTANCE
67NFSPID=~/.runqemu-sdk/nfs$NFS_INSTANCE.pid
68MOUNTPID=~/.runqemu-sdk/mount$NFS_INSTANCE.pid
69
70PSEUDO_OPTS="-P $OECORE_NATIVE_SYSROOT/usr"
71PSEUDO_LOCALSTATEDIR="$NFS_EXPORT_DIR/../$(basename $NFS_EXPORT_DIR).pseudo_state"
72export PSEUDO_LOCALSTATEDIR
73
74if [ ! -d "$PSEUDO_LOCALSTATEDIR" ]; then
75 echo "Error: $PSEUDO_LOCALSTATEDIR does not exist."
76 echo "Did you create the export directory using runqemu-extract-sdk?"
77 exit 1
78fi
79
80# rpc.mountd RPC port
81NFS_MOUNTPROG=$[ 21111 + $NFS_INSTANCE ]
82# rpc.nfsd RPC port
83NFS_NFSPROG=$[ 11111 + $NFS_INSTANCE ]
84# NFS port number
85NFS_PORT=$[ 3049 + 2 * $NFS_INSTANCE ]
86# mountd port number
87MOUNT_PORT=$[ 3048 + 2 * $NFS_INSTANCE ]
88
89## For debugging you would additionally add
90## --debug all
91UNFSD_OPTS="-p -N -i $NFSPID -e $EXPORTS -x $NFS_NFSPROG -n $NFS_PORT -y $NFS_MOUNTPROG -m $MOUNT_PORT"
92
93# Setup the exports file
94if [ "$1" = "start" ]; then
95 echo "Creating exports file..."
96 echo "$NFS_EXPORT_DIR (rw,async,no_root_squash,no_all_squash,insecure)" > $EXPORTS
97fi
98
99# See how we were called.
100case "$1" in
101 start)
102 PORTMAP_RUNNING=`ps -ef | grep portmap | grep -v grep`
103 RPCBIND_RUNNING=`ps -ef | grep rpcbind | grep -v grep`
104 if [[ "x$PORTMAP_RUNNING" = "x" && "x$RPCBIND_RUNNING" = "x" ]]; then
105 echo "======================================================="
106 echo "Error: neither rpcbind nor portmap appear to be running"
107 echo "Please install and start one of these services first"
108 echo "======================================================="
109 echo "Tip: for recent Ubuntu hosts, run:"
110 echo " sudo apt-get install rpcbind"
111 echo "Then add OPTIONS=\"-i -w\" to /etc/default/rpcbind and run"
112 echo " sudo service portmap restart"
113
114 exit 1
115 fi
116
117 echo "Starting User Mode nfsd"
118 echo " $PSEUDO $PSEUDO_OPTS $OECORE_NATIVE_SYSROOT/usr/sbin/unfsd $UNFSD_OPTS"
119 $PSEUDO $PSEUDO_OPTS $OECORE_NATIVE_SYSROOT/usr/sbin/unfsd $UNFSD_OPTS
120 if [ ! $? = 0 ]; then
121 echo "Error starting nfsd"
122 exit 1
123 fi
124 # Check to make sure everything started ok.
125 if [ ! -f $NFSPID ]; then
126 echo "rpc.nfsd did not start correctly"
127 exit 1
128 fi
129 ps -fp `cat $NFSPID` > /dev/null 2> /dev/null
130 if [ ! $? = 0 ]; then
131 echo "rpc.nfsd did not start correctly"
132 exit 1
133 fi
134 echo " "
135 echo "On your target please remember to add the following options for NFS"
136 echo "nfsroot=IP_ADDRESS:$NFS_EXPORT_DIR,nfsvers=3,port=$NFSD_PORT,mountprog=$MOUNTD_RPCPORT,nfsprog=$NFSD_RPCPORT,udp,mountport=$MOUNTD_PORT"
137 ;;
138 stop)
139 if [ -f "$NFSPID" ]; then
140 echo "Stopping rpc.nfsd"
141 kill `cat $NFSPID`
142 rm -f $NFSPID
143 else
144 echo "No PID file, not stopping rpc.nfsd"
145 fi
146 if [ -f "$EXPORTS" ]; then
147 echo "Removing exports file"
148 rm -f $EXPORTS
149 fi
150 ;;
151 restart)
152 $0 stop $NFS_EXPORT_DIR
153 $0 start $NFS_EXPORT_DIR
154 if [ ! $? = 0 ]; then
155 exit 1
156 fi
157 ;;
158 *)
159 echo "$0 {start|stop|restart} <nfs-export-dir>"
160 ;;
161esac
162
163exit 0
diff --git a/scripts/runqemu-extract-sdk b/scripts/runqemu-extract-sdk
new file mode 100755
index 0000000000..4ce906aef0
--- /dev/null
+++ b/scripts/runqemu-extract-sdk
@@ -0,0 +1,103 @@
1#!/bin/bash
2#
3# This utility extracts an SDK image tarball using pseudo, and stores
4# the pseudo database in var/pseudo within the rootfs. If you want to
5# boot QEMU using an nfsroot, you *must* use this script to create the
6# rootfs to ensure it is done correctly with pseudo.
7#
8# Copyright (c) 2010 Intel Corp.
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17# See the GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23function usage() {
24 echo "Usage: $0 <image-tarball> <extract-dir>"
25}
26
27if [ $# -ne 2 ]; then
28 usage
29 exit 1
30fi
31
32SYSROOT_SETUP_SCRIPT=`which oe-find-native-sysroot 2> /dev/null`
33if [ -z "$SYSROOT_SETUP_SCRIPT" ]; then
34 echo "Error: Unable to find the oe-find-native-sysroot script"
35 echo "Did you forget to source your build system environment setup script?"
36 exit 1
37fi
38. $SYSROOT_SETUP_SCRIPT
39PSEUDO_OPTS="-P $OECORE_NATIVE_SYSROOT/usr"
40
41ROOTFS_TARBALL=$1
42SDK_ROOTFS_DIR=$2
43
44if [ ! -e "$ROOTFS_TARBALL" ]; then
45 echo "Error: sdk tarball '$ROOTFS_TARBALL' does not exist"
46 usage
47 exit 1
48fi
49
50# Convert SDK_ROOTFS_DIR to a full pathname
51if [[ ${SDK_ROOTFS_DIR:0:1} != "/" ]]; then
52 SDK_ROOTFS_DIR=$(pwd)/$SDK_ROOTFS_DIR
53fi
54
55TAR_OPTS=""
56if [[ "$ROOTFS_TARBALL" =~ tar\.bz2$ ]]; then
57 TAR_OPTS="--numeric-owner -xjf"
58fi
59if [[ "$ROOTFS_TARBALL" =~ tar\.gz$ ]]; then
60 TAR_OPTS="--numeric-owner -xzf"
61fi
62if [[ "$ROOTFS_TARBALL" =~ \.tar$ ]]; then
63 TAR_OPTS="--numeric-owner -xf"
64fi
65if [ -z "$TAR_OPTS" ]; then
66 echo "Error: Unable to determine sdk tarball format"
67 echo "Accepted types: .tar / .tar.gz / .tar.bz2"
68 exit 1
69fi
70
71if [ ! -d "$SDK_ROOTFS_DIR" ]; then
72 echo "Creating directory $SDK_ROOTFS_DIR"
73 mkdir -p "$SDK_ROOTFS_DIR"
74fi
75
76pseudo_state_dir="$SDK_ROOTFS_DIR/../$(basename "$SDK_ROOTFS_DIR").pseudo_state"
77
78if [ -e "$pseudo_state_dir" ]; then
79 echo "Error: $pseudo_state_dir already exists!"
80 echo "Please delete the rootfs tree and pseudo directory manually"
81 echo "if this is really what you want."
82 exit 1
83fi
84
85mkdir -p "$pseudo_state_dir"
86touch "$pseudo_state_dir/pseudo.pid"
87PSEUDO_LOCALSTATEDIR="$pseudo_state_dir"
88export PSEUDO_LOCALSTATEDIR
89
90echo "Extracting rootfs tarball using pseudo..."
91echo "$PSEUDO $PSEUDO_OPTS tar -C \"$SDK_ROOTFS_DIR\" $TAR_OPTS \"$ROOTFS_TARBALL\""
92$PSEUDO $PSEUDO_OPTS tar -C "$SDK_ROOTFS_DIR" $TAR_OPTS "$ROOTFS_TARBALL"
93
94DIRCHECK=`ls -l "$SDK_ROOTFS_DIR" | wc -l`
95if [ "$DIRCHECK" -lt 5 ]; then
96 echo "Warning: I don't see many files in $SDK_ROOTFS_DIR"
97 echo "Please double-check the extraction worked as intended"
98 exit 0
99fi
100
101echo "SDK image successfully extracted to $SDK_ROOTFS_DIR"
102
103exit 0
diff --git a/scripts/runqemu-gen-tapdevs b/scripts/runqemu-gen-tapdevs
new file mode 100755
index 0000000000..d3b27be291
--- /dev/null
+++ b/scripts/runqemu-gen-tapdevs
@@ -0,0 +1,91 @@
1#!/bin/bash
2#
3# Create a "bank" of tap network devices that can be used by the
4# runqemu script. This script needs to be run as root, and will
5# use the tunctl binary from the build system sysroot. Note: many Linux
6# distros these days still use an older version of tunctl which does not
7# support the group permissions option, hence the need to use the build
8# system provided version.
9#
10# Copyright (C) 2010 Intel Corp.
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License version 2 as
14# published by the Free Software Foundation.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along
22# with this program; if not, write to the Free Software Foundation, Inc.,
23# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25usage() {
26 echo "Usage: sudo $0 <uid> <gid> <num> <native-sysroot-basedir>"
27 echo "Where <uid> is the numeric user id the tap devices will be owned by"
28 echo "Where <gid> is the numeric group id the tap devices will be owned by"
29 echo "<num> is the number of tap devices to create (0 to remove all)"
30 echo "<native-sysroot-basedir> is the path to the build system's native sysroot"
31 exit 1
32}
33
34if [ $EUID -ne 0 ]; then
35 echo "Error: This script must be run with root privileges"
36 exit
37fi
38
39if [ $# -ne 4 ]; then
40 echo "Error: Incorrect number of arguments"
41 usage
42fi
43
44TUID=$1
45GID=$2
46COUNT=$3
47SYSROOT=$4
48
49TUNCTL=$SYSROOT/usr/bin/tunctl
50if [[ ! -x "$TUNCTL" || -d "$TUNCTL" ]]; then
51 echo "Error: $TUNCTL is not an executable"
52 usage
53fi
54
55SCRIPT_DIR=`dirname $0`
56RUNQEMU_IFUP="$SCRIPT_DIR/runqemu-ifup"
57if [ ! -x "$RUNQEMU_IFUP" ]; then
58 echo "Error: Unable to find the runqemu-ifup script in $SCRIPT_DIR"
59 exit 1
60fi
61
62IFCONFIG=`which ip 2> /dev/null`
63if [ -z "$IFCONFIG" ]; then
64 # Is it ever anywhere else?
65 IFCONFIG=/sbin/ip
66fi
67if [ ! -x "$IFCONFIG" ]; then
68 echo "$IFCONFIG cannot be executed"
69 exit 1
70fi
71
72# Ensure we start with a clean slate
73for tap in `$IFCONFIG link | grep tap | awk '{ print \$2 }' | sed s/://`; do
74 echo "Note: Destroying pre-existing tap interface $tap..."
75 $TUNCTL -d $tap
76done
77
78echo "Creating $COUNT tap devices for UID: $TUID GID: $GID..."
79for ((index=0; index < $COUNT; index++)); do
80 echo "Creating tap$index"
81 ifup=`$RUNQEMU_IFUP $TUID $GID $SYSROOT 2>&1`
82 if [ $? -ne 0 ]; then
83 echo "Error running tunctl: $ifup"
84 exit 1
85 fi
86done
87
88# The runqemu script will check for this file, and if it exists,
89# will use the existing bank of tap devices without creating
90# additional ones via sudo.
91touch /etc/runqemu-nosudo
diff --git a/scripts/runqemu-ifdown b/scripts/runqemu-ifdown
new file mode 100755
index 0000000000..8f66cfa2a9
--- /dev/null
+++ b/scripts/runqemu-ifdown
@@ -0,0 +1,66 @@
1#!/bin/bash
2#
3# QEMU network configuration script to bring down tap devices. This
4# utility needs to be run as root, and will use the tunctl binary
5# from the native sysroot.
6#
7# If you find yourself calling this script a lot, you can add the
8# the following to your /etc/sudoers file to be able to run this
9# command without entering your password each time:
10#
11# <my-username> ALL=NOPASSWD: /path/to/runqemu-ifup
12# <my-username> ALL=NOPASSWD: /path/to/runqemu-ifdown
13#
14# Copyright (c) 2006-2011 Linux Foundation
15#
16# This program is free software; you can redistribute it and/or modify
17# it under the terms of the GNU General Public License version 2 as
18# published by the Free Software Foundation.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License along
26# with this program; if not, write to the Free Software Foundation, Inc.,
27# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28
29usage() {
30 echo "sudo $(basename $0) <tap-dev> <native-sysroot-basedir>"
31}
32
33if [ $EUID -ne 0 ]; then
34 echo "Error: This script (runqemu-ifdown) must be run with root privileges"
35 exit 1
36fi
37
38if [ $# -ne 2 ]; then
39 usage
40 exit 1
41fi
42
43TAP=$1
44NATIVE_SYSROOT_DIR=$2
45
46TUNCTL=$NATIVE_SYSROOT_DIR/usr/bin/tunctl
47if [ ! -e "$TUNCTL" ]; then
48 echo "Error: Unable to find tunctl binary in '$NATIVE_SYSROOT_DIR/usr/bin', please bitbake qemu-helper-native"
49 exit 1
50fi
51
52$TUNCTL -d $TAP
53
54# cleanup the remaining iptables rules
55IPTABLES=`which iptables 2> /dev/null`
56if [ "x$IPTABLES" = "x" ]; then
57 IPTABLES=/sbin/iptables
58fi
59if [ ! -x "$IPTABLES" ]; then
60 echo "$IPTABLES cannot be executed"
61 exit 1
62fi
63n=$[ (`echo $TAP | sed 's/tap//'` * 2) + 1 ]
64dest=$[ (`echo $TAP | sed 's/tap//'` * 2) + 2 ]
65$IPTABLES -D POSTROUTING -t nat -j MASQUERADE -s 192.168.7.$n/32
66$IPTABLES -D POSTROUTING -t nat -j MASQUERADE -s 192.168.7.$dest/32
diff --git a/scripts/runqemu-ifup b/scripts/runqemu-ifup
new file mode 100755
index 0000000000..b5a3db964b
--- /dev/null
+++ b/scripts/runqemu-ifup
@@ -0,0 +1,106 @@
1#!/bin/bash
2#
3# QEMU network interface configuration script. This utility needs to
4# be run as root, and will use the tunctl binary from a native sysroot.
5# Note: many Linux distros these days still use an older version of
6# tunctl which does not support the group permissions option, hence
7# the need to use build system's version.
8#
9# If you find yourself calling this script a lot, you can add the
10# the following to your /etc/sudoers file to be able to run this
11# command without entering your password each time:
12#
13# <my-username> ALL=NOPASSWD: /path/to/runqemu-ifup
14# <my-username> ALL=NOPASSWD: /path/to/runqemu-ifdown
15#
16# If you'd like to create a bank of tap devices at once, you should use
17# the runqemu-gen-tapdevs script instead. If tap devices are set up using
18# that script, the runqemu script will never end up calling this
19# script.
20#
21# Copyright (c) 2006-2011 Linux Foundation
22#
23# This program is free software; you can redistribute it and/or modify
24# it under the terms of the GNU General Public License version 2 as
25# published by the Free Software Foundation.
26#
27# This program is distributed in the hope that it will be useful,
28# but WITHOUT ANY WARRANTY; without even the implied warranty of
29# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30# GNU General Public License for more details.
31#
32# You should have received a copy of the GNU General Public License along
33# with this program; if not, write to the Free Software Foundation, Inc.,
34# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35
36usage() {
37 echo "sudo $(basename $0) <uid> <gid> <native-sysroot-basedir>"
38}
39
40if [ $EUID -ne 0 ]; then
41 echo "Error: This script (runqemu-ifup) must be run with root privileges"
42 exit 1
43fi
44
45if [ $# -ne 3 ]; then
46 usage
47 exit 1
48fi
49
50USERID="-u $1"
51GROUP="-g $2"
52NATIVE_SYSROOT_DIR=$3
53
54TUNCTL=$NATIVE_SYSROOT_DIR/usr/bin/tunctl
55if [ ! -x "$TUNCTL" ]; then
56 echo "Error: Unable to find tunctl binary in '$NATIVE_SYSROOT_DIR/usr/bin', please bitbake qemu-helper-native"
57 exit 1
58fi
59
60TAP=`$TUNCTL -b $GROUP 2>&1`
61STATUS=$?
62if [ $STATUS -ne 0 ]; then
63# If tunctl -g fails, try using tunctl -u, for older host kernels
64# which do not support the TUNSETGROUP ioctl
65 TAP=`$TUNCTL -b $USERID 2>&1`
66 STATUS=$?
67 if [ $STATUS -ne 0 ]; then
68 echo "tunctl failed:"
69 exit 1
70 fi
71fi
72
73IFCONFIG=`which ip 2> /dev/null`
74if [ "x$IFCONFIG" = "x" ]; then
75 # better than nothing...
76 IFCONFIG=/sbin/ip
77fi
78if [ ! -x "$IFCONFIG" ]; then
79 echo "$IFCONFIG cannot be executed"
80 exit 1
81fi
82
83IPTABLES=`which iptables 2> /dev/null`
84if [ "x$IPTABLES" = "x" ]; then
85 IPTABLES=/sbin/iptables
86fi
87if [ ! -x "$IPTABLES" ]; then
88 echo "$IPTABLES cannot be executed"
89 exit 1
90fi
91
92n=$[ (`echo $TAP | sed 's/tap//'` * 2) + 1 ]
93$IFCONFIG addr add 192.168.7.$n/32 broadcast 192.168.7.255 dev $TAP
94$IFCONFIG link set dev $TAP up
95
96dest=$[ (`echo $TAP | sed 's/tap//'` * 2) + 2 ]
97$IFCONFIG route add to 192.168.7.$dest dev $TAP
98
99# setup NAT for tap0 interface to have internet access in QEMU
100$IPTABLES -A POSTROUTING -t nat -j MASQUERADE -s 192.168.7.$n/32
101$IPTABLES -A POSTROUTING -t nat -j MASQUERADE -s 192.168.7.$dest/32
102echo 1 > /proc/sys/net/ipv4/ip_forward
103echo 1 > /proc/sys/net/ipv4/conf/$TAP/proxy_arp
104$IPTABLES -P FORWARD ACCEPT
105
106echo $TAP
diff --git a/scripts/runqemu-internal b/scripts/runqemu-internal
new file mode 100755
index 0000000000..d317dfd242
--- /dev/null
+++ b/scripts/runqemu-internal
@@ -0,0 +1,659 @@
1#!/bin/bash -x
2
3# Handle running OE images under qemu
4#
5# Copyright (C) 2006-2011 Linux Foundation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20# Call setting:
21# QEMU_MEMORY (optional) - set the amount of memory in the emualted system.
22# SERIAL_LOGFILE (optional) - log the serial port output to a file
23#
24# Image options:
25# MACHINE - the machine to run
26# FSTYPE - the image type to run
27# KERNEL - the kernel image file to use
28# ROOTFS - the disk image file to use
29#
30
31
32mem_size=-1
33
34#Get rid of <> and get the contents of extra qemu running params
35SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/<//' -e 's/>//'`
36#if user set qemu memory, eg: -m 256 in qemu extra params, we need to do some
37# validation check
38mem_set=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-m[[:space:]] *[0-9]*\)'`
39if [ ! -z "$mem_set" ] ; then
40#Get memory setting size from user input
41 mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'`
42else
43 case "$MACHINE" in
44 "qemux86")
45 mem_size=256
46 ;;
47 "qemux86-64")
48 mem_size=256
49 ;;
50 "qemuarm")
51 mem_size=128
52 ;;
53 "qemumicroblaze")
54 mem_size=64
55 ;;
56 "qemumips"|"qemumips64")
57 mem_size=256
58 ;;
59 "qemuppc")
60 mem_size=256
61 ;;
62 "qemush4")
63 mem_size=1024
64 ;;
65 "qemuzynq")
66 mem_size=1024
67 ;;
68 *)
69 mem_size=64
70 ;;
71 esac
72
73fi
74
75# QEMU_MEMORY has 'M' appended to mem_size
76QEMU_MEMORY="$mem_size"M
77
78# Bug 433: qemuarm cannot use > 256 MB RAM
79if [ "$MACHINE" = "qemuarm" ]; then
80 if [ -z "$mem_size" -o $mem_size -gt 256 ]; then
81 echo "WARNING: qemuarm does not support > 256M of RAM."
82 echo "Changing QEMU_MEMORY to default of 256M."
83 QEMU_MEMORY="256M"
84 mem_size="256"
85 SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e "s/$mem_set/-m 256/" `
86 fi
87fi
88
89# We need to specify -m <mem_size> to overcome a bug in qemu 0.14.0
90# https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/584480
91
92if [ -z "$mem_set" ] ; then
93 SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -m $mem_size"
94fi
95# This file is created when runqemu-gen-tapdevs creates a bank of tap
96# devices, indicating that the user should not bring up new ones using
97# sudo.
98NOSUDO_FLAG="/etc/runqemu-nosudo"
99
100QEMUIFUP=`which runqemu-ifup 2> /dev/null`
101QEMUIFDOWN=`which runqemu-ifdown 2> /dev/null`
102if [ -z "$QEMUIFUP" -o ! -x "$QEMUIFUP" ]; then
103 echo "runqemu-ifup cannot be found or executed"
104 exit 1
105fi
106if [ -z "$QEMUIFDOWN" -o ! -x "$QEMUIFDOWN" ]; then
107 echo "runqemu-ifdown cannot be found or executed"
108 exit 1
109fi
110
111NFSRUNNING="false"
112
113#capture original stty values
114ORIG_STTY=$(stty -g)
115
116if [ "$SLIRP_ENABLED" = "yes" ]; then
117 KERNEL_NETWORK_CMD="ip=dhcp"
118 QEMU_TAP_CMD=""
119 QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice wacom-tablet"
120 if [ "$KVM_ACTIVE" = "yes" ]; then
121 QEMU_NETWORK_CMD=""
122 DROOT="/dev/vda"
123 ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio"
124 else
125 QEMU_NETWORK_CMD=""
126 DROOT="/dev/hda"
127 ROOTFS_OPTIONS="-hda $ROOTFS"
128 fi
129
130else
131 acquire_lock() {
132 lockfile=$1
133 if [ -z "$lockfile" ]; then
134 echo "Error: missing lockfile arg passed to acquire_lock()"
135 return 1
136 fi
137
138 touch $lockfile.lock
139 exec 8>$lockfile.lock
140 flock -n -x 8
141 if [ $? -ne 0 ]; then
142 exec 8>&-
143 return 1
144 fi
145
146 return 0
147 }
148
149 release_lock() {
150 lockfile=$1
151 if [ -z "$lockfile" ]; then
152 echo "Error: missing lockfile arg passed to release_lock()"
153 return 1
154 fi
155
156 rm -f $lockfile.lock
157 exec 8>&-
158 }
159
160 LOCKDIR="/tmp/qemu-tap-locks"
161 if [ ! -d "$LOCKDIR" ]; then
162 mkdir $LOCKDIR
163 chmod 777 $LOCKDIR
164 fi
165
166 IFCONFIG=`which ip 2> /dev/null`
167 if [ -z "$IFCONFIG" ]; then
168 IFCONFIG=/sbin/ip
169 fi
170 if [ ! -x "$IFCONFIG" ]; then
171 echo "$IFCONFIG cannot be executed"
172 exit 1
173 fi
174
175 POSSIBLE=`$IFCONFIG link | grep 'tap' | awk '{print $2}' | sed s/://`
176 TAP=""
177 LOCKFILE=""
178 USE_PRECONF_TAP="no"
179 for tap in $POSSIBLE; do
180 LOCKFILE="$LOCKDIR/$tap"
181 if [ -e "$LOCKFILE.skip" ]; then
182 echo "Found $LOCKFILE.skip, skipping $tap"
183 continue
184 fi
185 echo "Acquiring lockfile for $tap..."
186 acquire_lock $LOCKFILE
187 if [ $? -eq 0 ]; then
188 TAP=$tap
189 USE_PRECONF_TAP="yes"
190 break
191 fi
192 done
193
194 if [ "$TAP" = "" ]; then
195 if [ -e "$NOSUDO_FLAG" ]; then
196 echo "Error: There are no available tap devices to use for networking,"
197 echo "and I see $NOSUDO_FLAG exists, so I am not going to try creating"
198 echo "a new one with sudo."
199 exit 1
200 fi
201
202 GROUPID=`id -g`
203 USERID=`id -u`
204 echo "Setting up tap interface under sudo"
205 # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded
206 # but inactive. This looks scary but is harmless
207 tap=`sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT 2> /dev/null`
208 if [ $? -ne 0 ]; then
209 # Re-run standalone to see verbose errors
210 sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT
211 return 1
212 fi
213 LOCKFILE="$LOCKDIR/$tap"
214 echo "Acquiring lockfile for $tap..."
215 acquire_lock $LOCKFILE
216 if [ $? -eq 0 ]; then
217 TAP=$tap
218 fi
219 else
220 echo "Using preconfigured tap device '$TAP'"
221 echo "If this is not intended, touch $LOCKFILE.skip to make runqemu skip $TAP."
222 fi
223
224 cleanup() {
225 if [ ! -e "$NOSUDO_FLAG" -a "$USE_PRECONF_TAP" = "no" ]; then
226 # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded
227 # but inactive. This looks scary but is harmless
228 sudo $QEMUIFDOWN $TAP $OECORE_NATIVE_SYSROOT 2> /dev/null
229 fi
230 echo "Releasing lockfile of preconfigured tap device '$TAP'"
231 release_lock $LOCKFILE
232
233 if [ "$NFSRUNNING" = "true" ]; then
234 echo "Shutting down the userspace NFS server..."
235 echo "runqemu-export-rootfs stop $ROOTFS"
236 runqemu-export-rootfs stop $ROOTFS
237 fi
238 # If QEMU crashes or somehow tty properties are not restored
239 # after qemu exits, we need to run stty sane
240 #stty sane
241
242 #instead of using stty sane we set the original stty values
243 stty ${ORIG_STTY}
244
245 }
246
247
248 n0=$(echo $TAP | sed 's/tap//')
249 n1=$(($n0 * 2 + 1))
250 n2=$(($n1 + 1))
251
252 KERNEL_NETWORK_CMD="ip=192.168.7.$n2::192.168.7.$n1:255.255.255.0"
253 QEMU_TAP_CMD="-net tap,vlan=0,ifname=$TAP,script=no,downscript=no"
254 if [ "$KVM_ACTIVE" = "yes" ]; then
255 QEMU_NETWORK_CMD="-net nic,model=virtio $QEMU_TAP_CMD,vhost=on"
256 DROOT="/dev/vda"
257 ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio"
258 else
259 QEMU_NETWORK_CMD="-net nic,vlan=0 $QEMU_TAP_CMD"
260 DROOT="/dev/hda"
261 ROOTFS_OPTIONS="-hda $ROOTFS"
262 fi
263 KERNCMDLINE="mem=$QEMU_MEMORY"
264 QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice wacom-tablet"
265
266 NFS_INSTANCE=`echo $TAP | sed 's/tap//'`
267 export NFS_INSTANCE
268
269 SERIALOPTS=""
270 if [ "x$SERIAL_LOGFILE" != "x" ]; then
271 SERIALOPTS="-serial file:$SERIAL_LOGFILE"
272 fi
273fi
274
275case "$MACHINE" in
276 "qemuarm") ;;
277 "qemumicroblaze") ;;
278 "qemumips") ;;
279 "qemumipsel") ;;
280 "qemumips64") ;;
281 "qemush4") ;;
282 "qemuppc") ;;
283 "qemuarmv6") ;;
284 "qemuarmv7") ;;
285 "qemux86") ;;
286 "qemux86-64") ;;
287 "qemuzynq") ;;
288 "akita") ;;
289 "spitz") ;;
290 *)
291 echo "Error: Unsupported machine type $MACHINE"
292 return 1
293 ;;
294esac
295
296if [ ! -f "$KERNEL" -a "x$FSTYPE" != "xvmdk" ]; then
297 echo "Error: Kernel image file $KERNEL doesn't exist"
298 cleanup
299 return 1
300fi
301
302if [ "$FSTYPE" != "nfs" -a "$FSTYPE" != "vmdk" -a ! -f "$ROOTFS" ]; then
303 echo "Error: Image file $ROOTFS doesn't exist"
304 cleanup
305 return 1
306fi
307
308if [ "$NFS_SERVER" = "" ]; then
309 NFS_SERVER="192.168.7.1"
310 if [ "$SLIRP_ENABLED" = "yes" ]; then
311 NFS_SERVER="10.0.2.2"
312 fi
313fi
314
315if [ "$FSTYPE" = "nfs" ]; then
316 NFS_DIR=`echo $ROOTFS | sed 's/^[^:]*:\(.*\)/\1/'`
317 if [ "$NFS_INSTANCE" = "" ] ; then
318 NFS_INSTANCE=0
319 fi
320 MOUNTD_RPCPORT=$[ 21111 + $NFS_INSTANCE ]
321 NFSD_RPCPORT=$[ 11111 + $NFS_INSTANCE ]
322 NFSD_PORT=$[ 3049 + 2 * $NFS_INSTANCE ]
323 MOUNTD_PORT=$[ 3048 + 2 * $NFS_INSTANCE ]
324 UNFS_OPTS="nfsvers=3,port=$NFSD_PORT,mountprog=$MOUNTD_RPCPORT,nfsprog=$NFSD_RPCPORT,udp,mountport=$MOUNTD_PORT"
325
326 PSEUDO_LOCALSTATEDIR=~/.runqemu-sdk/pseudo
327 export PSEUDO_LOCALSTATEDIR
328
329 # Start the userspace NFS server
330 echo "runqemu-export-rootfs restart $ROOTFS"
331 runqemu-export-rootfs restart $ROOTFS
332 if [ $? != 0 ]; then
333 return 1
334 fi
335 NFSRUNNING="true"
336fi
337
338if [ "$MACHINE" = "qemuarm" -o "$MACHINE" = "qemuarmv6" -o "$MACHINE" = "qemuarmv7" ]; then
339 QEMU=qemu-system-arm
340 MACHINE_SUBTYPE=versatilepb
341 export QEMU_AUDIO_DRV="none"
342 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
343 # QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -force-pointer"
344 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
345 KERNCMDLINE="root=/dev/sda rw console=ttyAMA0,115200 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY highres=off"
346 QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
347 fi
348 if [ "$FSTYPE" = "nfs" ]; then
349 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
350 echo "Error: NFS mount point $ROOTFS doesn't exist"
351 cleanup
352 return 1
353 fi
354 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
355 QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} --no-reboot $QEMU_UI_OPTIONS"
356 fi
357 if [ "$MACHINE" = "qemuarmv6" ]; then
358 QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136"
359 fi
360 if [ "$MACHINE" = "qemuarmv7" ]; then
361 QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8"
362 fi
363fi
364
365if [ "$MACHINE" = "qemux86" ]; then
366 QEMU=qemu-system-i386
367 if [ "$KVM_ACTIVE" = "yes" ]; then
368 CPU_SUBTYPE=kvm32
369 else
370 CPU_SUBTYPE=qemu32
371 fi
372 if [ ! -z "$vga_option" ]; then
373 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
374 else
375 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware"
376 fi
377 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
378 KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
379 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS"
380 fi
381 if [ "$FSTYPE" = "nfs" ]; then
382 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
383 echo "Error: NFS mount point $ROOTFS doesn't exist."
384 cleanup
385 return 1
386 fi
387 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
388 QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
389 fi
390 if [ "$FSTYPE" = "vmdk" ]; then
391 QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
392 fi
393 # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
394 # qemux86 and qemux86-64. We can use timer interrupt mode for now.
395 KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
396fi
397
398if [ "$MACHINE" = "qemux86-64" ]; then
399 QEMU=qemu-system-x86_64
400 if [ "$KVM_ACTIVE" = "yes" ]; then
401 CPU_SUBTYPE=kvm64
402 else
403 CPU_SUBTYPE=core2duo
404 fi
405 if [ ! -z "$vga_option" ]; then
406 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
407 else
408 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware"
409 fi
410 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
411 KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
412 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS"
413 fi
414 if [ "$FSTYPE" = "nfs" ]; then
415 if [ "x$ROOTFS" = "x" ]; then
416 ROOTFS=/srv/nfs/qemux86-64
417 fi
418 if [ ! -d "$ROOTFS" ]; then
419 echo "Error: NFS mount point $ROOTFS doesn't exist."
420 cleanup
421 return 1
422 fi
423 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
424 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS"
425 fi
426 if [ "$FSTYPE" = "vmdk" ]; then
427 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS"
428 fi
429 # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
430 # qemux86 and qemux86-64. We can use timer interrupt mode for now.
431 KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
432fi
433
434if [ "$MACHINE" = "spitz" ]; then
435 QEMU=qemu-system-arm
436 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
437 echo $ROOTFS
438 ROOTFS=`readlink -f $ROOTFS`
439 echo $ROOTFS
440 if [ ! -e "$ROOTFS.qemudisk" ]; then
441 echo "Adding a partition table to the ext3 image for use by QEMU, please wait..."
442 runqemu-addptable2image $ROOTFS $ROOTFS.qemudisk
443 fi
444 QEMUOPTIONS="$QEMU_NETWORK_CMD -M spitz -hda $ROOTFS.qemudisk -portrait"
445 fi
446fi
447
448if [ "$MACHINE" = "qemumips" -o "$MACHINE" = "qemumipsel" -o "$MACHINE" = "qemumips64" ]; then
449 case "$MACHINE" in
450 qemumips) QEMU=qemu-system-mips ;;
451 qemumipsel) QEMU=qemu-system-mipsel ;;
452 qemumips64) QEMU=qemu-system-mips64 ;;
453 esac
454 MACHINE_SUBTYPE=malta
455 QEMU_UI_OPTIONS="-vga cirrus $QEMU_UI_OPTIONS"
456 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
457 #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
458 KERNCMDLINE="root=/dev/hda rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
459 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
460 fi
461 if [ "$FSTYPE" = "nfs" ]; then
462 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
463 echo "Error: NFS mount point $ROOTFS doesn't exist"
464 cleanup
465 return 1
466 fi
467 KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
468 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS"
469 fi
470fi
471
472if [ "$MACHINE" = "qemuppc" ]; then
473 QEMU=qemu-system-ppc
474 MACHINE_SUBTYPE=mac99
475 CPU_SUBTYPE=G4
476 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
477 if [ "$SLIRP_ENABLED" = "yes" ]; then
478 QEMU_NETWORK_CMD=""
479 else
480 QEMU_NETWORK_CMD="-net nic,model=pcnet $QEMU_TAP_CMD"
481 fi
482 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
483 KERNCMDLINE="root=/dev/hda rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
484 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
485 fi
486 if [ "$FSTYPE" = "nfs" ]; then
487 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
488 echo "Error: NFS mount point $ROOTFS doesn't exist"
489 cleanup
490 return 1
491 fi
492 KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
493 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS"
494 fi
495fi
496
497if [ "$MACHINE" = "qemush4" ]; then
498 QEMU=qemu-system-sh4
499 MACHINE_SUBTYPE=r2d
500 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
501 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" ]; then
502 #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
503 KERNCMDLINE="root=/dev/hda rw console=ttySC1 noiotrap earlyprintk=sh-sci.1 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
504 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio"
505 SERIALSTDIO="1"
506 fi
507 if [ "$FSTYPE" = "nfs" ]; then
508 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
509 echo "Error: NFS mount point $ROOTFS doesn't exist"
510 cleanup
511 return 1
512 fi
513 KERNCMDLINE="root=/dev/nfs console=ttySC1 noiotrap earlyprintk=sh-sci.1 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
514 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio"
515 SERIALSTDIO="1"
516 fi
517fi
518
519if [ "$MACHINE" = "akita" ]; then
520 QEMU=qemu-system-arm
521 if [ "$FSTYPE" = "jffs2" ]; then
522 ROOTFS=`readlink -f $ROOTFS`
523 if [ ! -e "$ROOTFS.qemuflash" ]; then
524 echo "Converting raw image into flash image format for use by QEMU, please wait..."
525 raw2flash.akita < $ROOTFS > $ROOTFS.qemuflash
526 fi
527 QEMUOPTIONS="$QEMU_NETWORK_CMD -M akita -mtdblock $ROOTFS.qemuflash -portrait"
528 fi
529fi
530
531if [ "$MACHINE" = "qemumicroblaze" ]; then
532 QEMU=qemu-system-microblazeel
533 QEMU_SYSTEM_OPTIONS="-M petalogix-ml605 -serial mon:stdio -dtb $KERNEL-$MACHINE.dtb"
534 if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then
535 KERNCMDLINE="earlyprintk root=/dev/ram rw"
536 QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS"
537 fi
538fi
539
540if [ "$MACHINE" = "qemuzynq" ]; then
541 QEMU=qemu-system-arm
542 QEMU_SYSTEM_OPTIONS="-M xilinx-zynq-a9 -serial null -serial mon:stdio -dtb $KERNEL-$MACHINE.dtb"
543 # zynq serial ports are named 'ttyPS0' and 'ttyPS1', fixup the default values
544 SCRIPT_KERNEL_OPT=$(echo "$SCRIPT_KERNEL_OPT" | sed 's/console=ttyS/console=ttyPS/g')
545 if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then
546 KERNCMDLINE="earlyprintk root=/dev/ram rw"
547 QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS"
548 fi
549fi
550
551if [ "x$RAMFS" = "xtrue" ]; then
552 QEMUOPTIONS="-initrd $ROOTFS -nographic"
553 KERNCMDLINE="root=/dev/ram0 debugshell"
554fi
555
556if [ "x$ISOFS" = "xtrue" ]; then
557 QEMUOPTIONS="$QEMU_NETWORK_CMD -cdrom $ROOTFS $QEMU_UI_OPTIONS"
558fi
559
560if [ "x$QEMUOPTIONS" = "x" ]; then
561 echo "Error: Unable to support this combination of options"
562 cleanup
563 return 1
564fi
565
566PATH=$OECORE_NATIVE_SYSROOT/usr/bin:$PATH
567
568QEMUBIN=`which $QEMU 2> /dev/null`
569if [ ! -x "$QEMUBIN" ]; then
570 echo "Error: No QEMU binary '$QEMU' could be found."
571 cleanup
572 return 1
573fi
574
575NEED_GL=`ldd $QEMUBIN/$QEMU 2>&1 | grep libGLU`
576# We can't run without a libGL.so
577if [ "$NEED_GL" != "" ]; then
578 libgl='no'
579
580 [ -e /usr/lib/libGL.so -a -e /usr/lib/libGLU.so ] && libgl='yes'
581 [ -e /usr/lib64/libGL.so -a -e /usr/lib64/libGLU.so ] && libgl='yes'
582 [ -e /usr/lib/*-linux-gnu/libGL.so -a -e /usr/lib/*-linux-gnu/libGLU.so ] && libgl='yes'
583
584 if [ "$libgl" != 'yes' ]; then
585 echo "You need libGL.so and libGLU.so to exist in your library path to run the QEMU emulator.
586 Ubuntu package names are: libgl1-mesa-dev and libglu1-mesa-dev.
587 Fedora package names are: mesa-libGL-devel mesa-libGLU-devel."
588 return 1;
589 fi
590fi
591
592do_quit() {
593 cleanup
594 return 1
595}
596
597trap do_quit INT TERM QUIT
598
599# qemu got segfault if linked with nVidia's libgl
600GL_LD_PRELOAD=$LD_PRELOAD
601
602if ldd $QEMUBIN | grep -i nvidia &> /dev/null
603then
604cat << EOM
605WARNING: nVidia proprietary OpenGL libraries detected.
606nVidia's OpenGL libraries are known to have compatibility issues with qemu,
607resulting in a segfault. Please uninstall these drivers or ensure the mesa libGL
608libraries precede nvidia's via LD_PRELOAD(Already do it on Ubuntu 10).
609EOM
610
611# Automatically use Ubuntu system's mesa libGL, other distro can add its own path
612if grep -i ubuntu /etc/lsb-release &> /dev/null
613then
614 # precede nvidia's driver on Ubuntu 10
615 UBUNTU_MAIN_VERSION=`cat /etc/lsb-release |grep DISTRIB_RELEASE |cut -d= -f 2| cut -d. -f 1`
616 if [ "$UBUNTU_MAIN_VERSION" = "10" ];
617 then
618 GL_PATH=""
619 if test -e /usr/lib/libGL.so
620 then
621 GL_PATH="/usr/lib/libGL.so"
622 elif test -e /usr/lib/x86_64-linux-gnu/libGL.so
623 then
624 GL_PATH="/usr/lib/x86_64-linux-gnu/libGL.so"
625 fi
626
627 echo "Skip nVidia's libGL on Ubuntu 10!"
628 GL_LD_PRELOAD="$GL_PATH $LD_PRELOAD"
629 fi
630fi
631fi
632
633if [ "x$SERIALSTDIO" = "x1" ]; then
634 echo "Interrupt character is '^]'"
635 stty intr ^]
636fi
637
638echo "Running $QEMU..."
639# -no-reboot is a mandatory option - see bug #100
640if [ "$FSTYPE" = "vmdk" ]; then
641 echo $QEMUBIN $VM $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT
642 LD_PRELOAD="$GL_LD_PRELOAD" $QEMUBIN $VM $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT
643elif [ "$FSTYPE" = "iso" ]; then
644 echo $QEMUBIN $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT
645 LD_PRELOAD="$GL_LD_PRELOAD" $QEMUBIN $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT
646else
647 echo $QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SLIRP_CMD $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT --append '"'$KERNCMDLINE $SCRIPT_KERNEL_OPT'"'
648 LD_PRELOAD="$GL_LD_PRELOAD" $QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT --append "$KERNCMDLINE $SCRIPT_KERNEL_OPT"
649fi
650ret=$?
651if [ "$SLIRP_ENABLED" != "yes" ]; then
652 cleanup
653fi
654
655#set the original stty values before exit
656stty ${ORIG_STTY}
657trap - INT TERM QUIT
658
659return $ret
diff --git a/scripts/runqemu.README b/scripts/runqemu.README
new file mode 100644
index 0000000000..5908d831a4
--- /dev/null
+++ b/scripts/runqemu.README
@@ -0,0 +1,42 @@
1Using OE images with QEMU
2=========================
3
4OE-Core can generate qemu bootable kernels and images with can be used
5on a desktop system. The scripts currently support booting ARM, MIPS, PowerPC
6and x86 (32 and 64 bit) images. The scripts can be used within the OE build
7system or externaly.
8
9The runqemu script is run as:
10
11 runqemu <machine> <zimage> <filesystem>
12
13where:
14
15 <machine> is the machine/architecture to use (qemuarm/qemumips/qemuppc/qemux86/qemux86-64)
16 <zimage> is the path to a kernel (e.g. zimage-qemuarm.bin)
17 <filesystem> is the path to an ext2 image (e.g. filesystem-qemuarm.ext2) or an nfs directory
18
19If <machine> isn't specified, the script will try to detect the machine name
20from the name of the <zimage> file.
21
22If <filesystem> isn't specified, nfs booting will be assumed.
23
24When used within the build system, it will default to qemuarm, ext2 and the last kernel and
25core-image-sato-sdk image built by the build system. If an sdk image isn't present it will look
26for sato and minimal images.
27
28Full usage instructions can be seen by running the command with no options specified.
29
30
31Notes
32=====
33
34 - The scripts run qemu using sudo. Change perms on /dev/net/tun to
35 run as non root. The runqemu-gen-tapdevs script can also be used by
36 root to prepopulate the appropriate network devices.
37 - You can access the host computer at 192.168.7.1 within the image.
38 - Your qemu system will be accessible as 192.16.7.2.
39 - The script extracts the root filesystem specified under pseudo and sets up a userspace
40 NFS server to share the image over by default meaning the filesystem can be accessed by
41 both the host and guest systems.
42
diff --git a/scripts/send-error-report b/scripts/send-error-report
new file mode 100755
index 0000000000..d23ae27dda
--- /dev/null
+++ b/scripts/send-error-report
@@ -0,0 +1,80 @@
1#!/usr/bin/env python
2
3# Sends an error report (if the report-error class was enabled) to a remote server.
4#
5# Copyright (C) 2013 Intel Corporation
6# Author: Andreea Proca <andreea.b.proca@intel.com>
7
8
9
10import httplib, urllib, os, sys, json
11
12
13def sendData(json_file, server):
14
15 if os.path.isfile(json_file):
16
17 home = os.path.expanduser("~")
18 userfile = os.path.join(home, ".oe-send-error")
19 if os.path.isfile(userfile):
20 with open(userfile) as g:
21 username = g.readline()
22 email = g.readline()
23 else:
24 print("Please enter your name and your email (optionally), they'll be saved in the file you send.")
25 username = raw_input("Name: ")
26 email = raw_input("E-mail (not required): ")
27 if len(username) > 0 and len(username) < 50:
28 with open(userfile, "w") as g:
29 g.write(username + "\n")
30 g.write(email + "\n")
31 else:
32 print("Invalid inputs, try again.")
33 return
34
35 with open(json_file) as f:
36 data = f.read()
37
38 try:
39 jsondata = json.loads(data)
40 jsondata['username'] = username.strip()
41 jsondata['email'] = email.strip()
42 data = json.dumps(jsondata, indent=4, sort_keys=True)
43 except:
44 print("Invalid json data")
45 return
46
47 try:
48 params = urllib.urlencode({'data': data})
49 headers = {"Content-type": "application/json"}
50 conn = httplib.HTTPConnection(server)
51 conn.request("POST", "/ClientPost/", params, headers)
52 response = conn.getresponse()
53 print response.status, response.reason
54 res = response.read()
55 if response.status == 200:
56 print(res)
57 else:
58 print("There was a problem submiting your data, response written in %s.response.html" % json_file)
59 with open("%s.response.html" % json_file, "w") as f:
60 f.write(res)
61 conn.close()
62 except:
63 print("Server connection failed")
64
65 else:
66 print("No data file found.")
67
68
69if __name__ == '__main__':
70 print ("\nSends an error report (if the report-error class was enabled) to a remote server.")
71 if len(sys.argv) < 2:
72 print("\nThis scripts sends the contents of a file to an upstream server.")
73 print("\nUsage: send-error-report <error_fileName> [server]")
74 print("\nIf this is the first when sending a report you'll be asked for your name and optionally your email address.")
75 print("They will be associated with your report.\n")
76
77 elif len(sys.argv) == 3:
78 sendData(sys.argv[1], sys.argv[2])
79 else:
80 sendData(sys.argv[1], "errors.yoctoproject.org")
diff --git a/scripts/send-pull-request b/scripts/send-pull-request
new file mode 100755
index 0000000000..575549db38
--- /dev/null
+++ b/scripts/send-pull-request
@@ -0,0 +1,179 @@
1#!/bin/bash
2#
3# Copyright (c) 2010-2011, Intel Corporation.
4# All Rights Reserved
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14# the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19#
20
21#
22# This script is intended to be used to send a patch series prepared by the
23# create-pull-request script to Open Embedded and The Yocto Project, as well
24# as to related projects and layers.
25#
26
27AUTO=0
28AUTO_CL=0
29GITSOBCC="--suppress-cc=all"
30
31# Prevent environment leakage to these vars.
32unset TO
33unset CC
34unset AUTO_CC
35unset EXTRA_CC
36
37usage()
38{
39cat <<EOM
40Usage: $(basename $0) [-h] [-a] [-c] [[-t email]...] -p pull-dir
41 -a Send the cover letter to every recipient listed in Cc and
42 Signed-off-by lines found in the cover letter and the patches.
43 This option implies -c.
44 -c Expand the Cc list for the individual patches using the Cc and
45 Signed-off-by lines from the same patch.
46 -C Add extra CC to each email sent.
47 -p pull-dir Directory containing summary and patch files
48 -t email Explicitly add email to the recipients
49EOM
50}
51
52# Collect addresses from a patch into AUTO_CC
53# $1: a patch file
54harvest_recipients()
55{
56 PATCH=$1
57 export IFS=$',\n'
58 for REGX in "^[Cc][Cc]: *" "^[Ss]igned-[Oo]ff-[Bb]y: *"; do
59 for EMAIL in $(sed '/^---$/q' $PATCH | grep -e "$REGX" | sed "s/$REGX//"); do
60 if [ "${AUTO_CC/$EMAIL/}" == "$AUTO_CC" ] && [ -n "$EMAIL" ]; then
61 if [ -z "$AUTO_CC" ]; then
62 AUTO_CC=$EMAIL;
63 else
64 AUTO_CC="$AUTO_CC,$EMAIL";
65 fi
66 fi
67 done
68 done
69 unset IFS
70}
71
72# Parse and verify arguments
73while getopts "acC:hp:t:" OPT; do
74 case $OPT in
75 a)
76 AUTO=1
77 GITSOBCC="--signed-off-by-cc"
78 AUTO_CL=1
79 ;;
80 c)
81 AUTO=1
82 GITSOBCC="--signed-off-by-cc"
83 ;;
84 C)
85 EXTRA_CC="$OPTARG"
86 ;;
87 h)
88 usage
89 exit 0
90 ;;
91 p)
92 PDIR=${OPTARG%/}
93 if [ ! -d $PDIR ]; then
94 echo "ERROR: pull-dir \"$PDIR\" does not exist."
95 usage
96 exit 1
97 fi
98 ;;
99 t)
100 if [ -n "$TO" ]; then
101 TO="$TO,$OPTARG"
102 else
103 TO="$OPTARG"
104 fi
105 ;;
106 esac
107done
108
109if [ -z "$PDIR" ]; then
110 echo "ERROR: you must specify a pull-dir."
111 usage
112 exit 1
113fi
114
115
116# Verify the cover letter is complete and free of tokens
117if [ -e $PDIR/0000-cover-letter.patch ]; then
118 CL="$PDIR/0000-cover-letter.patch"
119 for TOKEN in SUBJECT BLURB; do
120 grep -q "*** $TOKEN HERE ***" "$CL"
121 if [ $? -eq 0 ]; then
122 echo "ERROR: Please edit $CL and try again (Look for '*** $TOKEN HERE ***')."
123 exit 1
124 fi
125 done
126else
127 echo "WARNING: No cover letter will be sent."
128fi
129
130# Harvest emails from the generated patches and populate AUTO_CC.
131if [ $AUTO_CL -eq 1 ]; then
132 for PATCH in $PDIR/*.patch; do
133 harvest_recipients $PATCH
134 done
135fi
136
137AUTO_TO="$(git config sendemail.to)"
138if [ -n "$AUTO_TO" ]; then
139 if [ -n "$TO" ]; then
140 TO="$TO,$AUTO_TO"
141 else
142 TO="$AUTO_TO"
143 fi
144fi
145
146if [ -z "$TO" ] && [ -z "$AUTO_CC" ]; then
147 echo "ERROR: you have not specified any recipients."
148 usage
149 exit 1
150fi
151
152
153# Convert the collected addresses into git-send-email argument strings
154export IFS=$','
155GIT_TO=$(for R in $TO; do echo -n "--to='$R' "; done)
156GIT_CC=$(for R in $AUTO_CC; do echo -n "--cc='$R' "; done)
157GIT_EXTRA_CC=$(for R in $EXTRA_CC; do echo -n "--cc='$R' "; done)
158unset IFS
159
160# Handoff to git-send-email. It will perform the send confirmation.
161PATCHES=$(echo $PDIR/*.patch)
162if [ $AUTO_CL -eq 1 ]; then
163 # Send the cover letter to every recipient, both specified as well as
164 # harvested. Then remove it from the patches list.
165 eval "git send-email $GIT_TO $GIT_CC $GIT_EXTRA_CC --confirm=always --no-chain-reply-to --suppress-cc=all $CL"
166 if [ $? -eq 1 ]; then
167 echo "ERROR: failed to send cover-letter with automatic recipients."
168 exit 1
169 fi
170 PATCHES=${PATCHES/"$CL"/}
171fi
172
173# Send the patch to the specified recipients and, if -c was specified, those git
174# finds in this specific patch.
175eval "git send-email $GIT_TO $GIT_EXTRA_CC --confirm=always --no-chain-reply-to $GITSOBCC $PATCHES"
176if [ $? -eq 1 ]; then
177 echo "ERROR: failed to send patches."
178 exit 1
179fi
diff --git a/scripts/sstate-cache-management.sh b/scripts/sstate-cache-management.sh
new file mode 100755
index 0000000000..e5c57d318d
--- /dev/null
+++ b/scripts/sstate-cache-management.sh
@@ -0,0 +1,469 @@
1#!/bin/bash
2
3# Copyright (c) 2012 Wind River Systems, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12# See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#
18
19# Global vars
20cache_dir=
21confirm=
22fsym=
23total_deleted=0
24verbose=
25debug=0
26
27usage () {
28 cat << EOF
29Welcome to sstate cache management utilities.
30sstate-cache-management.sh <OPTION>
31
32Options:
33 -h, --help
34 Display this help and exit.
35
36 --cache-dir=<sstate cache dir>
37 Specify sstate cache directory, will use the environment
38 variable SSTATE_CACHE_DIR if it is not specified.
39
40 --extra-archs=<arch1>,<arch2>...<archn>
41 Specify list of architectures which should be tested, this list
42 will be extended with native arch, allarch and empty arch. The
43 script won't be trying to generate list of available archs from
44 AVAILTUNES in tune files.
45
46 --extra-layer=<layer1>,<layer2>...<layern>
47 Specify the layer which will be used for searching the archs,
48 it will search the meta and meta-* layers in the top dir by
49 default, and will search meta, meta-*, <layer1>, <layer2>,
50 ...<layern> when specified. Use "," as the separator.
51
52 This is useless for --stamps-dir or when --extra-archs is used.
53
54 -d, --remove-duplicated
55 Remove the duplicated sstate cache files of one package, only
56 the newest one will be kept. The duplicated sstate cache files
57 of one package must have the same arch, which means sstate cache
58 files with multiple archs are not considered duplicate.
59
60 Conflicts with --stamps-dir.
61
62 --stamps-dir=<dir1>,<dir2>...<dirn>
63 Specify the build directory's stamps directories, the sstate
64 cache file which IS USED by these build diretories will be KEPT,
65 other sstate cache files in cache-dir will be removed. Use ","
66 as the separator. For example:
67 --stamps-dir=build1/tmp/stamps,build2/tmp/stamps
68
69 Conflicts with --remove-duplicated.
70
71 -L, --follow-symlink
72 Rmove both the symbol link and the destination file, default: no.
73
74 -y, --yes
75 Automatic yes to prompts; assume "yes" as answer to all prompts
76 and run non-interactively.
77
78 -v, --verbose
79 explain what is being done
80
81 -D, --debug
82 show debug info, repeat for more debug info
83
84EOF
85}
86
87if [ $# -lt 1 ]; then
88 usage
89 exit 0
90fi
91
92# Echo no files to remove
93no_files () {
94 echo No files to remove
95}
96
97# Echo nothing to do
98do_nothing () {
99 echo Nothing to do
100}
101
102# Read the input "y"
103read_confirm () {
104 echo "$total_deleted from $total_files files will be removed! "
105 if [ "$confirm" != "y" ]; then
106 echo "Do you want to continue (y/n)? "
107 while read confirm; do
108 [ "$confirm" = "Y" -o "$confirm" = "y" -o "$confirm" = "n" \
109 -o "$confirm" = "N" ] && break
110 echo "Invalid input \"$confirm\", please input 'y' or 'n': "
111 done
112 else
113 echo
114 fi
115}
116
117# Print error information and exit.
118echo_error () {
119 echo "ERROR: $1" >&2
120 exit 1
121}
122
123# Generate the remove list:
124#
125# * Add .done/.siginfo to the remove list
126# * Add destination of symlink to the remove list
127#
128# $1: output file, others: sstate cache file (.tgz)
129gen_rmlist (){
130 local rmlist_file="$1"
131 shift
132 local files="$@"
133 for i in $files; do
134 echo $i >> $rmlist_file
135 # Add the ".siginfo"
136 if [ -e $i.siginfo ]; then
137 echo $i.siginfo >> $rmlist_file
138 fi
139 # Add the destination of symlink
140 if [ -L "$i" ]; then
141 if [ "$fsym" = "y" ]; then
142 dest="`readlink -e $i`"
143 if [ -n "$dest" ]; then
144 echo $dest >> $rmlist_file
145 # Remove the .siginfo when .tgz is removed
146 if [ -f "$dest.siginfo" ]; then
147 echo $dest.siginfo >> $rmlist_file
148 fi
149 fi
150 fi
151 # Add the ".tgz.done" and ".siginfo.done" (may exist in the future)
152 base_fn="${i##/*/}"
153 t_fn="$base_fn.done"
154 s_fn="$base_fn.siginfo.done"
155 for d in $t_fn $s_fn; do
156 if [ -f $cache_dir/$d ]; then
157 echo $cache_dir/$d >> $rmlist_file
158 fi
159 done
160 fi
161 done
162}
163
164# Remove the duplicated cache files for the pkg, keep the newest one
165remove_duplicated () {
166
167 local topdir
168 local oe_core_dir
169 local tunedirs
170 local all_archs
171 local all_machines
172 local ava_archs
173 local arch
174 local file_names
175 local sstate_files_list
176 local fn_tmp
177 local list_suffix=`mktemp` || exit 1
178
179 if [ -z "$extra_archs" ] ; then
180 # Find out the archs in all the layers
181 echo "Figuring out the archs in the layers ... "
182 oe_core_dir=$(dirname $(dirname $(readlink -e $0)))
183 topdir=$(dirname $oe_core_dir)
184 tunedirs="`find $topdir/meta* ${oe_core_dir}/meta* $layers -path '*/meta*/conf/machine/include' 2>/dev/null`"
185 [ -n "$tunedirs" ] || echo_error "Can't find the tune directory"
186 all_machines="`find $topdir/meta* ${oe_core_dir}/meta* $layers -path '*/meta*/conf/machine/*' -name '*.conf' 2>/dev/null | sed -e 's/.*\///' -e 's/.conf$//'`"
187 all_archs=`grep -r -h "^AVAILTUNES .*=" $tunedirs | sed -e 's/.*=//' -e 's/\"//g'`
188 fi
189
190 # Use the "_" to substitute "-", e.g., x86-64 to x86_64, but not for extra_archs which can be something like cortexa9t2-vfp-neon
191 # Sort to remove the duplicated ones
192 # Add allarch and builder arch (native)
193 builder_arch=$(uname -m)
194 all_archs="$(echo allarch $all_archs $all_machines $builder_arch \
195 | sed -e 's/-/_/g' -e 's/ /\n/g' | sort -u) $extra_archs"
196 echo "Done"
197
198 # Total number of files including sstate-, .siginfo and .done files
199 total_files=`find $cache_dir -name 'sstate*' | wc -l`
200 # Save all the sstate files in a file
201 sstate_files_list=`mktemp` || exit 1
202 find $cache_dir -name 'sstate:*:*:*:*:*:*:*.tgz*' >$sstate_files_list
203
204 echo "Figuring out the suffixes in the sstate cache dir ... "
205 sstate_suffixes="`sed 's%.*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^_]*_\([^:]*\)\.tgz.*%\1%g' $sstate_files_list | sort -u`"
206 echo "Done"
207 echo "The following suffixes have been found in the cache dir:"
208 echo $sstate_suffixes
209
210 echo "Figuring out the archs in the sstate cache dir ... "
211 # Using this SSTATE_PKGSPEC definition it's 6th colon separated field
212 # SSTATE_PKGSPEC = "sstate:${PN}:${PACKAGE_ARCH}${TARGET_VENDOR}-${TARGET_OS}:${PV}:${PR}:${SSTATE_PKGARCH}:${SSTATE_VERSION}:"
213 for arch in $all_archs; do
214 grep -q ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.tgz$" $sstate_files_list
215 [ $? -eq 0 ] && ava_archs="$ava_archs $arch"
216 # ${builder_arch}_$arch used by toolchain sstate
217 grep -q ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:${builder_arch}_$arch:[^:]*:[^:]*\.tgz$" $sstate_files_list
218 [ $? -eq 0 ] && ava_archs="$ava_archs ${builder_arch}_$arch"
219 done
220 echo "Done"
221 echo "The following archs have been found in the cache dir:"
222 echo $ava_archs
223 echo ""
224
225 # Save the file list which needs to be removed
226 local remove_listdir=`mktemp -d` || exit 1
227 for suffix in $sstate_suffixes; do
228 if [ "$suffix" = "populate_lic" ] ; then
229 echo "Skipping populate_lic, because removing duplicates doesn't work correctly for them (use --stamps-dir instead)"
230 continue
231 fi
232 # Total number of files including .siginfo and .done files
233 total_files_suffix=`grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tgz.*" $sstate_files_list | wc -l 2>/dev/null`
234 total_tgz_suffix=`grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tgz$" $sstate_files_list | wc -l 2>/dev/null`
235 # Save the file list to a file, some suffix's file may not exist
236 grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:_]*_$suffix\.tgz.*" $sstate_files_list >$list_suffix 2>/dev/null
237 local deleted_tgz=0
238 local deleted_files=0
239 for ext in tgz tgz.siginfo tgz.done; do
240 echo "Figuring out the sstate:xxx_$suffix.$ext ... "
241 # Uniq BPNs
242 file_names=`for arch in $ava_archs ""; do
243 sed -ne "s%.*/sstate:\([^:]*\):[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.${ext}$%\1%p" $list_suffix
244 done | sort -u`
245
246 fn_tmp=`mktemp` || exit 1
247 rm_list="$remove_listdir/sstate:xxx_$suffix"
248 for fn in $file_names; do
249 [ -z "$verbose" ] || echo "Analyzing sstate:$fn-xxx_$suffix.${ext}"
250 for arch in $ava_archs ""; do
251 grep -h ".*/sstate:$fn:[^:]*:[^:]*:[^:]*:$arch:[^:]*:[^:]*\.${ext}$" $list_suffix >$fn_tmp
252 if [ -s $fn_tmp ] ; then
253 [ $debug -gt 1 ] && echo "Available files for $fn-$arch- with suffix $suffix.${ext}:" && cat $fn_tmp
254 # Use the modification time
255 to_del=$(ls -t $(cat $fn_tmp) | sed -n '1!p')
256 [ $debug -gt 2 ] && echo "Considering to delete: $to_del"
257 # The sstate file which is downloaded from the SSTATE_MIRROR is
258 # put in SSTATE_DIR, and there is a symlink in SSTATE_DIR/??/ to
259 # it, so filter it out from the remove list if it should not be
260 # removed.
261 to_keep=$(ls -t $(cat $fn_tmp) | sed -n '1p')
262 [ $debug -gt 2 ] && echo "Considering to keep: $to_keep"
263 for k in $to_keep; do
264 if [ -L "$k" ]; then
265 # The symlink's destination
266 k_dest="`readlink -e $k`"
267 # Maybe it is the one in cache_dir
268 k_maybe="$cache_dir/${k##/*/}"
269 # Remove it from the remove list if they are the same.
270 if [ "$k_dest" = "$k_maybe" ]; then
271 to_del="`echo $to_del | sed 's#'\"$k_maybe\"'##g'`"
272 fi
273 fi
274 done
275 rm -f $fn_tmp
276 [ $debug -gt 2 ] && echo "Decided to delete: $to_del"
277 gen_rmlist $rm_list.$ext "$to_del"
278 fi
279 done
280 done
281 done
282 deleted_tgz=`cat $rm_list.* 2>/dev/null | grep ".tgz$" | wc -l`
283 deleted_files=`cat $rm_list.* 2>/dev/null | wc -l`
284 [ "$deleted_files" -gt 0 -a $debug -gt 0 ] && cat $rm_list.*
285 echo "($deleted_tgz from $total_tgz_suffix .tgz files for $suffix suffix will be removed or $deleted_files from $total_files_suffix when counting also .siginfo and .done files)"
286 let total_deleted=$total_deleted+$deleted_files
287 done
288 deleted_tgz=0
289 rm_old_list=$remove_listdir/sstate-old-filenames
290 find $cache_dir -name 'sstate-*.tgz' >$rm_old_list
291 [ -s "$rm_old_list" ] && deleted_tgz=`cat $rm_old_list | grep ".tgz$" | wc -l`
292 [ -s "$rm_old_list" ] && deleted_files=`cat $rm_old_list | wc -l`
293 [ -s "$rm_old_list" -a $debug -gt 0 ] && cat $rm_old_list
294 echo "($deleted_tgz .tgz files with old sstate-* filenames will be removed or $deleted_files when counting also .siginfo and .done files)"
295 let total_deleted=$total_deleted+$deleted_files
296
297 rm -f $list_suffix
298 rm -f $sstate_files_list
299 if [ $total_deleted -gt 0 ]; then
300 read_confirm
301 if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
302 for list in `ls $remove_listdir/`; do
303 echo "Removing $list.tgz (`cat $remove_listdir/$list | wc -w` files) ... "
304 # Remove them one by one to avoid the argument list too long error
305 for i in `cat $remove_listdir/$list`; do
306 rm -f $verbose $i
307 done
308 echo "Done"
309 done
310 echo "$total_deleted files have been removed!"
311 else
312 do_nothing
313 fi
314 else
315 no_files
316 fi
317 [ -d $remove_listdir ] && rm -fr $remove_listdir
318}
319
320# Remove the sstate file by stamps dir, the file not used by the stamps dir
321# will be removed.
322rm_by_stamps (){
323
324 local cache_list=`mktemp` || exit 1
325 local keep_list=`mktemp` || exit 1
326 local rm_list=`mktemp` || exit 1
327 local sums
328 local all_sums
329
330 # Total number of files including sstate-, .siginfo and .done files
331 total_files=`find $cache_dir -type f -name 'sstate*' | wc -l`
332 # Save all the state file list to a file
333 find $cache_dir -type f -name 'sstate*' | sort -u -o $cache_list
334
335 echo "Figuring out the suffixes in the sstate cache dir ... "
336 local sstate_suffixes="`sed 's%.*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^_]*_\([^:]*\)\.tgz.*%\1%g' $cache_list | sort -u`"
337 echo "Done"
338 echo "The following suffixes have been found in the cache dir:"
339 echo $sstate_suffixes
340
341 # Figure out all the md5sums in the stamps dir.
342 echo "Figuring out all the md5sums in stamps dir ... "
343 for i in $sstate_suffixes; do
344 # There is no "\.sigdata" but "_setcene" when it is mirrored
345 # from the SSTATE_MIRRORS, use them to figure out the sum.
346 sums=`find $stamps -maxdepth 3 -name "*.do_$i.*" \
347 -o -name "*.do_${i}_setscene.*" | \
348 sed -ne 's#.*_setscene\.##p' -e 's#.*\.sigdata\.##p' | \
349 sed -e 's#\..*##' | sort -u`
350 all_sums="$all_sums $sums"
351 done
352 echo "Done"
353
354 echo "Figuring out the files which will be removed ... "
355 for i in $all_sums; do
356 grep ".*/sstate:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:${i}_.*" $cache_list >>$keep_list
357 done
358 echo "Done"
359
360 if [ -s $keep_list ]; then
361 sort -u $keep_list -o $keep_list
362 to_del=`comm -1 -3 $keep_list $cache_list`
363 gen_rmlist $rm_list "$to_del"
364 let total_deleted=`cat $rm_list | sort -u | wc -w`
365 if [ $total_deleted -gt 0 ]; then
366 [ $debug -gt 0 ] && cat $rm_list | sort -u
367 read_confirm
368 if [ "$confirm" = "y" -o "$confirm" = "Y" ]; then
369 echo "Removing sstate cache files ... ($total_deleted files)"
370 # Remove them one by one to avoid the argument list too long error
371 for i in `cat $rm_list | sort -u`; do
372 rm -f $verbose $i
373 done
374 echo "$total_deleted files have been removed"
375 else
376 do_nothing
377 fi
378 else
379 no_files
380 fi
381 else
382 echo_error "All files in cache dir will be removed! Abort!"
383 fi
384
385 rm -f $cache_list
386 rm -f $keep_list
387 rm -f $rm_list
388}
389
390# Parse arguments
391while [ -n "$1" ]; do
392 case $1 in
393 --cache-dir=*)
394 cache_dir=`echo $1 | sed -e 's#^--cache-dir=##' | xargs readlink -e`
395 [ -d "$cache_dir" ] || echo_error "Invalid argument to --cache-dir"
396 shift
397 ;;
398 --remove-duplicated|-d)
399 rm_duplicated="y"
400 shift
401 ;;
402 --yes|-y)
403 confirm="y"
404 shift
405 ;;
406 --follow-symlink|-L)
407 fsym="y"
408 shift
409 ;;
410 --extra-archs=*)
411 extra_archs=`echo $1 | sed -e 's#^--extra-archs=##' -e 's#,# #g'`
412 [ -n "$extra_archs" ] || echo_error "Invalid extra arch parameter"
413 shift
414 ;;
415 --extra-layer=*)
416 extra_layers=`echo $1 | sed -e 's#^--extra-layer=##' -e 's#,# #g'`
417 [ -n "$extra_layers" ] || echo_error "Invalid extra layer parameter"
418 for i in $extra_layers; do
419 l=`readlink -e $i`
420 if [ -d "$l" ]; then
421 layers="$layers $l"
422 else
423 echo_error "Can't find layer $i"
424 fi
425 done
426 shift
427 ;;
428 --stamps-dir=*)
429 stamps=`echo $1 | sed -e 's#^--stamps-dir=##' -e 's#,# #g'`
430 [ -n "$stamps" ] || echo_error "Invalid stamps dir $i"
431 for i in $stamps; do
432 [ -d "$i" ] || echo_error "Invalid stamps dir $i"
433 done
434 shift
435 ;;
436 --verbose|-v)
437 verbose="-v"
438 shift
439 ;;
440 --debug|-D)
441 debug=`expr $debug + 1`
442 echo "Debug level $debug"
443 shift
444 ;;
445 --help|-h)
446 usage
447 exit 0
448 ;;
449 *)
450 echo "Invalid arguments $*"
451 echo_error "Try 'sstate-cache-management.sh -h' for more information."
452 ;;
453 esac
454done
455
456# sstate cache directory, use environment variable SSTATE_CACHE_DIR
457# if it was not specified, otherwise, error.
458[ -n "$cache_dir" ] || cache_dir=$SSTATE_CACHE_DIR
459[ -n "$cache_dir" ] || echo_error "No cache dir found!"
460[ -d "$cache_dir" ] || echo_error "Invalid cache directory \"$cache_dir\""
461
462[ -n "$rm_duplicated" -a -n "$stamps" ] && \
463 echo_error "Can not use both --remove-duplicated and --stamps-dir"
464
465[ "$rm_duplicated" = "y" ] && remove_duplicated
466[ -n "$stamps" ] && rm_by_stamps
467[ -z "$rm_duplicated" -a -z "$stamps" ] && \
468 echo "What do you want to do?"
469exit 0
diff --git a/scripts/sstate-diff-machines.sh b/scripts/sstate-diff-machines.sh
new file mode 100755
index 0000000000..860be73679
--- /dev/null
+++ b/scripts/sstate-diff-machines.sh
@@ -0,0 +1,107 @@
1#!/bin/sh
2
3# Used to compare sstate checksums between MACHINES
4# Execute script and compare generated list.M files
5
6# It's also usefull to keep older sstate checksums
7# to be able to find out why something is rebuilding
8# after updating metadata
9
10# $ diff \
11# sstate-diff/1349348392/fake-cortexa8/list.M \
12# sstate-diff/1349348392/fake-cortexa9/list.M \
13# | wc -l
14# 538
15
16# Then to compare sigdata use something like:
17# $ ls sstate-diff/1349348392/*/armv7a-vfp-neon*/linux-libc-headers/*do_configure*sigdata*
18# sstate-diff/1349348392/fake-cortexa8/armv7a-vfp-neon-oe-linux-gnueabi/linux-libc-headers/3.4.3-r0.do_configure.sigdata.cb73b3630a7b8191e72fc469c5137025
19# sstate-diff/1349348392/fake-cortexa9/armv7a-vfp-neon-oe-linux-gnueabi/linux-libc-headers/3.4.3-r0.do_configure.sigdata.f37ada177bf99ce8af85914df22b5a0b
20# $ bitbake-diffsigs stamps.1349348392/*/armv7a-vfp-neon*/linux-libc-headers/*do_configure*sigdata*
21# basehash changed from 8d0bd67bb1da6f68717760fc3ef43171 to e869fa61426e88e9c30726ba88a1216a
22# Variable TUNE_CCARGS value changed from -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -mtune=cortex-a8 to -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -mtune=cortex-a9
23
24# Global vars
25tmpdir=
26machines=
27targets=
28default_machines="qemuarm qemux86 qemux86-64"
29default_targets="core-image-base"
30
31usage () {
32 cat << EOF
33Welcome to utility to compare sstate checksums between different MACHINEs.
34$0 <OPTION>
35
36Options:
37 -h, --help
38 Display this help and exit.
39
40 --tmpdir=<tmpdir>
41 Specify tmpdir, will use the environment variable TMPDIR if it is not specified.
42 Something like /OE/oe-core/tmp-eglibc (no / at the end).
43
44 --machines=<machines>
45 List of MACHINEs separated by space, will use the environment variable MACHINES if it is not specified.
46 Default value is "qemuarm qemux86 qemux86-64".
47
48 --targets=<targets>
49 List of targets separated by space, will use the environment variable TARGETS if it is not specified.
50 Default value is "core-image-base".
51EOF
52}
53
54# Print error information and exit.
55echo_error () {
56 echo "ERROR: $1" >&2
57 exit 1
58}
59
60while [ -n "$1" ]; do
61 case $1 in
62 --tmpdir=*)
63 tmpdir=`echo $1 | sed -e 's#^--tmpdir=##' | xargs readlink -e`
64 [ -d "$tmpdir" ] || echo_error "Invalid argument to --tmpdir"
65 shift
66 ;;
67 --machines=*)
68 machines=`echo $1 | sed -e 's#^--machines="*\([^"]*\)"*#\1#'`
69 shift
70 ;;
71 --targets=*)
72 targets=`echo $1 | sed -e 's#^--targets="*\([^"]*\)"*#\1#'`
73 shift
74 ;;
75 --help|-h)
76 usage
77 exit 0
78 ;;
79 *)
80 echo "Invalid arguments $*"
81 echo_error "Try '$0 -h' for more information."
82 ;;
83 esac
84done
85
86# tmpdir directory, use environment variable TMPDIR
87# if it was not specified, otherwise, error.
88[ -n "$tmpdir" ] || tmpdir=$TMPDIR
89[ -n "$tmpdir" ] || echo_error "No tmpdir found!"
90[ -d "$tmpdir" ] || echo_error "Invalid tmpdir \"$tmpdir\""
91[ -n "$machines" ] || machines=$MACHINES
92[ -n "$machines" ] || machines=$default_machines
93[ -n "$targets" ] || targets=$TARGETS
94[ -n "$targets" ] || targets=$default_targets
95
96OUTPUT=${tmpdir}/sstate-diff/`date "+%s"`
97
98for M in ${machines}; do
99 find ${tmpdir}/stamps/ -name \*sigdata\* | xargs rm -f
100 mkdir -p ${OUTPUT}/${M}
101 export MACHINE=${M}; bitbake -S none ${targets} | tee -a ${OUTPUT}/${M}/log;
102 cp -ra ${tmpdir}/stamps/* ${OUTPUT}/${M}
103 find ${OUTPUT}/${M} -name \*sigdata\* | sed "s#${OUTPUT}/${M}/##g" | sort > ${OUTPUT}/${M}/list
104 M_UNDERSCORE=`echo ${M} | sed 's/-/_/g'`
105 sed "s/${M_UNDERSCORE}/MACHINE/g; s/${M}/MACHINE/g" ${OUTPUT}/${M}/list | sort > ${OUTPUT}/${M}/list.M
106 find ${tmpdir}/stamps/ -name \*sigdata\* | xargs rm -f
107done
diff --git a/scripts/sstate-sysroot-cruft.sh b/scripts/sstate-sysroot-cruft.sh
new file mode 100755
index 0000000000..ca2316cdcc
--- /dev/null
+++ b/scripts/sstate-sysroot-cruft.sh
@@ -0,0 +1,78 @@
1#!/bin/sh
2
3# Used to find files installed in sysroot which are not tracked by sstate manifest
4
5# Global vars
6tmpdir=
7
8usage () {
9 cat << EOF
10Welcome to sysroot cruft finding utility.
11$0 <OPTION>
12
13Options:
14 -h, --help
15 Display this help and exit.
16
17 --tmpdir=<tmpdir>
18 Specify tmpdir, will use the environment variable TMPDIR if it is not specified.
19 Something like /OE/oe-core/tmp-eglibc (no / at the end).
20EOF
21}
22
23# Print error information and exit.
24echo_error () {
25 echo "ERROR: $1" >&2
26 exit 1
27}
28
29while [ -n "$1" ]; do
30 case $1 in
31 --tmpdir=*)
32 tmpdir=`echo $1 | sed -e 's#^--tmpdir=##' | xargs readlink -e`
33 [ -d "$tmpdir" ] || echo_error "Invalid argument to --tmpdir"
34 shift
35 ;;
36 --help|-h)
37 usage
38 exit 0
39 ;;
40 *)
41 echo "Invalid arguments $*"
42 echo_error "Try '$0 -h' for more information."
43 ;;
44 esac
45done
46
47# sstate cache directory, use environment variable TMPDIR
48# if it was not specified, otherwise, error.
49[ -n "$tmpdir" ] || tmpdir=$TMPDIR
50[ -n "$tmpdir" ] || echo_error "No tmpdir found!"
51[ -d "$tmpdir" ] || echo_error "Invalid tmpdir \"$tmpdir\""
52
53OUTPUT=${tmpdir}/sysroot.cruft.`date "+%s"`
54WHITELIST="\/var\/pseudo\($\|\/[^\/]*$\) \/shlibs$ \.pyc$ \.pyo$"
55
56mkdir ${OUTPUT}
57find ${tmpdir}/sstate-control -name \*.populate-sysroot\* -o -name \*.package\* | xargs cat | grep sysroots | \
58 sed 's#/$##g; s#///*#/#g' | \
59 # work around for paths ending with / for directories and multiplied // (e.g. paths to native sysroot)
60 sort > ${OUTPUT}/master.list.all
61sort -u ${OUTPUT}/master.list.all > ${OUTPUT}/master.list # -u because some directories are listed for more recipes
62find ${tmpdir}/sysroots/ | \
63 sort > ${OUTPUT}/sysroot.list
64
65diff ${OUTPUT}/master.list.all ${OUTPUT}/master.list > ${OUTPUT}/duplicates
66diff ${OUTPUT}/master.list ${OUTPUT}/sysroot.list > ${OUTPUT}/diff.all
67
68cp ${OUTPUT}/diff.all ${OUTPUT}/diff
69for item in ${WHITELIST}; do
70 sed -i "/${item}/d" ${OUTPUT}/diff;
71done
72
73# too many false positives for directories
74# echo "Following files are installed in sysroot at least twice"
75# cat ${OUTPUT}/duplicates
76
77echo "Following files are installed in sysroot, but not tracked by sstate"
78cat ${OUTPUT}/diff
diff --git a/scripts/swabber-strace-attach b/scripts/swabber-strace-attach
new file mode 100755
index 0000000000..bb0391a7ca
--- /dev/null
+++ b/scripts/swabber-strace-attach
@@ -0,0 +1,31 @@
1#!/usr/bin/env python
2import os
3import sys
4import subprocess
5
6# Detach from the controlling terminal and parent process by forking twice to daemonize ourselves,
7# then run the command passed as argv[1]. Send log data to argv[2].
8
9pid = os.fork()
10if (pid == 0):
11 os.setsid()
12 pid = os.fork()
13 if (pid != 0):
14 os._exit(0)
15else:
16 sys.exit()
17
18
19si = file(os.devnull, 'r')
20so = file(sys.argv[2], 'w')
21se = so
22
23# Replace those fds with our own
24os.dup2(si.fileno(), sys.stdin.fileno())
25os.dup2(so.fileno(), sys.stdout.fileno())
26os.dup2(se.fileno(), sys.stderr.fileno())
27
28ret = subprocess.call(sys.argv[1], shell=True)
29
30os._exit(ret)
31
diff --git a/scripts/sysroot-relativelinks.py b/scripts/sysroot-relativelinks.py
new file mode 100755
index 0000000000..ac26367e77
--- /dev/null
+++ b/scripts/sysroot-relativelinks.py
@@ -0,0 +1,31 @@
1#!/usr/bin/env python
2import sys
3import os
4
5# Take a sysroot directory and turn all the abolute symlinks and turn them into
6# relative ones such that the sysroot is usable within another system.
7
8if len(sys.argv) != 2:
9 print("Usage is " + sys.argv[0] + "<directory>")
10 sys.exit(1)
11
12topdir = sys.argv[1]
13topdir = os.path.abspath(topdir)
14
15def handlelink(filep, subdir):
16 link = os.readlink(filep)
17 if link[0] != "/":
18 return
19 if link.startswith(topdir):
20 return
21 #print("Replacing %s with %s for %s" % (link, topdir+link, filep))
22 print("Replacing %s with %s for %s" % (link, os.path.relpath(topdir+link, subdir), filep))
23 os.unlink(filep)
24 os.symlink(os.path.relpath(topdir+link, subdir), filep)
25
26for subdir, dirs, files in os.walk(topdir):
27 for f in files:
28 filep = os.path.join(subdir, f)
29 if os.path.islink(filep):
30 #print("Considering %s" % filep)
31 handlelink(filep, subdir)
diff --git a/scripts/test-dependencies.sh b/scripts/test-dependencies.sh
new file mode 100755
index 0000000000..d3212c4f49
--- /dev/null
+++ b/scripts/test-dependencies.sh
@@ -0,0 +1,256 @@
1#!/bin/sh
2
3# Author: Martin Jansa <martin.jansa@gmail.com>
4#
5# Copyright (c) 2013 Martin Jansa <Martin.Jansa@gmail.com>
6
7# Used to detect missing dependencies or automagically
8# enabled dependencies which aren't explicitly enabled
9# or disabled.
10
11# It does 3 builds of <target>
12# 1st to populate sstate-cache directory and sysroot
13# 2nd to rebuild each recipe with every possible
14# dependency found in sysroot (which stays populated
15# from 1st build
16# 3rd to rebuild each recipe only with dependencies defined
17# in DEPENDS
18# 4th (optional) repeat build like 3rd to make sure that
19# minimal versions of dependencies defined in DEPENDS
20# is also enough
21
22# Global vars
23tmpdir=
24targets=
25recipes=
26buildhistory=
27buildtype=
28default_targets="world"
29default_buildhistory="buildhistory"
30default_buildtype="1 2 3 c"
31
32usage () {
33 cat << EOF
34Welcome to utility to detect missing or autoenabled dependencies.
35WARNING: this utility will completely remove your tmpdir (make sure
36 you don't have important buildhistory or persistent dir there).
37$0 <OPTION>
38
39Options:
40 -h, --help
41 Display this help and exit.
42
43 --tmpdir=<tmpdir>
44 Specify tmpdir, will use the environment variable TMPDIR if it is not specified.
45 Something like /OE/oe-core/tmp-eglibc (no / at the end).
46
47 --targets=<targets>
48 List of targets separated by space, will use the environment variable TARGETS if it is not specified.
49 It will run "bitbake <targets>" to populate sysroots.
50 Default value is "world".
51
52 --recipes=<recipes>
53 File with list of recipes we want to rebuild with minimal and maximal sysroot.
54 Will use the environment variable RECIPES if it is not specified.
55 Default value will use all packages ever recorded in buildhistory directory.
56
57 --buildhistory=<buildhistory>
58 Path to buildhistory directory, it needs to be enabled in your config,
59 because it's used to detect different dependencies and to create list
60 of recipes to rebuild when it's not specified.
61 Will use the environment variable BUILDHISTORY if it is not specified.
62 Default value is "buildhistory"
63
64 --buildtype=<buildtype>
65 There are 4 types of build:
66 1: build to populate sstate-cache directory and sysroot
67 2: build to rebuild each recipe with every possible dep
68 3: build to rebuild each recipe with minimal dependencies
69 4: build to rebuild each recipe again with minimal dependencies
70 c: compare buildhistory directories from build 2 and 3
71 Will use the environment variable BUILDTYPE if it is not specified.
72 Default value is "1 2 3 c", order is important, type 4 is optional.
73EOF
74}
75
76# Print error information and exit.
77echo_error () {
78 echo "ERROR: $1" >&2
79 exit 1
80}
81
82while [ -n "$1" ]; do
83 case $1 in
84 --tmpdir=*)
85 tmpdir=`echo $1 | sed -e 's#^--tmpdir=##' | xargs readlink -e`
86 [ -d "$tmpdir" ] || echo_error "Invalid argument to --tmpdir"
87 shift
88 ;;
89 --targets=*)
90 targets=`echo $1 | sed -e 's#^--targets="*\([^"]*\)"*#\1#'`
91 shift
92 ;;
93 --recipes=*)
94 recipes=`echo $1 | sed -e 's#^--recipes="*\([^"]*\)"*#\1#'`
95 shift
96 ;;
97 --buildhistory=*)
98 buildhistory=`echo $1 | sed -e 's#^--buildhistory="*\([^"]*\)"*#\1#'`
99 shift
100 ;;
101 --buildtype=*)
102 buildtype=`echo $1 | sed -e 's#^--buildtype="*\([^"]*\)"*#\1#'`
103 shift
104 ;;
105 --help|-h)
106 usage
107 exit 0
108 ;;
109 *)
110 echo "Invalid arguments $*"
111 echo_error "Try '$0 -h' for more information."
112 ;;
113 esac
114done
115
116# tmpdir directory, use environment variable TMPDIR
117# if it was not specified, otherwise, error.
118[ -n "$tmpdir" ] || tmpdir=$TMPDIR
119[ -n "$tmpdir" ] || echo_error "No tmpdir found!"
120[ -d "$tmpdir" ] || echo_error "Invalid tmpdir \"$tmpdir\""
121[ -n "$targets" ] || targets=$TARGETS
122[ -n "$targets" ] || targets=$default_targets
123[ -n "$recipes" ] || recipes=$RECIPES
124[ -n "$recipes" -a ! -f "$recipes" ] && echo_error "Invalid file with list of recipes to rebuild"
125[ -n "$recipes" ] || echo "All packages ever recorded in buildhistory directory will be rebuilt"
126[ -n "$buildhistory" ] || buildhistory=$BUILDHISTORY
127[ -n "$buildhistory" ] || buildhistory=$default_buildhistory
128[ -d "$buildhistory" ] || echo_error "Invalid buildhistory directory \"$buildhistory\""
129[ -n "$buildtype" ] || buildtype=$BUILDTYPE
130[ -n "$buildtype" ] || buildtype=$default_buildtype
131echo "$buildtype" | grep -v '^[1234c ]*$' && echo_error "Invalid buildtype \"$buildtype\", only some combination of 1, 2, 3, 4, c separated by space is allowed"
132
133OUTPUT_BASE=test-dependencies/`date "+%s"`
134
135build_all() {
136 echo "===== 1st build to populate sstate-cache directory and sysroot ====="
137 OUTPUT1=${OUTPUT_BASE}/${TYPE}_all
138 mkdir -p ${OUTPUT1}
139 echo "Logs will be stored in ${OUTPUT1} directory"
140 bitbake -k $targets 2>&1 | tee -a ${OUTPUT1}/complete.log
141}
142
143build_every_recipe() {
144 if [ "${TYPE}" = "2" ] ; then
145 echo "===== 2nd build to rebuild each recipe with every possible dep ====="
146 OUTPUT_MAX=${OUTPUT_BASE}/${TYPE}_max
147 OUTPUTB=${OUTPUT_MAX}
148 else
149 echo "===== 3rd or 4th build to rebuild each recipe with minimal dependencies ====="
150 OUTPUT_MIN=${OUTPUT_BASE}/${TYPE}_min
151 OUTPUTB=${OUTPUT_MIN}
152 fi
153
154 mkdir -p ${OUTPUTB} ${OUTPUTB}/failed ${OUTPUTB}/ok
155 echo "Logs will be stored in ${OUTPUTB} directory"
156 if [ -z "$recipes" ]; then
157 ls -d $buildhistory/packages/*/* | xargs -n 1 basename | sort -u > ${OUTPUTB}/recipe.list
158 recipes=${OUTPUTB}/recipe.list
159 fi
160 if [ "${TYPE}" != "2" ] ; then
161 echo "!!!Removing tmpdir \"$tmpdir\"!!!"
162 rm -rf $tmpdir/deploy $tmpdir/pkgdata $tmpdir/sstate-control $tmpdir/stamps $tmpdir/sysroots $tmpdir/work $tmpdir/work-shared 2>/dev/null
163 fi
164 i=1
165 count=`cat $recipes | wc -l`
166 for recipe in `cat $recipes`; do
167 echo "Building recipe: ${recipe} ($i/$count)"
168 bitbake -c cleansstate ${recipe} > ${OUTPUTB}/log.${recipe} 2>&1;
169 bitbake ${recipe} >> ${OUTPUTB}/log.${recipe} 2>&1;
170 grep "ERROR: Task.*failed" ${OUTPUTB}/log.${recipe} && mv ${OUTPUTB}/log.${recipe} ${OUTPUTB}/failed/${recipe} || mv ${OUTPUTB}/log.${recipe} ${OUTPUTB}/ok/${recipe}
171 if [ "${TYPE}" != "2" ] ; then
172 rm -rf $tmpdir/deploy $tmpdir/pkgdata $tmpdir/sstate-control $tmpdir/stamps $tmpdir/sysroots $tmpdir/work $tmpdir/work-shared 2>/dev/null
173 fi
174 i=`expr $i + 1`
175 done
176 echo "Copying buildhistory/packages to ${OUTPUTB}"
177 cp -ra $buildhistory/packages ${OUTPUTB}
178 # This will be usefull to see which library is pulling new dependency
179 echo "Copying do_package logs to ${OUTPUTB}/do_package/"
180 mkdir ${OUTPUTB}/do_package
181 find $tmpdir/work/ -name log.do_package 2>/dev/null| while read f; do
182 # pn is 3 levels back, but we don't know if there is just one log per pn (only one arch and version)
183 # dest=`echo $f | sed 's#^.*/\([^/]*\)/\([^/]*\)/\([^/]*\)/log.do_package#\1#g'`
184 dest=`echo $f | sed "s#$tmpdir/work/##g; s#/#_#g"`
185 cp $f ${OUTPUTB}/do_package/$dest
186 done
187 grep "ERROR: Task.*failed" ${OUTPUTB}/failed/* 2>/dev/null
188 ls -1 ${OUTPUTB}/failed/* >> ${OUTPUT_BASE}/failed.recipes 2>/dev/null
189}
190
191compare_deps() {
192 # you can run just compare task with command like this
193 # OUTPUT_BASE=test-dependencies/1373140172 \
194 # OUTPUT_MAX=${OUTPUT_BASE}/2_max \
195 # OUTPUT_MIN=${OUTPUT_BASE}/3_min \
196 # openembedded-core/scripts/test-dependencies.sh --tmpdir=tmp-eglibc --targets=glib-2.0 --recipes=recipe_list --buildtype=c
197 echo "===== Compare dependencies recorded in \"${OUTPUT_MAX}\" and \"${OUTPUT_MIN}\" ====="
198 [ -n "${OUTPUTC}" ] || OUTPUTC=${OUTPUT_BASE}
199 mkdir -p ${OUTPUTC}
200 OUTPUT_FILE=${OUTPUTC}/dependency-changes
201 echo "Differences will be stored in ${OUTPUT_FILE}, dot is shown for every 100 of checked packages"
202 echo > ${OUTPUT_FILE}
203
204 [ -d ${OUTPUT_MAX} ] || echo_error "Directory with output from build 2 \"${OUTPUT_MAX}\" does not exist"
205 [ -d ${OUTPUT_MIN} ] || echo_error "Directory with output from build 3 \"${OUTPUT_MIN}\" does not exist"
206 [ -d ${OUTPUT_MAX}/packages/ ] || echo_error "Directory with packages from build 2 \"${OUTPUT_MAX}/packages/\" does not exist"
207 [ -d ${OUTPUT_MIN}/packages/ ] || echo_error "Directory with packages from build 3 \"${OUTPUT_MIN}/packages/\" does not exist"
208 i=0
209 find ${OUTPUT_MAX}/packages/ -name latest | sed "s#${OUTPUT_MAX}/##g" | while read pkg; do
210 max_pkg=${OUTPUT_MAX}/${pkg}
211 min_pkg=${OUTPUT_MIN}/${pkg}
212 if [ ! -f "${min_pkg}" ] ; then
213 echo "ERROR: ${min_pkg} doesn't exist" | tee -a ${OUTPUT_FILE}
214 continue
215 fi
216 # strip version information in parenthesis
217 max_deps=`grep "^RDEPENDS = " ${max_pkg} | sed 's/^RDEPENDS = / /g; s/$/ /g; s/([^(]*)//g'`
218 min_deps=`grep "^RDEPENDS = " ${min_pkg} | sed 's/^RDEPENDS = / /g; s/$/ /g; s/([^(]*)//g'`
219 if [ "$i" = 100 ] ; then
220 echo -n "." # cheap progressbar
221 i=0
222 fi
223 if [ "${max_deps}" = "${min_deps}" ] ; then
224 # it's annoying long, but at least it's showing some progress, warnings are grepped at the end
225 echo "NOTE: ${pkg} dependencies weren't changed" >> ${OUTPUT_FILE}
226 else
227 missing_deps=
228 for dep in ${max_deps}; do
229 echo "${min_deps}" | grep -q " ${dep} " || missing_deps="${missing_deps} ${dep}"
230 done
231 if [ -n "${missing_deps}" ] ; then
232 echo # to get rid of dots on last line
233 echo "WARN: ${pkg} lost dependency on ${missing_deps}" | tee -a ${OUTPUT_FILE}
234 fi
235 fi
236 i=`expr $i + 1`
237 done
238 echo # to get rid of dots on last line
239 echo "Found differences: "
240 grep "^WARN: " ${OUTPUT_FILE} | tee ${OUTPUT_FILE}.warn
241 echo "Found errors: "
242 grep "^ERROR: " ${OUTPUT_FILE} | tee ${OUTPUT_FILE}.error
243 # useful for reexecuting this script with only small subset of recipes with known issues
244 sed 's#.*[ /]packages/\([^/]*\)/\([^/]*\)/.*#\2#g' ${OUTPUT_FILE}.warn ${OUTPUT_FILE}.error | sort -u >> ${OUTPUT_BASE}/failed.recipes
245}
246
247for TYPE in $buildtype; do
248 case ${TYPE} in
249 1) build_all;;
250 2) build_every_recipe;;
251 3) build_every_recipe;;
252 4) build_every_recipe;;
253 c) compare_deps;;
254 *) echo_error "Invalid buildtype \"$TYPE\""
255 esac
256done
diff --git a/scripts/test-reexec b/scripts/test-reexec
new file mode 100755
index 0000000000..9eaa96e754
--- /dev/null
+++ b/scripts/test-reexec
@@ -0,0 +1,123 @@
1#!/bin/bash
2
3# Test Script for task re-execution
4#
5# Copyright 2012 Intel Corporation
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21#
22# DESCRIPTION
23# This script is intended to address issues for re-execution of
24# tasks. The test results are saved in ./reexeclogs. Force build
25# logs are saved with prefix "force". Build failure logs are saved with
26# prefix "failed". Log files with prefix "initial" are used to save
27# initial build logs for each recipe. Log files with prefix "clean" are
28# used to save logs of clean task after testing for a recipe is finished.
29#
30
31targets=`bitbake -s | cut -d " " -f 1`
32
33LOGS=./reexeclogs
34
35mkdir -p $LOGS
36
37# Clear sstate files for specified recipe
38function clearsstate {
39 target=$1
40
41 sstate_dir=`bitbake $target -e | grep "^SSTATE_DIR" | cut -d "\"" -f 2`
42 sstate_pkgspec=`bitbake $target -e | grep "^SSTATE_PKGSPEC" | cut -d "\"" -f 2`
43 sstasks=`bitbake $target -e | grep "^SSTATETASKS" | cut -d "\"" -f 2`
44
45 for sstask in $sstasks
46 do
47 sstask=${sstask:3}
48 case $sstask in
49 populate_sysroot) sstask="populate-sysroot"
50 ;;
51 populate_lic) sstask="populate-lic"
52 ;;
53 package_write_ipk) sstask="deploy-ipk"
54 ;;
55 package_write_deb) sstask="deploy-deb"
56 ;;
57 package_write_rpm) sstask="deploy-rpm"
58 ;;
59 package) sstask="package"
60 ;;
61 deploy) sstask="deploy"
62 ;;
63 *)
64 ;;
65 esac
66
67 echo "Removing ${sstate_dir}/${sstate_pkgspec}*_${sstask}.tgz* for $target"
68 rm -rf ${sstate_dir}/${sstate_pkgspec}*_${sstask}.tgz*
69 done
70}
71
72# Function to re-execute specified task of recipe
73function testit {
74 target=$1
75 task=$2
76
77 task=`echo $task | sed 's/_setscene//'`
78
79 if [ -f $LOGS/force.$target.$task ]; then
80 return
81 fi
82
83 case $task in
84 clean|build|cleansstate|cleanall|package|cleansstate2|package_write|package_write_ipk|package_write_rpm|package_write_deb|fetch|populate_lic) return;;
85 fetchall|devshell|buildall|listtasks|checkuri|checkuriall) return;;
86 esac
87
88 echo "Attempting target $target, task $task"
89 echo "Initial build"
90 bitbake $target -c cleansstate > $LOGS/initial.$target.$task
91 bitbake $target >> $LOGS/initial.$target.$task
92 clearsstate $target >> $LOGS/initial.$target.$task
93 echo "Re-execution build"
94 bitbake $target -c $task -f > $LOGS/force.$target.$task
95 if [ "$?" != 0 ]; then
96 echo "FAILURE for $target $task"
97 cp $LOGS/force.$target.$task $LOGS/failed.$target.$task
98 bitbake $target -c clean > $LOGS/clean.$target.$task
99 else
100 bitbake $target >> $LOGS/force.$target.$task
101 if [ "$?" != 0 ]; then
102 echo "FAILURE2 for $target $task"
103 cp $LOGS/force.$target.$task $LOGS/failed.$target.$task
104 bitbake $target -c clean > $LOGS/clean.$target.$task
105 fi
106 fi
107 echo "Done"
108}
109
110# Go through the recipe list and these recipes' task list
111# Then re-execute them
112for target in $targets; do
113 # Remove log messages from bitbake output
114 case $target in
115 Summary*|WARNING*|Loading*|Loaded*|Package*|=====*) continue;;
116 esac
117 tasks=`bitbake $target -c listtasks | grep ^do_ | sed s/do_//`
118 for task in $tasks; do
119 testit $target $task
120 done
121done
122
123
diff --git a/scripts/tiny/dirsize.py b/scripts/tiny/dirsize.py
new file mode 100755
index 0000000000..40ff4ab895
--- /dev/null
+++ b/scripts/tiny/dirsize.py
@@ -0,0 +1,93 @@
1#!/usr/bin/env python
2#
3# Copyright (c) 2011, Intel Corporation.
4# All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20#
21# Display details of the root filesystem size, broken up by directory.
22# Allows for limiting by size to focus on the larger files.
23#
24# Author: Darren Hart <dvhart@linux.intel.com>
25#
26
27import os
28import sys
29import stat
30
31class Record:
32 def create(path):
33 r = Record(path)
34
35 s = os.lstat(path)
36 if stat.S_ISDIR(s.st_mode):
37 for p in os.listdir(path):
38 pathname = path + "/" + p
39 ss = os.lstat(pathname)
40 if not stat.S_ISLNK(ss.st_mode):
41 r.records.append(Record.create(pathname))
42 r.size += r.records[-1].size
43 r.records.sort(reverse=True)
44 else:
45 r.size = os.lstat(path).st_size
46
47 return r
48 create = staticmethod(create)
49
50 def __init__(self, path):
51 self.path = path
52 self.size = 0
53 self.records = []
54
55 def __cmp__(this, that):
56 if that is None:
57 return 1
58 if not isinstance(that, Record):
59 raise TypeError
60 if len(this.records) > 0 and len(that.records) == 0:
61 return -1
62 if len(this.records) == 0 and len(that.records) > 0:
63 return 1
64 if this.size < that.size:
65 return -1
66 if this.size > that.size:
67 return 1
68 return 0
69
70 def show(self, minsize):
71 total = 0
72 if self.size <= minsize:
73 return 0
74 print "%10d %s" % (self.size, self.path)
75 for r in self.records:
76 total += r.show(minsize)
77 if len(self.records) == 0:
78 total = self.size
79 return total
80
81
82def main():
83 minsize = 0
84 if len(sys.argv) == 2:
85 minsize = int(sys.argv[1])
86 rootfs = Record.create(".")
87 total = rootfs.show(minsize)
88 print "Displayed %d/%d bytes (%.2f%%)" % \
89 (total, rootfs.size, 100 * float(total) / rootfs.size)
90
91
92if __name__ == "__main__":
93 main()
diff --git a/scripts/tiny/ksize.py b/scripts/tiny/ksize.py
new file mode 100755
index 0000000000..4006f2f6f1
--- /dev/null
+++ b/scripts/tiny/ksize.py
@@ -0,0 +1,165 @@
1#!/usr/bin/env python
2#
3# Copyright (c) 2011, Intel Corporation.
4# All rights reserved.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19#
20#
21# Display details of the kernel build size, broken up by built-in.o. Sort
22# the objects by size. Run from the top level kernel build directory.
23#
24# Author: Darren Hart <dvhart@linux.intel.com>
25#
26
27import sys
28import getopt
29import os
30from subprocess import *
31from string import join
32
33
34def usage():
35 prog = os.path.basename(sys.argv[0])
36 print 'Usage: %s [OPTION]...' % (prog)
37 print ' -d, display an additional level of drivers detail'
38 print ' -h, --help display this help and exit'
39 print ''
40 print 'Run %s from the top-level Linux kernel build directory.' % (prog)
41
42
43class Sizes:
44 def __init__(self, glob):
45 self.title = glob
46 p = Popen("size -t " + glob, shell=True, stdout=PIPE, stderr=PIPE)
47 output = p.communicate()[0].splitlines()
48 if len(output) > 2:
49 sizes = output[-1].split()[0:4]
50 self.text = int(sizes[0])
51 self.data = int(sizes[1])
52 self.bss = int(sizes[2])
53 self.total = int(sizes[3])
54 else:
55 self.text = self.data = self.bss = self.total = 0
56
57 def show(self, indent=""):
58 print "%-32s %10d | %10d %10d %10d" % \
59 (indent+self.title, self.total, self.text, self.data, self.bss)
60
61
62class Report:
63 def create(filename, title, subglob=None):
64 r = Report(filename, title)
65 path = os.path.dirname(filename)
66
67 p = Popen("ls " + path + "/*.o | grep -v built-in.o",
68 shell=True, stdout=PIPE, stderr=PIPE)
69 glob = join(p.communicate()[0].splitlines())
70 oreport = Report(glob, path + "/*.o")
71 oreport.sizes.title = path + "/*.o"
72 r.parts.append(oreport)
73
74 if subglob:
75 p = Popen("ls " + subglob, shell=True, stdout=PIPE, stderr=PIPE)
76 for f in p.communicate()[0].splitlines():
77 path = os.path.dirname(f)
78 r.parts.append(Report.create(f, path, path + "/*/built-in.o"))
79 r.parts.sort(reverse=True)
80
81 for b in r.parts:
82 r.totals["total"] += b.sizes.total
83 r.totals["text"] += b.sizes.text
84 r.totals["data"] += b.sizes.data
85 r.totals["bss"] += b.sizes.bss
86
87 r.deltas["total"] = r.sizes.total - r.totals["total"]
88 r.deltas["text"] = r.sizes.text - r.totals["text"]
89 r.deltas["data"] = r.sizes.data - r.totals["data"]
90 r.deltas["bss"] = r.sizes.bss - r.totals["bss"]
91 return r
92 create = staticmethod(create)
93
94 def __init__(self, glob, title):
95 self.glob = glob
96 self.title = title
97 self.sizes = Sizes(glob)
98 self.parts = []
99 self.totals = {"total":0, "text":0, "data":0, "bss":0}
100 self.deltas = {"total":0, "text":0, "data":0, "bss":0}
101
102 def show(self, indent=""):
103 rule = str.ljust(indent, 80, '-')
104 print "%-32s %10s | %10s %10s %10s" % \
105 (indent+self.title, "total", "text", "data", "bss")
106 print rule
107 self.sizes.show(indent)
108 print rule
109 for p in self.parts:
110 if p.sizes.total > 0:
111 p.sizes.show(indent)
112 print rule
113 print "%-32s %10d | %10d %10d %10d" % \
114 (indent+"sum", self.totals["total"], self.totals["text"],
115 self.totals["data"], self.totals["bss"])
116 print "%-32s %10d | %10d %10d %10d" % \
117 (indent+"delta", self.deltas["total"], self.deltas["text"],
118 self.deltas["data"], self.deltas["bss"])
119 print "\n"
120
121 def __cmp__(this, that):
122 if that is None:
123 return 1
124 if not isinstance(that, Report):
125 raise TypeError
126 if this.sizes.total < that.sizes.total:
127 return -1
128 if this.sizes.total > that.sizes.total:
129 return 1
130 return 0
131
132
133def main():
134 try:
135 opts, args = getopt.getopt(sys.argv[1:], "dh", ["help"])
136 except getopt.GetoptError, err:
137 print '%s' % str(err)
138 usage()
139 sys.exit(2)
140
141 driver_detail = False
142 for o, a in opts:
143 if o == '-d':
144 driver_detail = True
145 elif o in ('-h', '--help'):
146 usage()
147 sys.exit(0)
148 else:
149 assert False, "unhandled option"
150
151 glob = "arch/*/built-in.o */built-in.o"
152 vmlinux = Report.create("vmlinux", "Linux Kernel", glob)
153
154 vmlinux.show()
155 for b in vmlinux.parts:
156 if b.totals["total"] > 0 and len(b.parts) > 1:
157 b.show()
158 if b.title == "drivers" and driver_detail:
159 for d in b.parts:
160 if d.totals["total"] > 0 and len(d.parts) > 1:
161 d.show(" ")
162
163
164if __name__ == "__main__":
165 main()
diff --git a/scripts/wic b/scripts/wic
new file mode 100755
index 0000000000..6d239fa0fc
--- /dev/null
+++ b/scripts/wic
@@ -0,0 +1,302 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (c) 2013, Intel Corporation.
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# DESCRIPTION 'wic' is the OpenEmbedded Image Creator that users can
22# use to generate bootable images. Invoking it without any arguments
23# will display help screens for the 'wic' command and list the
24# available 'wic' subcommands. Invoking a subcommand without any
25# arguments will likewise display help screens for the specified
26# subcommand. Please use that interface for detailed help.
27#
28# AUTHORS
29# Tom Zanussi <tom.zanussi (at] linux.intel.com>
30#
31
32__version__ = "0.1.0"
33
34# Python Standard Library modules
35import os
36import sys
37import optparse
38import logging
39
40# External modules
41scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
42lib_path = scripts_path + '/lib'
43sys.path = sys.path + [lib_path]
44
45from image.help import *
46from image.engine import *
47
48def rootfs_dir_to_args(krootfs_dir):
49 """
50 Get a rootfs_dir dict and serialize to string
51 """
52 rootfs_dir = ''
53 for k, v in krootfs_dir.items():
54 rootfs_dir += ' '
55 rootfs_dir += '='.join([k, v])
56 return rootfs_dir.strip()
57
58def callback_rootfs_dir(option, opt, value, parser):
59 """
60 Build a dict using --rootfs_dir connection=dir
61 """
62 if not type(parser.values.rootfs_dir) is dict:
63 parser.values.rootfs_dir = dict()
64
65 if '=' in value:
66 (key, rootfs_dir) = value.split('=')
67 else:
68 key = 'ROOTFS_DIR'
69 rootfs_dir = value
70
71 parser.values.rootfs_dir[key] = rootfs_dir
72
73def wic_create_subcommand(args, usage_str):
74 """
75 Command-line handling for image creation. The real work is done
76 by image.engine.wic_create()
77 """
78 parser = optparse.OptionParser(usage = usage_str)
79
80 parser.add_option("-o", "--outdir", dest = "outdir",
81 action = "store", help = "name of directory to create image in")
82 parser.add_option("-i", "--infile", dest = "properties_file",
83 action = "store", help = "name of file containing the values for image properties as a JSON file")
84 parser.add_option("-e", "--image-name", dest = "image_name",
85 action = "store", help = "name of the image to use the artifacts from e.g. core-image-sato")
86 parser.add_option("-r", "--rootfs-dir", dest = "rootfs_dir",
87 action = "callback", callback = callback_rootfs_dir, type = "string",
88 help = "path to the /rootfs dir to use as the .wks rootfs source")
89 parser.add_option("-b", "--bootimg-dir", dest = "bootimg_dir",
90 action = "store", help = "path to the dir containing the boot artifacts (e.g. /EFI or /syslinux dirs) to use as the .wks bootimg source")
91 parser.add_option("-k", "--kernel-dir", dest = "kernel_dir",
92 action = "store", help = "path to the dir containing the kernel to use in the .wks bootimg")
93 parser.add_option("-n", "--native-sysroot", dest = "native_sysroot",
94 action = "store", help = "path to the native sysroot containing the tools to use to build the image")
95 parser.add_option("-p", "--skip-build-check", dest = "build_check",
96 action = "store_false", default = True, help = "skip the build check")
97 parser.add_option("-D", "--debug", dest = "debug", action = "store_true",
98 default = False, help = "output debug information")
99
100 (options, args) = parser.parse_args(args)
101
102 if options.debug:
103 loglevel = logging.DEBUG
104 start_logging(loglevel)
105
106 if len(args) != 1:
107 logging.error("Wrong number of arguments, exiting\n")
108 parser.print_help()
109 sys.exit(1)
110
111 if not options.image_name and not (options.rootfs_dir and
112 options.bootimg_dir and
113 options.kernel_dir and
114 options.native_sysroot or
115 options.native_sysroot):
116 print "Build artifacts not completely specified, exiting."
117 print " (Use 'wic -e' or 'wic -r -b -k -n' or 'wic -r -n' to specify artifacts)"
118 print options
119 sys.exit(1)
120
121 if not options.image_name:
122 options.build_check = False
123
124 if options.build_check and not options.properties_file:
125 print "Checking basic build environment..."
126 if not verify_build_env():
127 print "Couldn't verify build environment, exiting\n"
128 sys.exit(1)
129 else:
130 print "Done.\n"
131
132 print "Creating image(s)...\n"
133
134 # If '-e' option is used the values are extracted from bitbake env.
135 if options.image_name:
136 bitbake_env_lines = find_bitbake_env_lines(options.image_name)
137 if not bitbake_env_lines:
138 print "Couldn't get bitbake environment, exiting."
139 sys.exit(1)
140 set_bitbake_env_lines(bitbake_env_lines)
141
142 bootimg_dir = staging_data_dir = hdddir = ""
143 rootfs_dir = native_sysroot = kernel_dir = image_output_dir = ""
144
145 if options.image_name:
146 (rootfs_dir, kernel_dir, hdddir, staging_data_dir, native_sysroot) = \
147 find_artifacts(options.image_name)
148
149 wks_file = args[0]
150
151 if not wks_file.endswith(".wks"):
152 # Return full path of the .wks file
153 wks_file = find_canned_image(scripts_path, wks_file)
154 if not wks_file:
155 print "No image named %s found, exiting.\n" % wks_file
156 print "(Use 'wic list images' to list available images, or specify a fully-qualified OE kickstart (.wks) filename)\n"
157 sys.exit(1)
158
159 if options.outdir:
160 image_output_dir = options.outdir
161
162 if options.native_sysroot:
163 native_sysroot = options.native_sysroot
164 print "Using native_sysroot from user command: %s" % native_sysroot
165
166 if not os.path.isdir(native_sysroot):
167 print "--native-sysroot (-n) not found, exiting"
168 sys.exit(1)
169
170 native_sysroot = os.path.abspath(native_sysroot)
171
172 if not options.image_name:
173 if (options.bootimg_dir and options.kernel_dir and
174 options.rootfs_dir and options.native_sysroot):
175 rootfs_dir = ''
176 if 'ROOTFS_DIR' in options.rootfs_dir:
177 rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
178 bootimg_dir = options.bootimg_dir
179 kernel_dir = options.kernel_dir
180 native_sysroot = options.native_sysroot
181
182 if rootfs_dir and not os.path.isdir(rootfs_dir):
183 print "--roofs-dir (-r) not found, exiting\n"
184 sys.exit(1)
185 if not os.path.isdir(bootimg_dir):
186 print "--bootimg-dir (-b) not found, exiting\n"
187 sys.exit(1)
188 if not os.path.isdir(kernel_dir):
189 print "--kernel-dir (-k) not found, exiting\n"
190 sys.exit(1)
191 if not os.path.isdir(native_sysroot):
192 print "--native-sysroot (-n) not found, exiting\n"
193 sys.exit(1)
194 else:
195 print 'Build image from rootfs and a package list using native rootfs\n'
196 if options.rootfs_dir and 'ROOTFS_DIR' in options.rootfs_dir:
197 rootfs_dir = options.rootfs_dir['ROOTFS_DIR']
198 elif options.rootfs_dir:
199 rootfs_dir = options.rootfs_dir
200 else:
201 rootfs_dir = ""
202
203 native_sysroot = options.native_sysroot
204
205 if rootfs_dir and not os.path.isdir(rootfs_dir):
206 print "--roofs-dir (-r) not found, exiting\n"
207 sys.exit(1)
208 if not os.path.isdir(native_sysroot):
209 print "--native-sysroot (-n) not found, exiting\n"
210 sys.exit(1)
211 else:
212 not_found = not_found_dir = ""
213 if not os.path.isdir(rootfs_dir):
214 (not_found, not_found_dir) = ("rootfs-dir", rootfs_dir)
215 elif not os.path.isdir(hdddir) and not os.path.isdir(staging_data_dir):
216 (not_found, not_found_dir) = ("bootimg-dir", bootimg_dir)
217 elif not os.path.isdir(kernel_dir):
218 (not_found, not_found_dir) = ("kernel-dir", kernel_dir)
219 elif not os.path.isdir(native_sysroot):
220 (not_found, not_found_dir) = ("native-sysroot", native_sysroot)
221 if not_found:
222 if not not_found_dir:
223 not_found_dir = "Completely missing artifact - wrong image (.wks) used?"
224 print "Build artifacts not found, exiting."
225 print " (Please check that the build artifacts for the machine"
226 print " selected in local.conf actually exist and that they"
227 print " are the correct artifacts for the image (.wks file)).\n"
228 print "The artifact that couldn't be found was %s:\n %s" % \
229 (not_found, not_found_dir)
230 sys.exit(1)
231
232 krootfs_dir = options.rootfs_dir
233 if krootfs_dir is None:
234 krootfs_dir = {}
235 krootfs_dir['ROOTFS_DIR'] = rootfs_dir
236
237 rootfs_dir = rootfs_dir_to_args(krootfs_dir)
238
239 wic_create(args, wks_file, rootfs_dir, bootimg_dir, kernel_dir,
240 native_sysroot, hdddir, staging_data_dir, scripts_path,
241 image_output_dir, options.debug, options.properties_file)
242
243
244def wic_list_subcommand(args, usage_str):
245 """
246 Command-line handling for listing available image properties and
247 values. The real work is done by image.engine.wic_list()
248 """
249 parser = optparse.OptionParser(usage = usage_str)
250
251 parser.add_option("-o", "--outfile", action = "store",
252 dest = "properties_file",
253 help = "dump the possible values for image properties to a JSON file")
254
255 (options, args) = parser.parse_args(args)
256
257 if not wic_list(args, scripts_path, options.properties_file):
258 logging.error("Bad list arguments, exiting\n")
259 parser.print_help()
260 sys.exit(1)
261
262
263subcommands = {
264 "create": [wic_create_subcommand,
265 wic_create_usage,
266 wic_create_help],
267 "list": [wic_list_subcommand,
268 wic_list_usage,
269 wic_list_help],
270}
271
272
273def start_logging(loglevel):
274 logging.basicConfig(filname = 'wic.log', filemode = 'w', level=loglevel)
275
276
277def main():
278 parser = optparse.OptionParser(version = "wic version %s" % __version__,
279 usage = wic_usage)
280
281 parser.disable_interspersed_args()
282
283 (options, args) = parser.parse_args()
284
285 if len(args):
286 if args[0] == "help":
287 if len(args) == 1:
288 parser.print_help()
289 sys.exit(1)
290
291 invoke_subcommand(args, parser, wic_help_usage, subcommands)
292
293
294if __name__ == "__main__":
295 try:
296 ret = main()
297 except Exception:
298 ret = 1
299 import traceback
300 traceback.print_exc(5)
301 sys.exit(ret)
302
diff --git a/scripts/wipe-sysroot b/scripts/wipe-sysroot
new file mode 100755
index 0000000000..c22d39a405
--- /dev/null
+++ b/scripts/wipe-sysroot
@@ -0,0 +1,54 @@
1#! /bin/sh
2
3# Wipe out all of the sysroots and all of the stamps that populated it.
4# Author: Ross Burton <ross.burton@intel.com>
5#
6# Copyright (c) 2012 Intel Corporation
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15# See the GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21set -e
22
23if [ $# -gt 0 ]; then
24 echo "Wipe all sysroots and sysroot-related stamps for the current build directory." >&2
25 echo "Usage: $0" >&2
26 exit 1
27fi
28
29ENVS=`mktemp --suffix -wipe-sysroot-envs`
30bitbake -p -e > $ENVS
31
32eval `grep -F SSTATE_MANIFESTS= $ENVS`
33eval `grep -F STAGING_DIR= $ENVS`
34eval `grep -F STAMPS_DIR= $ENVS`
35rm -f $ENVS
36
37if [ -z "$SSTATE_MANIFESTS" -o -z "$STAGING_DIR" -o -z "$STAMPS_DIR" ]; then
38 echo "Could not determine SSTATE_MANIFESTS/STAGING_DIR/STAMPS_DIR from bitbake, check above for errors"
39 exit 1
40fi
41
42echo "Deleting the sysroots in $STAGING_DIR, and selected stamps in $SSTATE_MANIFESTS and $STAMPS_DIR."
43
44# The sysroots themselves
45rm -rf $STAGING_DIR
46
47# The stamps that said the sysroot was populated
48rm -rf $STAMPS_DIR/*/*/*.do_populate_sysroot.*
49rm -rf $STAMPS_DIR/*/*/*.do_populate_sysroot_setscene.*
50rm -rf $STAMPS_DIR/*/*/*.do_packagedata.*
51rm -rf $STAMPS_DIR/*/*/*.do_packagedata_setscene.*
52
53# The sstate manifests
54rm -rf $SSTATE_MANIFESTS/manifest-*.populate-sysroot
diff --git a/scripts/yocto-bsp b/scripts/yocto-bsp
new file mode 100755
index 0000000000..d269861769
--- /dev/null
+++ b/scripts/yocto-bsp
@@ -0,0 +1,156 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (c) 2012, Intel Corporation.
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# DESCRIPTION
22# 'yocto-bsp' is the Yocto BSP Tool that helps users create a new
23# Yocto BSP. Invoking it without any arguments will display help
24# screens for the 'yocto-bsp' command and list the available
25# 'yocto-bsp' subcommands. Invoking a subcommand without any
26# arguments will likewise display help screens for the specified
27# subcommand. Please use that interface for detailed help.
28#
29# AUTHORS
30# Tom Zanussi <tom.zanussi (at] intel.com>
31#
32
33__version__ = "0.1.0"
34
35import os
36import sys
37import optparse
38import logging
39
40scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
41lib_path = scripts_path + '/lib'
42sys.path = sys.path + [lib_path]
43
44from bsp.help import *
45from bsp.engine import *
46
47
48def yocto_bsp_create_subcommand(args, usage_str):
49 """
50 Command-line handling for BSP creation. The real work is done by
51 bsp.engine.yocto_bsp_create()
52 """
53 parser = optparse.OptionParser(usage = usage_str)
54
55 parser.add_option("-o", "--outdir", dest = "outdir", action = "store",
56 help = "name of BSP dir to create")
57 parser.add_option("-i", "--infile", dest = "properties_file", action = "store",
58 help = "name of file containing the values for BSP properties as a JSON file")
59 parser.add_option("-c", "--codedump", dest = "codedump", action = "store_true",
60 default = False, help = "dump the generated code to bspgen.out")
61 parser.add_option("-s", "--skip-git-check", dest = "git_check", action = "store_false",
62 default = True, help = "skip the git connectivity check")
63 (options, args) = parser.parse_args(args)
64
65 if len(args) != 2:
66 logging.error("Wrong number of arguments, exiting\n")
67 parser.print_help()
68 sys.exit(1)
69
70 machine = args[0]
71 karch = args[1]
72
73 if options.outdir:
74 bsp_output_dir = options.outdir
75 else:
76 bsp_output_dir = "meta-" + machine
77
78 if options.git_check and not options.properties_file:
79 print "Checking basic git connectivity..."
80 if not verify_git_repo(GIT_CHECK_URI):
81 print "Couldn't verify git connectivity, exiting\n"
82 print "Details: couldn't access %s" % GIT_CHECK_URI
83 print " (this most likely indicates a network connectivity problem or"
84 print " a misconfigured git intallation)"
85 sys.exit(1)
86 else:
87 print "Done.\n"
88
89 yocto_bsp_create(machine, karch, scripts_path, bsp_output_dir, options.codedump, options.properties_file)
90
91
92def yocto_bsp_list_subcommand(args, usage_str):
93 """
94 Command-line handling for listing available BSP properties and
95 values. The real work is done by bsp.engine.yocto_bsp_list()
96 """
97 parser = optparse.OptionParser(usage = usage_str)
98
99 parser.add_option("-o", "--outfile", action = "store", dest = "properties_file",
100 help = "dump the possible values for BSP properties to a JSON file")
101
102 (options, args) = parser.parse_args(args)
103
104 if not yocto_bsp_list(args, scripts_path, options.properties_file):
105 logging.error("Bad list arguments, exiting\n")
106 parser.print_help()
107 sys.exit(1)
108
109
110subcommands = {
111 "create": [yocto_bsp_create_subcommand,
112 yocto_bsp_create_usage,
113 yocto_bsp_create_help],
114 "list": [yocto_bsp_list_subcommand,
115 yocto_bsp_list_usage,
116 yocto_bsp_list_help],
117}
118
119
120def start_logging(loglevel):
121 logging.basicConfig(filname = 'yocto-bsp.log', filemode = 'w', level=loglevel)
122
123
124def main():
125 parser = optparse.OptionParser(version = "yocto-bsp version %s" % __version__,
126 usage = yocto_bsp_usage)
127
128 parser.disable_interspersed_args()
129 parser.add_option("-D", "--debug", dest = "debug", action = "store_true",
130 default = False, help = "output debug information")
131
132 (options, args) = parser.parse_args()
133
134 loglevel = logging.INFO
135 if options.debug:
136 loglevel = logging.DEBUG
137 start_logging(loglevel)
138
139 if len(args):
140 if args[0] == "help":
141 if len(args) == 1:
142 parser.print_help()
143 sys.exit(1)
144
145 invoke_subcommand(args, parser, yocto_bsp_help_usage, subcommands)
146
147
148if __name__ == "__main__":
149 try:
150 ret = main()
151 except Exception:
152 ret = 1
153 import traceback
154 traceback.print_exc(5)
155 sys.exit(ret)
156
diff --git a/scripts/yocto-kernel b/scripts/yocto-kernel
new file mode 100755
index 0000000000..c9b2821e00
--- /dev/null
+++ b/scripts/yocto-kernel
@@ -0,0 +1,399 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (c) 2012, Intel Corporation.
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# DESCRIPTION
22# 'yocto-kernel' is the Yocto BSP Tool that helps users manage kernel
23# config options and patches for a Yocto BSP. Invoking it without any
24# arguments will display help screens for the 'yocto-kernel' command
25# and list the available 'yocto-kernel' subcommands. Invoking a
26# subcommand without any arguments will likewise display help screens
27# for the specified subcommand. Please use that interface for
28# detailed help.
29#
30# AUTHORS
31# Tom Zanussi <tom.zanussi (at] intel.com>
32#
33
34__version__ = "0.1.0"
35
36import os
37import sys
38import optparse
39import logging
40
41scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
42lib_path = scripts_path + '/lib'
43sys.path = sys.path + [lib_path]
44
45from bsp.help import *
46from bsp.kernel import *
47
48
49def yocto_kernel_config_list_subcommand(args, usage_str):
50 """
51 Command-line handling for listing BSP config options. The
52 real work is done by bsp.kernel.yocto_kernel_config_list().
53 """
54 logging.debug("yocto_kernel_config_list_subcommand")
55
56 parser = optparse.OptionParser(usage = usage_str)
57
58 (options, args) = parser.parse_args(args)
59
60 if len(args) != 1:
61 logging.error("Wrong number of arguments, exiting\n")
62 parser.print_help()
63 sys.exit(1)
64
65 yocto_kernel_config_list(scripts_path, args[0])
66
67
68def yocto_kernel_config_add_subcommand(args, usage_str):
69 """
70 Command-line handling for adding BSP config items. The real work
71 is done by bsp.kernel.yocto_kernel_config_add().
72 """
73 logging.debug("yocto_kernel_config_add_subcommand")
74
75 parser = optparse.OptionParser(usage = usage_str)
76
77 (options, args) = parser.parse_args(args)
78
79 if len(args) < 2:
80 logging.error("Wrong number of arguments, exiting\n")
81 parser.print_help()
82 sys.exit(1)
83
84 machine = args.pop(0)
85 yocto_kernel_config_add(scripts_path, machine, args)
86
87
88def yocto_kernel_config_rm_subcommand(args, usage_str):
89 """
90 Command-line handling for removing BSP config items. The real
91 work is done by bsp.kernel.yocto_kernel_config_rm().
92 """
93 logging.debug("yocto_kernel_config_rm_subcommand")
94
95 parser = optparse.OptionParser(usage = usage_str)
96
97 (options, args) = parser.parse_args(args)
98
99 if len(args) != 1:
100 logging.error("Wrong number of arguments, exiting\n")
101 parser.print_help()
102 sys.exit(1)
103
104 yocto_kernel_config_rm(scripts_path, args[0])
105
106
107def yocto_kernel_patch_list_subcommand(args, usage_str):
108 """
109 Command-line handling for listing BSP (SRC_URI patches. The real
110 work is done by bsp.kernel.yocto_kernel_patch_list().
111 """
112 logging.debug("yocto_kernel_patch_list_subcommand")
113
114 parser = optparse.OptionParser(usage = usage_str)
115
116 (options, args) = parser.parse_args(args)
117
118 if len(args) != 1:
119 logging.error("Wrong number of arguments, exiting\n")
120 parser.print_help()
121 sys.exit(1)
122
123 yocto_kernel_patch_list(scripts_path, args[0])
124
125
126def yocto_kernel_patch_add_subcommand(args, usage_str):
127 """
128 Command-line handling for adding BSP patches. The real work is
129 done by bsp.kernel.yocto_kernel_patch_add().
130 """
131 logging.debug("yocto_kernel_patch_add_subcommand")
132
133 parser = optparse.OptionParser(usage = usage_str)
134
135 (options, args) = parser.parse_args(args)
136
137 if len(args) < 2:
138 logging.error("Wrong number of arguments, exiting\n")
139 parser.print_help()
140 sys.exit(1)
141
142 machine = args.pop(0)
143 yocto_kernel_patch_add(scripts_path, machine, args)
144
145
146def yocto_kernel_patch_rm_subcommand(args, usage_str):
147 """
148 Command-line handling for removing BSP patches. The real work is
149 done by bsp.kernel.yocto_kernel_patch_rm().
150 """
151 logging.debug("yocto_kernel_patch_rm_subcommand")
152
153 parser = optparse.OptionParser(usage = usage_str)
154
155 (options, args) = parser.parse_args(args)
156
157 if len(args) != 1:
158 logging.error("Wrong number of arguments, exiting\n")
159 parser.print_help()
160 sys.exit(1)
161
162 yocto_kernel_patch_rm(scripts_path, args[0])
163
164
165def yocto_kernel_feature_list_subcommand(args, usage_str):
166 """
167 Command-line handling for listing the BSP features that are being
168 used by the BSP. The real work is done by
169 bsp.kernel.yocto_kernel_feature_list().
170 """
171 logging.debug("yocto_kernel_feature_list_subcommand")
172
173 parser = optparse.OptionParser(usage = usage_str)
174
175 (options, args) = parser.parse_args(args)
176
177 if len(args) != 1:
178 logging.error("Wrong number of arguments, exiting\n")
179 parser.print_help()
180 sys.exit(1)
181
182 yocto_kernel_feature_list(scripts_path, args[0])
183
184
185def yocto_kernel_feature_add_subcommand(args, usage_str):
186 """
187 Command-line handling for adding the use of kernel features to a
188 BSP. The real work is done by bsp.kernel.yocto_kernel_feature_add().
189 """
190 logging.debug("yocto_kernel_feature_add_subcommand")
191
192 parser = optparse.OptionParser(usage = usage_str)
193
194 (options, args) = parser.parse_args(args)
195
196 if len(args) < 2:
197 logging.error("Wrong number of arguments, exiting\n")
198 parser.print_help()
199 sys.exit(1)
200
201 machine = args.pop(0)
202 yocto_kernel_feature_add(scripts_path, machine, args)
203
204
205def yocto_kernel_feature_rm_subcommand(args, usage_str):
206 """
207 Command-line handling for removing the use of kernel features from
208 a BSP. The real work is done by bsp.kernel.yocto_kernel_feature_rm().
209 """
210 logging.debug("yocto_kernel_feature_rm_subcommand")
211
212 parser = optparse.OptionParser(usage = usage_str)
213
214 (options, args) = parser.parse_args(args)
215
216 if len(args) != 1:
217 logging.error("Wrong number of arguments, exiting\n")
218 parser.print_help()
219 sys.exit(1)
220
221 yocto_kernel_feature_rm(scripts_path, args[0])
222
223
224def yocto_kernel_available_features_list_subcommand(args, usage_str):
225 """
226 Command-line handling for listing all the kernel features
227 available for use in a BSP. This includes the features present in
228 the meta branch(es) of the pointed-to repo(s) as well as the local
229 features added in recipe-space to the current BSP as well. The
230 real work is done by bsp.kernel.yocto_kernel_available_features_list().
231 """
232 logging.debug("yocto_kernel_feature_available_features_list_subcommand")
233
234 parser = optparse.OptionParser(usage = usage_str)
235
236 (options, args) = parser.parse_args(args)
237
238 if len(args) != 1:
239 logging.error("Wrong number of arguments, exiting\n")
240 parser.print_help()
241 sys.exit(1)
242
243 yocto_kernel_available_features_list(scripts_path, args[0])
244
245
246def yocto_kernel_feature_describe_subcommand(args, usage_str):
247 """
248 Command-line handling for listing the description of a specific
249 kernel feature available for use in a BSP. This includes the
250 features present in the meta branch(es) of the pointed-to repo(s)
251 as well as the local features added in recipe-space to the current
252 BSP as well. The real work is done by
253 bsp.kernel.yocto_kernel_feature_describe().
254 """
255 logging.debug("yocto_kernel_feature_describe_subcommand")
256
257 parser = optparse.OptionParser(usage = usage_str)
258
259 (options, args) = parser.parse_args(args)
260
261 if len(args) != 2:
262 logging.error("Wrong number of arguments, exiting\n")
263 parser.print_help()
264 sys.exit(1)
265
266 yocto_kernel_feature_describe(scripts_path, args[0], args[1])
267
268
269def yocto_kernel_feature_create_subcommand(args, usage_str):
270 """
271 Command-line handling for creating a recipe-space kernel feature
272 in a BSP. The real work is done by
273 bsp.kernel.yocto_kernel_feature_create().
274 """
275 logging.debug("yocto_kernel_feature_create_subcommand")
276
277 parser = optparse.OptionParser(usage = usage_str)
278
279 (options, args) = parser.parse_args(args)
280
281 if len(args) < 4:
282 logging.error("Wrong number of arguments, exiting\n")
283 parser.print_help()
284 sys.exit(1)
285
286 machine = args.pop(0)
287 yocto_kernel_feature_create(scripts_path, machine, args)
288
289
290def yocto_kernel_feature_destroy_subcommand(args, usage_str):
291 """
292 Command-line handling for removing a recipe-space kernel feature
293 from a BSP. The real work is done by
294 bsp.kernel.yocto_kernel_feature_destroy().
295 """
296 logging.debug("yocto_kernel_feature_destroy_subcommand")
297
298 parser = optparse.OptionParser(usage = usage_str)
299
300 (options, args) = parser.parse_args(args)
301
302 if len(args) != 2:
303 logging.error("Wrong number of arguments, exiting\n")
304 parser.print_help()
305 sys.exit(1)
306
307 yocto_kernel_feature_destroy(scripts_path, args[0], args[1])
308
309
310subcommands = {
311 "config-list": [yocto_kernel_config_list_subcommand,
312 yocto_kernel_config_list_usage,
313 yocto_kernel_config_list_help],
314 "config-add": [yocto_kernel_config_add_subcommand,
315 yocto_kernel_config_add_usage,
316 yocto_kernel_config_add_help],
317 "config-rm": [yocto_kernel_config_rm_subcommand,
318 yocto_kernel_config_rm_usage,
319 yocto_kernel_config_rm_help],
320 "patch-list": [yocto_kernel_patch_list_subcommand,
321 yocto_kernel_patch_list_usage,
322 yocto_kernel_patch_list_help],
323 "patch-add": [yocto_kernel_patch_add_subcommand,
324 yocto_kernel_patch_add_usage,
325 yocto_kernel_patch_add_help],
326 "patch-rm": [yocto_kernel_patch_rm_subcommand,
327 yocto_kernel_patch_rm_usage,
328 yocto_kernel_patch_rm_help],
329 "feature-list": [yocto_kernel_feature_list_subcommand,
330 yocto_kernel_feature_list_usage,
331 yocto_kernel_feature_list_help],
332 "feature-add": [yocto_kernel_feature_add_subcommand,
333 yocto_kernel_feature_add_usage,
334 yocto_kernel_feature_add_help],
335 "feature-rm": [yocto_kernel_feature_rm_subcommand,
336 yocto_kernel_feature_rm_usage,
337 yocto_kernel_feature_rm_help],
338 "features-list": [yocto_kernel_available_features_list_subcommand,
339 yocto_kernel_available_features_list_usage,
340 yocto_kernel_available_features_list_help],
341 "feature-describe": [yocto_kernel_feature_describe_subcommand,
342 yocto_kernel_feature_describe_usage,
343 yocto_kernel_feature_describe_help],
344 "feature-create": [yocto_kernel_feature_create_subcommand,
345 yocto_kernel_feature_create_usage,
346 yocto_kernel_feature_create_help],
347 "feature-destroy": [yocto_kernel_feature_destroy_subcommand,
348 yocto_kernel_feature_destroy_usage,
349 yocto_kernel_feature_destroy_help],
350}
351
352
353def start_logging(loglevel):
354 logging.basicConfig(filname = 'yocto-kernel.log', filemode = 'w', level=loglevel)
355
356
357def main():
358 parser = optparse.OptionParser(version = "yocto-kernel version %s" % __version__,
359 usage = yocto_kernel_usage)
360
361 parser.disable_interspersed_args()
362 parser.add_option("-D", "--debug", dest = "debug", action = "store_true",
363 default = False, help = "output debug information")
364
365 (options, args) = parser.parse_args()
366
367 loglevel = logging.INFO
368 if options.debug:
369 loglevel = logging.DEBUG
370 start_logging(loglevel)
371
372 if len(args):
373 if args[0] == "help":
374 if len(args) == 1:
375 parser.print_help()
376 sys.exit(1)
377 sc = 1
378 else:
379 sc = 0
380
381 if args[sc] == "config" or args[sc] == "patch" or \
382 args[sc] == "feature" or args[sc] == "features":
383 if len(args) < 2 + sc:
384 parser.print_help()
385 sys.exit(1)
386 args[sc] += "-" + args[sc + 1]
387 args.pop(sc + 1)
388
389 invoke_subcommand(args, parser, yocto_kernel_help_usage, subcommands)
390
391
392if __name__ == "__main__":
393 try:
394 ret = main()
395 except Exception:
396 ret = 1
397 import traceback
398 traceback.print_exc(5)
399 sys.exit(ret)
diff --git a/scripts/yocto-layer b/scripts/yocto-layer
new file mode 100755
index 0000000000..53d2aabd3f
--- /dev/null
+++ b/scripts/yocto-layer
@@ -0,0 +1,147 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (c) 2012, Intel Corporation.
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# DESCRIPTION
22# 'yocto-layer' is the Yocto Tool that helps users create a new Yocto
23# layer. Invoking it without any arguments will display help screens
24# for the 'yocto-layer' command and list the available 'yocto-layer'
25# subcommands. Invoking a subcommand without any arguments will
26# likewise display help screens for the specified subcommand. Please
27# use that interface for detailed help.
28#
29# AUTHORS
30# Tom Zanussi <tom.zanussi (at] intel.com>
31#
32
33__version__ = "0.1.0"
34
35import os
36import sys
37import optparse
38import logging
39
40scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0])))
41lib_path = scripts_path + '/lib'
42sys.path = sys.path + [lib_path]
43
44from bsp.help import *
45from bsp.engine import *
46
47
48def yocto_layer_create_subcommand(args, usage_str):
49 """
50 Command-line handling for layer creation. The real work is done by
51 bsp.engine.yocto_layer_create()
52 """
53 parser = optparse.OptionParser(usage = usage_str)
54
55 parser.add_option("-o", "--outdir", dest = "outdir", action = "store",
56 help = "name of layer dir to create")
57 parser.add_option("-i", "--infile", dest = "properties_file", action = "store",
58 help = "name of file containing the values for layer input properties as a JSON file")
59 parser.add_option("-c", "--codedump", dest = "codedump", action = "store_true",
60 default = False, help = "dump the generated code to layergen.out")
61 (options, args) = parser.parse_args(args)
62
63 if len(args) < 1 or len(args) > 2:
64 logging.error("Wrong number of arguments, exiting\n")
65 parser.print_help()
66 sys.exit(1)
67
68 layer_name = args[0]
69 properties = ""
70
71 if len(args) == 2:
72 layer_priority = args[1]
73 properties = '{"layer_priority":"' + layer_priority + '"}'
74
75 if options.outdir:
76 layer_output_dir = options.outdir
77 else:
78 layer_output_dir = "meta-" + layer_name
79
80 yocto_layer_create(layer_name, scripts_path, layer_output_dir, options.codedump, options.properties_file, properties)
81
82
83def yocto_layer_list_subcommand(args, usage_str):
84 """
85 Command-line handling for listing available layer properties and
86 values. The real work is done by bsp.engine.yocto_layer_list()
87 """
88 parser = optparse.OptionParser(usage = usage_str)
89
90 parser.add_option("-o", "--outfile", action = "store", dest = "properties_file",
91 help = "dump the possible values for layer properties to a JSON file")
92
93 (options, args) = parser.parse_args(args)
94
95 if not yocto_layer_list(args, scripts_path, options.properties_file):
96 logging.error("Bad list arguments, exiting\n")
97 parser.print_help()
98 sys.exit(1)
99
100
101subcommands = {
102 "create": [yocto_layer_create_subcommand,
103 yocto_layer_create_usage,
104 yocto_layer_create_help],
105 "list": [yocto_layer_list_subcommand,
106 yocto_layer_list_usage,
107 yocto_layer_list_help],
108}
109
110
111def start_logging(loglevel):
112 logging.basicConfig(filname = 'yocto-layer.log', filemode = 'w', level=loglevel)
113
114
115def main():
116 parser = optparse.OptionParser(version = "yocto-layer version %s" % __version__,
117 usage = yocto_layer_usage)
118
119 parser.disable_interspersed_args()
120 parser.add_option("-D", "--debug", dest = "debug", action = "store_true",
121 default = False, help = "output debug information")
122
123 (options, args) = parser.parse_args()
124
125 loglevel = logging.INFO
126 if options.debug:
127 loglevel = logging.DEBUG
128 start_logging(loglevel)
129
130 if len(args):
131 if args[0] == "help":
132 if len(args) == 1:
133 parser.print_help()
134 sys.exit(1)
135
136 invoke_subcommand(args, parser, yocto_layer_help_usage, subcommands)
137
138
139if __name__ == "__main__":
140 try:
141 ret = main()
142 except Exception:
143 ret = 1
144 import traceback
145 traceback.print_exc(5)
146 sys.exit(ret)
147