obs-build-20170201/ 0000755 0001750 0001750 00000000000 13044635504 012232 5 ustar alee alee obs-build-20170201/build-recipe-spec 0000644 0001750 0001750 00000021462 13044631422 015451 0 ustar alee alee #
# spec specific functions.
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
recipe_setup_spec() {
TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
if test -z "$TOPDIR"; then
cleanup_and_exit 1 "Error: TOPDIR empty"
fi
test "$DO_INIT_TOPDIR" = false || rm -rf "$BUILD_ROOT$TOPDIR"
for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do
mkdir -p $BUILD_ROOT$TOPDIR/$i
done
chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
mkdir -p $BUILD_ROOT$TOPDIR/SOURCES
cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
}
recipe_prepare_spec() {
args=()
if test -n "$RELEASE"; then
args=(--release "$RELEASE")
fi
rawcfgmacros=.rpmmacros
test "$BUILDTYPE" = debbuild && rawcfgmacros=.debmacros
# fixup specfile
CHANGELOGARGS=
test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" && CHANGELOGARGS="--changelog $BUILD_ROOT/.build-changelog"
substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" $CHANGELOGARGS "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1
# fix rpmrc if we are compiling for i686
test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
fi
# extract macros from configuration
queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/$rawcfgmacros
if test -n "$BUILD_DEBUG" && test "$BUILDTYPE" != debbuild ; then
echo '
%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep
%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package
%_build_insert_debug_package \
%global __debug_package 1 \
%undefine _enable_debug_packages \
%debug_package
' >> $BUILD_ROOT/root/$rawcfgmacros
fi
if test -n "$BUILD_JOBS" ; then
cat >> $BUILD_ROOT/root/$rawcfgmacros <<-EOF
%jobs $BUILD_JOBS
%_smp_mflags -j$BUILD_JOBS
EOF
fi
test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/$rawcfgmacros $BUILD_ROOT/home/abuild/$rawcfgmacros
# extract optflags from configuration
queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" optflags ${BUILD_DEBUG:+debug} > $BUILD_ROOT/root/.rpmrc
test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc
if test -z "$ABUILD_TARGET"; then
ABUILD_TARGET=$(queryconfig target --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
fi
# report specfile changes
if test -f $BUILD_ROOT/.spec.new ; then
if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT/.spec.new ; then
echo -----------------------------------------------------------------
echo "I have the following modifications for $RECIPEFILE:"
sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE > $BUILD_ROOT/.spec.t1
sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE
else
rm -f $BUILD_ROOT/.spec.new
fi
fi
}
recipe_build_spec() {
test -z "$BUILD_RPM_BUILD_STAGE" && BUILD_RPM_BUILD_STAGE=-ba
rpmbuild=rpmbuild
test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm
test "$BUILDTYPE" = debbuild && rpmbuild=debbuild
# XXX: move _srcdefattr to macro file?
rpmbopts=("$BUILD_RPM_BUILD_STAGE" "--define" "_srcdefattr (-,root,root)")
if test "$DO_CHECKS" != true ; then
if chroot "$BUILD_ROOT" "$rpmbuild" --nocheck --help >/dev/null 2>&1; then
rpmbopts[${#rpmbopts[@]}]="--nocheck"
else
echo "warning: --nocheck is not supported by this $rpmbuild version"
fi
fi
if test "$rpmbuild" == "rpmbuild" ; then
# use only --nosignature for rpm v4
rpmbopts[${#rpmbopts[@]}]="--nosignature"
fi
if test -n "$ABUILD_TARGET" ; then
rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
fi
if test -n "$BUILD_DEBUG" ; then
rpmbopts[${#rpmbopts[@]}]='--define'
rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
fi
if test -n "$DISTURL" ; then
rpmbopts[${#rpmbopts[@]}]='--define'
rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
fi
if test -n "$RSYNCDONE" ; then
rpmbopts[${#rpmbopts[@]}]='--define'
rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
fi
# su involves a shell which would require even more
# complicated quoting to bypass than this
toshellscript $rpmbuild \
"${definesnstuff[@]}" \
"${rpmbopts[@]}" \
"$TOPDIR/SOURCES/$RECIPEFILE" \
> $BUILD_ROOT/.build.command
chmod 755 $BUILD_ROOT/.build.command
check_exit
if test -n "$RUN_SHELL"; then
chroot $BUILD_ROOT su -
else
chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null && BUILD_SUCCEEDED=true
fi
}
recipe_resultdirs_spec() {
echo RPMS SRPMS
}
recipe_unpack_srcrpm() {
test -n "$LIST_STATE" || echo "processing src rpm $SRCDIR/$RECIPEFILE ..."
MYSRCDIR="$BUILD_ROOT/.build-srcdir"
rm -rf "$MYSRCDIR"
mkdir -p "$MYSRCDIR"
cd $MYSRCDIR || cleanup_and_exit 1
$BUILD_DIR/unrpm -q $SRCDIR/$RECIPEFILE || {
cleanup_and_exit 1 "could not unpack $RECIPEFILE."
}
for RECIPEFILE in *.spec ; do : ; done
}
# post build functions... move somewhere else?
recipe_check_file_owners() {
echo "... checking for files with abuild user/group"
BADFILE=
while read un gn fn ; do
if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
echo " $un $gn $fn"
BADFILE=true
fi
done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
if test -n "$BADFILE" ; then
cleanup_and_exit 1 "please fix your filelist (e.g. add defattr)"
fi
}
recipe_run_rpmlint() {
if ! test -x "$BUILD_ROOT/opt/testing/bin/rpmlint" ; then
return
fi
LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
\( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
-o -name "*-32bit-*" -o -name "*-64bit-*" \
-o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
-o -type f -name '*.rpm' -print))
SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
echo
echo "RPMLINT report:"
echo "==============="
rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
rm -f "$BUILD_ROOT$rpmlint_logfile"
ret=0
chroot $BUILD_ROOT su -s /opt/testing/bin/rpmlint "$BUILD_USER" -- \
--info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
${SRPM_FILE_LIST[*]#$BUILD_ROOT} > >(tee "$BUILD_ROOT$rpmlint_logfile") 2>&1 || ret=1
echo
if test "$ret" = 1 ; then
cleanup_and_exit 1
fi
}
recipe_compare_oldpackages() {
if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then
echo "... comparing built packages with the former built"
if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then
chroot $BUILD_ROOT touch /.build/.same_result_marker
# XXX: dirty build service hack. fix bs_worker. Search for
# 'same_result_marker' for traces of a first try to get rid of this
if test -n "$REASON" -a -n "$DISTURL" ; then
exitcode=2
fi
fi
fi
}
recipe_create_deltarpms() {
if test -x "$BUILD_ROOT/usr/bin/makedeltarpm" -a -x $BUILD_ROOT/usr/lib/build/mkdrpms ; then
echo "... creating delta rpms"
ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
fi
}
obs-build-20170201/t/ 0000755 0001750 0001750 00000000000 13044631422 012470 5 ustar alee alee obs-build-20170201/t/standard.livebuild 0000644 0001750 0001750 00000074000 13044631422 016172 0 ustar alee alee ./PaxHeaders.10269/auto 0000644 0000000 0000000 00000000132 12222266372 013110 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404999252.606063979
30 ctime=1404999250.918084803
auto/ 0000755 0001750 0000144 00000000000 12222266372 012701 5 ustar 00jblunck users 0000000 0000000 auto/PaxHeaders.10269/clean 0000644 0000000 0000000 00000000132 12222266372 014035 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
auto/clean 0000755 0001750 0000144 00000000240 12222266372 013705 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb clean noauto "${@}"
rm -f config/binary config/bootstrap config/chroot config/common config/source
rm -f config/control
rm -f build.log
auto/PaxHeaders.10269/config 0000644 0000000 0000000 00000000132 12222266372 014220 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
auto/config 0000755 0001750 0000144 00000000626 12222266372 014100 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
case "$(dpkg --print-architecture)" in
amd64)
_LINUX_FLAVOURS="amd64"
_SOURCE="false"
;;
i386)
_LINUX_FLAVOURS="486 686-pae"
_SOURCE="true"
;;
esac
lb config noauto \
--clean \
--ignore-system-defaults \
--mode debian \
--debian-installer live \
--linux-flavours "${_LINUX_FLAVOURS}" \
--linux-packages "linux-image linux-headers" \
--source "${_SOURCE}" \
"${@}"
auto/PaxHeaders.10269/build 0000644 0000000 0000000 00000000132 12222266372 014052 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
auto/build 0000755 0001750 0000144 00000000112 12222266372 013720 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb build noauto "${@}" && echo $? 2>&1 | tee build.log
./PaxHeaders.10269/config 0000644 0000000 0000000 00000000132 12222300375 013375 x ustar 00 0000000 0000000 30 mtime=1380548861.684530853
30 atime=1404999252.606063979
30 ctime=1404999250.918084803
config/ 0000755 0001750 0000144 00000000000 12222300375 013166 5 ustar 00jblunck users 0000000 0000000 config/PaxHeaders.10269/bootloaders 0000644 0000000 0000000 00000000132 12222304630 015553 x ustar 00 0000000 0000000 30 mtime=1380551064.696527946
30 atime=1404999252.606063979
30 ctime=1404999250.918084803
config/bootloaders/ 0000755 0001750 0000144 00000000000 12222304630 015501 5 ustar 00jblunck users 0000000 0000000 config/PaxHeaders.10269/package-lists 0000644 0000000 0000000 00000000132 12357312571 016001 x ustar 00 0000000 0000000 30 mtime=1404933497.776159592
30 atime=1404999252.606063979
30 ctime=1404999250.918084803
config/package-lists/ 0000755 0001750 0000144 00000000000 12357312571 015727 5 ustar 00jblunck users 0000000 0000000 config/package-lists/PaxHeaders.10269/installer.list.chroot 0000644 0000000 0000000 00000000132 12222266372 022243 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/package-lists/installer.list.chroot 0000644 0001750 0000144 00000000037 12222266372 022114 0 ustar 00jblunck users 0000000 0000000 debian-installer-launcher
sudo
config/package-lists/PaxHeaders.10269/live.list.chroot 0000644 0000000 0000000 00000000132 12222266372 021205 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/package-lists/live.list.chroot 0000644 0001750 0000144 00000000027 12222266372 021055 0 ustar 00jblunck users 0000000 0000000 live-manual
live-tools
config/package-lists/PaxHeaders.10269/localization.list.chroot 0000644 0000000 0000000 00000000132 12222266372 022736 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/package-lists/localization.list.chroot 0000644 0001750 0000144 00000000034 12222266372 022604 0 ustar 00jblunck users 0000000 0000000 task-english
console-tools
config/package-lists/PaxHeaders.10269/standard.list.chroot 0000644 0000000 0000000 00000000132 12222266372 022046 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/package-lists/standard.list.chroot 0000644 0001750 0000144 00000000072 12222266372 021716 0 ustar 00jblunck users 0000000 0000000 ! Packages Priority standard
task-laptop
task-ssh-server
config/package-lists/PaxHeaders.10269/memtest 0000644 0000000 0000000 00000000132 12222266372 017455 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/package-lists/memtest 0000644 0001750 0000144 00000000013 12222266372 017320 0 ustar 00jblunck users 0000000 0000000 memtest86+
config/PaxHeaders.10269/archives 0000644 0000000 0000000 00000000132 12357513140 015051 x ustar 00 0000000 0000000 30 mtime=1404999264.309919538
30 atime=1404999252.606063979
30 ctime=1404999264.309919538
config/archives/ 0000755 0001750 0000144 00000000000 12357513140 014777 5 ustar 00jblunck users 0000000 0000000 config/archives/PaxHeaders.10269/debian.key.chroot 0000644 0000000 0000000 00000000132 12222300432 020344 x ustar 00 0000000 0000000 30 mtime=1380548890.449530815
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
config/archives/debian.key.chroot 0000644 0001750 0000144 00000000045 12222300432 020214 0 ustar 00jblunck users 0000000 0000000 a73043cf-7b16-42dc-b0d9-3031ed4370be
./PaxHeaders.10269/README 0000644 0000000 0000000 00000000132 12222266372 013075 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404999250.918084803
30 ctime=1404999250.918084803
README 0000644 0001750 0000144 00000000771 12222266372 012616 0 ustar 00jblunck users 0000000 0000000 This is the configuration tree for:
Debian Standard
A software called live-build can be used to automatically build images from
this configuration tree.
live-build can be obtained from .
On Debian based systems, live-build can be installed with:
# apt-get install live-build
More information about live-build and the Live Systems project can be found on
its homepage at and in the manual at
.
obs-build-20170201/t/directory.livebuild 0000644 0001750 0001750 00000074000 13044631422 016376 0 ustar alee alee ./PaxHeaders.21794/directory 0000644 0000000 0000000 00000000132 12361532117 014146 x ustar 00 0000000 0000000 30 mtime=1405531215.102319719
30 atime=1405531213.970331813
30 ctime=1405531215.102319719
directory/ 0000755 0001750 0000144 00000000000 12361532117 013732 5 ustar 00jblunck users 0000000 0000000 directory/PaxHeaders.21794/README 0000644 0000000 0000000 00000000132 12222266372 014751 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/README 0000644 0001750 0000144 00000000771 12222266372 014622 0 ustar 00jblunck users 0000000 0000000 This is the configuration tree for:
Debian Standard
A software called live-build can be used to automatically build images from
this configuration tree.
live-build can be obtained from .
On Debian based systems, live-build can be installed with:
# apt-get install live-build
More information about live-build and the Live Systems project can be found on
its homepage at and in the manual at
.
directory/PaxHeaders.21794/auto 0000644 0000000 0000000 00000000132 12222266372 014764 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/auto/ 0000755 0001750 0000144 00000000000 12222266372 014705 5 ustar 00jblunck users 0000000 0000000 directory/auto/PaxHeaders.21794/clean 0000644 0000000 0000000 00000000132 12222266372 016046 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/auto/clean 0000755 0001750 0000144 00000000240 12222266372 015711 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb clean noauto "${@}"
rm -f config/binary config/bootstrap config/chroot config/common config/source
rm -f config/control
rm -f build.log
directory/auto/PaxHeaders.21794/config 0000644 0000000 0000000 00000000132 12222266372 016231 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/auto/config 0000755 0001750 0000144 00000000626 12222266372 016104 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
case "$(dpkg --print-architecture)" in
amd64)
_LINUX_FLAVOURS="amd64"
_SOURCE="false"
;;
i386)
_LINUX_FLAVOURS="486 686-pae"
_SOURCE="true"
;;
esac
lb config noauto \
--clean \
--ignore-system-defaults \
--mode debian \
--debian-installer live \
--linux-flavours "${_LINUX_FLAVOURS}" \
--linux-packages "linux-image linux-headers" \
--source "${_SOURCE}" \
"${@}"
directory/auto/PaxHeaders.21794/build 0000644 0000000 0000000 00000000132 12222266372 016063 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/auto/build 0000755 0001750 0000144 00000000112 12222266372 015724 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb build noauto "${@}" && echo $? 2>&1 | tee build.log
directory/PaxHeaders.21794/config 0000644 0000000 0000000 00000000132 12222300375 015251 x ustar 00 0000000 0000000 30 mtime=1380548861.684530853
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/ 0000755 0001750 0000144 00000000000 12222300375 015172 5 ustar 00jblunck users 0000000 0000000 directory/config/PaxHeaders.21794/bootloaders 0000644 0000000 0000000 00000000132 12222304630 017564 x ustar 00 0000000 0000000 30 mtime=1380551064.696527946
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/bootloaders/ 0000755 0001750 0000144 00000000000 12222304630 017505 5 ustar 00jblunck users 0000000 0000000 directory/config/PaxHeaders.21794/package-lists 0000644 0000000 0000000 00000000132 12357312571 020012 x ustar 00 0000000 0000000 30 mtime=1404933497.776159592
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/ 0000755 0001750 0000144 00000000000 12357312571 017733 5 ustar 00jblunck users 0000000 0000000 directory/config/package-lists/PaxHeaders.21794/installer.list.chroot 0000644 0000000 0000000 00000000132 12222266372 024254 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/installer.list.chroot 0000644 0001750 0000144 00000000037 12222266372 024120 0 ustar 00jblunck users 0000000 0000000 debian-installer-launcher
sudo
directory/config/package-lists/PaxHeaders.21794/live.list.chroot 0000644 0000000 0000000 00000000132 12222266372 023216 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/live.list.chroot 0000644 0001750 0000144 00000000027 12222266372 023061 0 ustar 00jblunck users 0000000 0000000 live-manual
live-tools
directory/config/package-lists/PaxHeaders.21794/localization.list.chroot 0000644 0000000 0000000 00000000132 12222266372 024747 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/localization.list.chroot 0000644 0001750 0000144 00000000034 12222266372 024610 0 ustar 00jblunck users 0000000 0000000 task-english
console-tools
directory/config/package-lists/PaxHeaders.21794/standard.list.chroot 0000644 0000000 0000000 00000000132 12222266372 024057 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/standard.list.chroot 0000644 0001750 0000144 00000000072 12222266372 023722 0 ustar 00jblunck users 0000000 0000000 ! Packages Priority standard
task-laptop
task-ssh-server
directory/config/package-lists/PaxHeaders.21794/memtest 0000644 0000000 0000000 00000000132 12222266372 021466 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/package-lists/memtest 0000644 0001750 0000144 00000000013 12222266372 021324 0 ustar 00jblunck users 0000000 0000000 memtest86+
directory/config/PaxHeaders.21794/archives 0000644 0000000 0000000 00000000132 12357513140 017062 x ustar 00 0000000 0000000 30 mtime=1404999264.309919538
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/archives/ 0000755 0001750 0000144 00000000000 12357513140 017003 5 ustar 00jblunck users 0000000 0000000 directory/config/archives/PaxHeaders.21794/debian.key.chroot 0000644 0000000 0000000 00000000132 12222300432 022355 x ustar 00 0000000 0000000 30 mtime=1380548890.449530815
30 atime=1405531215.102319719
30 ctime=1405531215.102319719
directory/config/archives/debian.key.chroot 0000644 0001750 0000144 00000000045 12222300432 022220 0 ustar 00jblunck users 0000000 0000000 a73043cf-7b16-42dc-b0d9-3031ed4370be
obs-build-20170201/t/dist 0000755 0001750 0001750 00000002711 13044631422 013362 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
use strict;
use Test::More tests => 9;
use Build;
sub d {
Build::dist_canon($_[0], $_[1]||'i586');
}
is(d("UnitedLinux 1.0 (x86-64)"), "ul1-x86_64");
is(d("SuSE SLES-8 (ia64)"), "sles8-ia64");
is(d("SuSE Linux 8.2 (x86-64)"), "8.2-x86_64");
is(d("SuSE SLES-9 (x86-64)"), "sles9-x86_64");
is(d("SUSE Linux 10.1 (PPC64)"), "10.1-ppc64");
is(d("SUSE Linux Enterprise 10 (PPC)"), "sles10-ppc");
is(d("openSUSE 10.3 (X86-64)"), "10.3-x86_64");
is(d("SUSE Linux Enterprise 11"), "sles11-i386");
is(d("openSUSE 11.3"), "11.3-i386");
obs-build-20170201/t/live-build 0000755 0001750 0001750 00000003736 13044631422 014463 0 ustar alee alee #!/usr/bin/perl -w -I ..
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
use strict;
use Test::More tests => 5;
use Build::LiveBuild;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
my $VAR = '
a
b
#comment
! whatever
';
is(Build::LiveBuild::filter($VAR), 'a
b
');
my $DEB_ARCHIVE = '
# comment
deb obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
deb-src obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
';
my $DEB_ARCHIVE_RESULT = "\$VAR1 = 'openSUSE.org:Debian:7.0/standard';
";
is(Dumper(Build::LiveBuild::parse_archive($DEB_ARCHIVE)), $DEB_ARCHIVE_RESULT);
my $config = {};
$Data::Dumper::Sortkeys = 1;
is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild'))),
'9cfb69e8f0581293f207342edacd19e7');
#print Dumper(Build::LiveBuild::parse( $config, 'standard.livebuild'));
is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild'))),
'bc803d2b4a375d9a02b3242117f6c93a');
#print Dumper(Build::LiveBuild::parse( $config, 'directory.livebuild'));
is(md5_hex(Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild'))),
'1e596160978007d1014e9c5e38574700');
#print Dumper(Build::LiveBuild::parse( $config, 'bad.livebuild'));
obs-build-20170201/t/bad.livebuild 0000644 0001750 0001750 00000120000 13044631422 015110 0 ustar alee alee ./PaxHeaders.6730/auto 0000644 0000000 0000000 00000000132 12222266372 013026 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
auto/ 0000755 0001750 0000144 00000000000 12222266372 012701 5 ustar 00jblunck users 0000000 0000000 auto/PaxHeaders.6730/clean 0000644 0000000 0000000 00000000132 12222266372 013753 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
auto/clean 0000755 0001750 0000144 00000000240 12222266372 013705 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb clean noauto "${@}"
rm -f config/binary config/bootstrap config/chroot config/common config/source
rm -f config/control
rm -f build.log
auto/PaxHeaders.6730/config 0000644 0000000 0000000 00000000132 12222266372 014136 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
auto/config 0000755 0001750 0000144 00000000626 12222266372 014100 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
case "$(dpkg --print-architecture)" in
amd64)
_LINUX_FLAVOURS="amd64"
_SOURCE="false"
;;
i386)
_LINUX_FLAVOURS="486 686-pae"
_SOURCE="true"
;;
esac
lb config noauto \
--clean \
--ignore-system-defaults \
--mode debian \
--debian-installer live \
--linux-flavours "${_LINUX_FLAVOURS}" \
--linux-packages "linux-image linux-headers" \
--source "${_SOURCE}" \
"${@}"
auto/PaxHeaders.6730/build 0000644 0000000 0000000 00000000132 12222266372 013770 x ustar 00 0000000 0000000 30 mtime=1380543738.699537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
auto/build 0000755 0001750 0000144 00000000112 12222266372 013720 0 ustar 00jblunck users 0000000 0000000 #!/bin/sh
set -e
lb build noauto "${@}" && echo $? 2>&1 | tee build.log
./PaxHeaders.6730/config 0000644 0000000 0000000 00000000132 12222300375 013313 x ustar 00 0000000 0000000 30 mtime=1380548861.684530853
30 atime=1404933484.298323059
30 ctime=1404933481.152361217
config/ 0000755 0001750 0000144 00000000000 12222300375 013166 5 ustar 00jblunck users 0000000 0000000 config/PaxHeaders.6730/bootloaders 0000644 0000000 0000000 00000000132 12222304630 015471 x ustar 00 0000000 0000000 30 mtime=1380551064.696527946
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/bootloaders/ 0000755 0001750 0000144 00000000000 12222304630 015501 5 ustar 00jblunck users 0000000 0000000 config/PaxHeaders.6730/package-lists 0000644 0000000 0000000 00000000132 12357312571 015717 x ustar 00 0000000 0000000 30 mtime=1404933497.776159592
30 atime=1404933498.247153879
30 ctime=1404933497.776159592
config/package-lists/ 0000755 0001750 0000144 00000000000 12357312571 015727 5 ustar 00jblunck users 0000000 0000000 config/package-lists/PaxHeaders.6730/installer.list.chroot 0000644 0000000 0000000 00000000132 12222266372 022161 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/package-lists/installer.list.chroot 0000644 0001750 0000144 00000000037 12222266372 022114 0 ustar 00jblunck users 0000000 0000000 debian-installer-launcher
sudo
config/package-lists/PaxHeaders.6730/live.list.chroot 0000644 0000000 0000000 00000000132 12222266372 021123 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/package-lists/live.list.chroot 0000644 0001750 0000144 00000000027 12222266372 021055 0 ustar 00jblunck users 0000000 0000000 live-manual
live-tools
config/package-lists/PaxHeaders.6730/localization.list.chroot 0000644 0000000 0000000 00000000132 12222266372 022654 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/package-lists/localization.list.chroot 0000644 0001750 0000144 00000000034 12222266372 022604 0 ustar 00jblunck users 0000000 0000000 task-english
console-tools
config/package-lists/PaxHeaders.6730/standard.list.chroot 0000644 0000000 0000000 00000000132 12222266372 021764 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933490.584246818
30 ctime=1404933481.152361217
config/package-lists/standard.list.chroot 0000644 0001750 0000144 00000000072 12222266372 021716 0 ustar 00jblunck users 0000000 0000000 ! Packages Priority standard
task-laptop
task-ssh-server
config/package-lists/PaxHeaders.6730/memtest 0000644 0000000 0000000 00000000132 12222266372 017373 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933486.633294738
30 ctime=1404933497.776159592
config/package-lists/memtest 0000644 0001750 0000144 00000000013 12222266372 017320 0 ustar 00jblunck users 0000000 0000000 memtest86+
config/PaxHeaders.6730/archives 0000644 0000000 0000000 00000000132 12222302706 014762 x ustar 00 0000000 0000000 30 mtime=1380550086.359529237
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/archives/ 0000755 0001750 0000144 00000000000 12222302706 014772 5 ustar 00jblunck users 0000000 0000000 config/archives/PaxHeaders.6730/debian.list.chroot 0000644 0000000 0000000 00000000132 12222302676 020461 x ustar 00 0000000 0000000 30 mtime=1380550078.121529248
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/archives/debian.list.chroot 0000644 0001750 0000144 00000000202 12222302676 020406 0 ustar 00jblunck users 0000000 0000000 deb obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
deb-src obs://openSUSE.org:Debian:7.0/standard wheezy main contrib
config/archives/PaxHeaders.6730/debian.key.chroot 0000644 0000000 0000000 00000000132 12222300432 020262 x ustar 00 0000000 0000000 30 mtime=1380548890.449530815
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
config/archives/debian.key.chroot 0000644 0001750 0000144 00000000045 12222300432 020214 0 ustar 00jblunck users 0000000 0000000 a73043cf-7b16-42dc-b0d9-3031ed4370be
./PaxHeaders.6730/README 0000644 0000000 0000000 00000000132 12222266372 013013 x ustar 00 0000000 0000000 30 mtime=1380543738.739537615
30 atime=1404933481.152361217
30 ctime=1404933481.152361217
README 0000644 0001750 0000144 00000000771 12222266372 012616 0 ustar 00jblunck users 0000000 0000000 This is the configuration tree for:
Debian Standard
A software called live-build can be used to automatically build images from
this configuration tree.
live-build can be obtained from .
On Debian based systems, live-build can be installed with:
# apt-get install live-build
More information about live-build and the Live Systems project can be found on
its homepage at and in the manual at
.
obs-build-20170201/getbuildids 0000755 0001750 0001750 00000004013 13044631422 014450 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 2016 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use Build;
use strict;
sub getbuildid {
my ($pkg) = @_;
my $d = Build::query($pkg, 'evra' => 1, 'buildtime' => 1);
return $d ? Build::getbuildid($d) : undef;
}
if (@ARGV && $ARGV[0] eq 'cachecheck') {
my $pkg;
my $buildid;
my $dst;
while () {
chomp;
if (/^PKG (\S+) (.+)$/) {
($pkg, $buildid, $dst) = ($1, $2, undef);
} elsif (/^PKG (\S+)$/) {
($pkg, $buildid, $dst) = ($1, undef, undef);
} elsif (/^DST (.+)$/) {
$dst = $1;
unlink($dst) if -e $dst;
} elsif (/^CACHE (.+)$/) {
next unless $dst;
my $cpkg = $1;
next unless -s $cpkg;
if ($buildid) {
my $bid = getbuildid($cpkg);
next unless $bid;
if ($bid =~ / 0-/) {
my $buildid2 = $buildid;
$buildid2 =~ s/ .*?-/0-/;
next if $bid ne $buildid2;
} else {
next if $bid ne $buildid;
}
}
symlink($cpkg, $dst);
$dst = undef; # first hit wins
}
}
exit(0);
}
while () {
chomp;
my $dst = $_;
my $buildid = getbuildid($dst);
next unless $buildid;
open(F, '>', "$dst.buildid") || next;
print F "$buildid\n";
close(F);
}
obs-build-20170201/README 0000644 0001750 0001750 00000000652 13044631422 013110 0 ustar alee alee
This is a tool to build binary packages in a safe and reproducible
way. The default is to build in a chroot sandbox, but it also
supports building in a virtual machine for better security.
The build tool can work with multiple package and recipe formats.
The currently supported package formats are deb, rpm, and arch.
The supported recipe formats are spec, dsc, kiwi, and PKGBUILD.
See the man page for more information.
obs-build-20170201/mkbaselibs 0000755 0001750 0001750 00000101652 13044631422 014274 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
use POSIX;
use strict;
use File::Temp qw/tempfile tempdir/;
# See: http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html#S3-RPM-FILE-FORMAT-HEADER-TAG-LISTING
# cf http://search.cpan.org/~davecross/Parse-RPM-Spec-0.01/lib/Parse/RPM/Spec.pm
my %STAG = (
"NAME" => 1000,
"VERSION" => 1001,
"RELEASE" => 1002,
"EPOCH" => 1003,
"SERIAL" => 1003,
"SUMMARY" => 1004,
"DESCRIPTION" => 1005,
"BUILDTIME" => 1006,
"BUILDHOST" => 1007,
"INSTALLTIME" => 1008,
"SIZE" => 1009,
"DISTRIBUTION" => 1010,
"VENDOR" => 1011,
"GIF" => 1012,
"XPM" => 1013,
"LICENSE" => 1014,
"COPYRIGHT" => 1014,
"PACKAGER" => 1015,
"GROUP" => 1016,
"SOURCE" => 1018,
"PATCH" => 1019,
"URL" => 1020,
"OS" => 1021,
"ARCH" => 1022,
"PREIN" => 1023,
"POSTIN" => 1024,
"PREUN" => 1025,
"POSTUN" => 1026,
"OLDFILENAMES" => 1027,
"FILESIZES" => 1028,
"FILESTATES" => 1029,
"FILEMODES" => 1030,
"FILERDEVS" => 1033,
"FILEMTIMES" => 1034,
"FILEMD5S" => 1035,
"FILELINKTOS" => 1036,
"FILEFLAGS" => 1037,
"FILEUSERNAME" => 1039,
"FILEGROUPNAME" => 1040,
"ICON" => 1043,
"SOURCERPM" => 1044,
"FILEVERIFYFLAGS" => 1045,
"ARCHIVESIZE" => 1046,
"PROVIDENAME" => 1047,
"PROVIDES" => 1047,
"REQUIREFLAGS" => 1048,
"REQUIRENAME" => 1049,
"REQUIREVERSION" => 1050,
"NOSOURCE" => 1051,
"NOPATCH" => 1052,
"CONFLICTFLAGS" => 1053,
"CONFLICTNAME" => 1054,
"CONFLICTVERSION" => 1055,
"EXCLUDEARCH" => 1059,
"EXCLUDEOS" => 1060,
"EXCLUSIVEARCH" => 1061,
"EXCLUSIVEOS" => 1062,
"RPMVERSION" => 1064,
"TRIGGERSCRIPTS" => 1065,
"TRIGGERNAME" => 1066,
"TRIGGERVERSION" => 1067,
"TRIGGERFLAGS" => 1068,
"TRIGGERINDEX" => 1069,
"VERIFYSCRIPT" => 1079,
"CHANGELOGTIME" => 1080,
"CHANGELOGNAME" => 1081,
"CHANGELOGTEXT" => 1082,
"PREINPROG" => 1085,
"POSTINPROG" => 1086,
"PREUNPROG" => 1087,
"POSTUNPROG" => 1088,
"BUILDARCHS" => 1089,
"OBSOLETENAME" => 1090,
"OBSOLETES" => 1090,
"VERIFYSCRIPTPROG" => 1091,
"TRIGGERSCRIPTPROG" => 1092,
"COOKIE" => 1094,
"FILEDEVICES" => 1095,
"FILEINODES" => 1096,
"FILELANGS" => 1097,
"PREFIXES" => 1098,
"INSTPREFIXES" => 1099,
"SOURCEPACKAGE" => 1106,
"PROVIDEFLAGS" => 1112,
"PROVIDEVERSION" => 1113,
"OBSOLETEFLAGS" => 1114,
"OBSOLETEVERSION" => 1115,
"DIRINDEXES" => 1116,
"BASENAMES" => 1117,
"DIRNAMES" => 1118,
"OPTFLAGS" => 1122,
"DISTURL" => 1123,
"PAYLOADFORMAT" => 1124,
"PAYLOADCOMPRESSOR" => 1125,
"PAYLOADFLAGS" => 1126,
"INSTALLCOLOR" => 1127,
"INSTALLTID" => 1128,
"REMOVETID" => 1129,
"RHNPLATFORM" => 1131,
"PLATFORM" => 1132,
"PATCHESNAME" => 1133,
"PATCHESFLAGS" => 1134,
"PATCHESVERSION" => 1135,
"CACHECTIME" => 1136,
"CACHEPKGPATH" => 1137,
"CACHEPKGSIZE" => 1138,
"CACHEPKGMTIME" => 1139,
"FILECOLORS" => 1140,
"FILECLASS" => 1141,
"CLASSDICT" => 1142,
"FILEDEPENDSX" => 1143,
"FILEDEPENDSN" => 1144,
"DEPENDSDICT" => 1145,
"SOURCEPKGID" => 1146,
"PRETRANS" => 1151,
"POSTTRANS" => 1152,
"PRETRANSPROG" => 1153,
"POSTTRANSPROG" => 1154,
"DISTTAG" => 1155,
"SUGGESTSNAME" => 1156,
"SUGGESTSVERSION" => 1157,
"SUGGESTSFLAGS" => 1158,
"ENHANCESNAME" => 1159,
"ENHANCESVERSION" => 1160,
"ENHANCESFLAGS" => 1161,
"PRIORITY" => 1162,
"CVSID" => 1163,
);
# do not mix numeric tags with symbolic tags.
# special symbolic tag 'FILENAME' exists.
# This function seems to take a set of tags and populates a global
# hash-table (%res) with data obtained by doing a binary unpack() on
# the raw package
# http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
sub rpmq_many {
my $rpm = shift;
my @stags = @_;
my $need_filenames = grep { $_ eq 'FILENAMES' } @stags;
push @stags, 'BASENAMES', 'DIRNAMES', 'DIRINDEXES', 'OLDFILENAMES' if $need_filenames;
@stags = grep { $_ ne 'FILENAMES' } @stags if $need_filenames;
my %stags = map {0+($STAG{$_} or $_) => $_} @stags;
my ($magic, $sigtype, $headmagic, $cnt, $cntdata, $lead, $head, $index, $data, $tag, $type, $offset, $count);
local *RPM;
if (ref($rpm) eq 'ARRAY') {
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $rpm->[0]);
if ($headmagic != 0x8eade801) {
warn("Bad rpm\n");
return ();
}
if (length($rpm->[0]) < 16 + $cnt * 16 + $cntdata) {
warn("Bad rpm\n");
return ();
}
$index = substr($rpm->[0], 16, $cnt * 16);
$data = substr($rpm->[0], 16 + $cnt * 16, $cntdata);
} else {
return () unless open(RPM, "<$rpm");
if (read(RPM, $lead, 96) != 96) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
($magic, $sigtype) = unpack('N@78n', $lead);
if ($magic != 0xedabeedb || $sigtype != 5) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
if (read(RPM, $head, 16) != 16) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
if ($headmagic != 0x8eade801) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
$cntdata = ($cntdata + 7) & ~7;
if (read(RPM, $data, $cntdata) != $cntdata) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
}
my %res = ();
if (ref($rpm) eq 'ARRAY' && @stags && @$rpm > 1) {
my %res2 = &rpmq_many([ $rpm->[1] ], @stags);
%res = (%res, %res2);
return %res;
}
if (ref($rpm) ne 'ARRAY' && @stags) {
if (read(RPM, $head, 16) != 16) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
if ($headmagic != 0x8eade801) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
if (read(RPM, $data, $cntdata) != $cntdata) {
warn("Bad rpm $rpm\n");
close RPM;
return ();
}
}
close RPM if ref($rpm) ne 'ARRAY';
return %res unless @stags; # nothing to do
while($cnt-- > 0) {
($tag, $type, $offset, $count, $index) = unpack('N4a*', $index);
$tag = 0+$tag;
if ($stags{$tag}) {
eval {
my $otag = $stags{$tag};
if ($type == 0) {
$res{$otag} = [ '' ];
} elsif ($type == 1) {
$res{$otag} = [ unpack("\@${offset}c$count", $data) ];
} elsif ($type == 2) {
$res{$otag} = [ unpack("\@${offset}c$count", $data) ];
} elsif ($type == 3) {
$res{$otag} = [ unpack("\@${offset}n$count", $data) ];
} elsif ($type == 4) {
$res{$otag} = [ unpack("\@${offset}N$count", $data) ];
} elsif ($type == 5) {
$res{$otag} = [ undef ];
} elsif ($type == 6) {
$res{$otag} = [ unpack("\@${offset}Z*", $data) ];
} elsif ($type == 7) {
$res{$otag} = [ unpack("\@${offset}a$count", $data) ];
} elsif ($type == 8 || $type == 9) {
my $d = unpack("\@${offset}a*", $data);
my @res = split("\0", $d, $count + 1);
$res{$otag} = [ splice @res, 0, $count ];
} else {
$res{$otag} = [ undef ];
}
};
if ($@) {
warn("Bad rpm $rpm: $@\n");
return ();
}
}
}
if ($need_filenames) {
if ($res{'OLDFILENAMES'}) {
$res{'FILENAMES'} = [ @{$res{'OLDFILENAMES'}} ];
} else {
my $i = 0;
$res{'FILENAMES'} = [ map {"$res{'DIRNAMES'}->[$res{'DIRINDEXES'}->[$i++]]$_"} @{$res{'BASENAMES'}} ];
}
}
return %res;
}
sub rpmq_add_flagsvers {
my $res = shift;
my $name = shift;
my $flags = shift;
my $vers = shift;
return unless $res;
my @flags = @{$res->{$flags} || []};
my @vers = @{$res->{$vers} || []};
for (@{$res->{$name}}) {
if (@flags && ($flags[0] & 0xe) && @vers) {
$_ .= ' ';
$_ .= '<' if $flags[0] & 2;
$_ .= '>' if $flags[0] & 4;
$_ .= '=' if $flags[0] & 8;
$_ .= " $vers[0]";
}
shift @flags;
shift @vers;
}
}
my @preamble = qw{
Name Version Release Epoch Summary Copyright License Distribution
Disturl Vendor Group Packager Url Icon Prefixes
};
my $rpm;
my $arch;
my $config = '';
my $targettype;
my $targetarch;
my $prefix;
my $extension;
my $configdir;
my $targetname;
my $legacyversion;
my @baselib;
my @config;
my @provides;
my @obsoletes;
my @requires;
my @prerequires;
my @conflicts;
my @recommends;
my @supplements;
my @suggests;
my @prein;
my @postin;
my @preun;
my @postun;
my $autoreqprov;
my $verbose;
my %target_matched;
my @filesystem;
# Used for each package by
sub parse_config {
my $target = shift;
my $pkgname = shift;
my $pkgver = shift;
my $pkghasmatched;
my $pkgmatches = 1;
$prefix = '';
$legacyversion = '';
$extension = '';
$configdir = '';
$targetname = '';
($targetarch, $targettype) = split(':', $target, 2);
@baselib = ();
@config = ();
@provides = ();
@obsoletes = ();
@requires = ();
@recommends = ();
@supplements = ();
@suggests = ();
@prerequires = ();
@conflicts = ();
@prein = ();
@postin = ();
@preun = ();
@postun = ();
$autoreqprov = 'on';
my $match1 = '';
for (split("\n", $config)) {
s/^\s+//;
s/\s+$//;
next if $_ eq '' || $_ =~ /^#/;
s/\/$targettype/g;
s/\/$targetarch/g;
s/\/$pkgname/g;
s/\/$pkgver/g;
s/\/$prefix/g;
s/\/$extension/g;
s/\/$configdir/g;
s/\/$match1/g;
if (/^arch\s+/) {
next unless s/^arch\s+\Q$arch\E\s+//;
}
next if /^targets\s+/;
if (/\s+package\s+[-+_a-zA-Z0-9]+$/) {
$pkgmatches = 0; # XXX: hack
}
if (/\s+package\s+\/[-+_a-zA-Z0-9]+\/$/) {
$pkgmatches = 0; # XXX: hack
}
if (/^targettype\s+/) {
next unless s/^targettype\s+\Q$targettype\E\s+//;
}
if (/^targetarch\s+/) {
next unless s/^targetarch\s+\Q$targetarch\E\s+//;
}
if (/^prefix\s+(.*?)$/) { $prefix = $1; next; }
if (/^legacyversion\s+(.*?)$/) { $legacyversion = $1; next; }
if (/^extension\s+(.*?)$/) { $extension = $1; next; }
if (/^configdir\s+(.*?)$/) { $configdir= $1; next; }
if (/^targetname\s+(.*?)$/) { $targetname = $1; next; }
$_ = "baselib $_" if /^[\+\-\"]/;
$_ = "package $_" if /^[-+_a-zA-Z0-9]+$/;
if (/^package\s+\/(.*?)\/$/) {
my $pm = $1;
$pkgmatches = $pkgname =~ /$pm/;
$match1 = $1 if defined $1;
$pkghasmatched |= $pkgmatches if $pkgname =~ /-debuginfo$/ && $target_matched{$target};
next;
}
if (/^package\s+(.*?)$/) {
$pkgmatches = $1 eq $pkgname;
$pkghasmatched |= $pkgmatches;
next;
}
next unless $pkgmatches;
return 0 if $_ eq 'block!';
if (/^provides\s+(.*?)$/) { push @provides, $1; next; }
if (/^requires\s+(.*?)$/) { push @requires, $1; next; }
if (/^recommends\s+(.*?)$/) { push @recommends, $1; next; }
if (/^supplements\s+(.*?)$/) { push @supplements, $1; next; }
if (/^suggests\s+(.*?)$/) { push @suggests, $1; next; }
if (/^prereq\s+(.*?)$/) { push @prerequires, $1; next; }
if (/^obsoletes\s+(.*?)$/) { push @obsoletes, $1; next; }
if (/^conflicts\s+(.*?)$/) { push @conflicts, $1; next; }
if (/^baselib\s+(.*?)$/) { push @baselib, $1; next; }
if (/^config\s+(.*?)$/) { push @config, $1; next; }
if (/^pre(in)?\s+(.*?)$/) { push @prein, $2; next; }
if (/^post(in)?\s+(.*?)$/) { push @postin, $2; next; }
if (/^preun\s+(.*?)$/) { push @preun, $1; next; }
if (/^postun\s+(.*?)$/) { push @preun, $1; next; }
if (/^autoreqprov\s+(.*?)$/) {$autoreqprov = $1; next; }
die("bad line: $_\n");
}
return $pkghasmatched;
}
sub read_config {
my $cfname = shift;
local *F;
open(F, "<$cfname") || die("$cfname: $!\n");
my @cf = ;
close F;
$config .= join('', @cf);
$config .= "\npackage __does_not_match__\n";
}
sub get_targets {
my $architecture = shift;
my $conf = shift;
my %targets;
for (split("\n", $conf)) {
if (/^arch\s+/) {
next unless s/^arch\s+\Q$architecture\E\s+//;
}
if (/^targets\s+(.*?)$/) {
$targets{$_} = 1 for split(' ', $1);
}
}
my @targets = sort keys %targets;
return @targets;
}
# Packages listed in config file
sub get_pkgnames {
my %rpms;
for (split("\n", $config)) {
if (/^(.*\s+)?package\s+([-+_a-zA-Z0-9]+)\s*$/) { # eg : arch ppc package libnuma-devel
$rpms{$2} = 1;
} elsif (/^\s*([-+_a-zA-Z0-9]+)\s*$/) { # eg: readline-devel
$rpms{$1} = 1;
}
}
return sort keys %rpms;
}
# Packages listed in config file - debian variant (can have "." in package names)
sub get_debpkgnames {
my %debs;
for (split("\n", $config)) {
if (/^(.*\s+)?package\s+([-+_a-zA-Z0-9.]+)\s*$/) { # eg : arch ppc package libnuma-devel
$debs{$2} = 1;
} elsif (/^\s*([-+_a-zA-Z0-9.]+)\s*$/) { # eg: readline-devel
$debs{$1} = 1;
}
}
return sort keys %debs;
}
sub handle_rpms {
for $rpm (@_) {
my @stags = map {uc($_)} @preamble;
push @stags, 'DESCRIPTION';
push @stags, 'FILENAMES', 'FILEMODES', 'FILEUSERNAME', 'FILEGROUPNAME', 'FILEFLAGS', 'FILEVERIFYFLAGS';
push @stags, 'CHANGELOGTIME', 'CHANGELOGNAME', 'CHANGELOGTEXT';
push @stags, 'ARCH', 'SOURCERPM', 'RPMVERSION';
push @stags, 'BUILDTIME';
my %res = rpmq_many($rpm, @stags);
die("$rpm: bad rpm\n") unless $res{'NAME'};
my $rname = $res{'NAME'}->[0];
my $sname = $res{'SOURCERPM'}->[0];
die("$rpm is a sourcerpm\n") unless $sname;
die("bad sourcerpm: $sname\n") unless $sname =~ /^(.*)-([^-]+)-([^-]+)\.(no)?src\.rpm$/;
$sname = $1;
my $sversion = $2;
my $srelease = $3;
$arch = $res{'ARCH'}->[0];
my @targets = get_targets($arch, $config);
if (!@targets) {
print "no targets for arch $arch, skipping $rname\n";
next;
}
for my $target (@targets) {
next unless parse_config($target, $res{'NAME'}->[0], $res{'VERSION'}->[0]);
die("targetname not set\n") unless $targetname;
$target_matched{$target} = 1;
my %ghosts;
my @rpmfiles = @{$res{'FILENAMES'}};
my @ff = @{$res{'FILEFLAGS'}};
for (@rpmfiles) {
$ghosts{$_} = 1 if $ff[0] & (1 << 6);
shift @ff;
}
my %files;
my %cfiles;
my %moves;
my %symlinks;
for my $r (@baselib) {
my $rr = substr($r, 1);
if (substr($r, 0, 1) eq '+') {
if ($rr =~ /^(.*?)\s*->\s*(.*?)$/) {
if (grep {$_ eq $1} @rpmfiles) {
$files{$1} = 1;
$moves{$1} = $2;
}
} else {
for (grep {/$rr/} @rpmfiles) {
$files{$_} = 1;
delete $moves{$_};
}
}
} elsif (substr($r, 0, 1) eq '-') {
delete $files{$_} for grep {/$rr/} keys %files;
} elsif (substr($r, 0, 1) eq '"') {
$rr =~ s/\"$//;
if ($rr =~ /^(.*?)\s*->\s*(.*?)$/) {
$symlinks{$1} = $2;
} else {
die("bad baselib string rule: $r\n");
}
} else {
die("bad baselib rule: $r\n");
}
}
if ($configdir) {
for my $r (@config) {
my $rr = substr($r, 1);
if (substr($r, 0, 1) eq '+') {
$cfiles{$_} = 1 for grep {/$rr/} grep {!$ghosts{$_}} @rpmfiles;
} elsif (substr($r, 0, 1) eq '-') {
delete $cfiles{$_} for grep {/$rr/} keys %cfiles;
} else {
die("bad config rule: $r\n");
}
}
}
$files{$_} = 1 for keys %cfiles;
if (!%files) {
print "$rname($target): empty filelist, skipping rpm\n";
next;
}
my $i = 0;
for (@{$res{'FILENAMES'}}) {
$files{$_} = $i if $files{$_};
$i++;
}
my %cpiodirs;
for (keys %files) {
next if $cfiles{$_} || $moves{$_};
my $fn = $_;
next unless $fn =~ s/\/[^\/]+$//;
$cpiodirs{$fn} = 1;
}
my %alldirs;
for (keys %files) {
next if $cfiles{$_};
my $fn = $_;
if ($moves{$fn}) {
$fn = $moves{$fn};
next unless $fn =~ s/\/[^\/]+$//;
$alldirs{$fn} = 1;
} else {
next unless $fn =~ s/\/[^\/]+$//;
$alldirs{"$prefix$fn"} = 1;
}
}
$alldirs{$_} = 1 for keys %symlinks;
$alldirs{$configdir} = 1 if %cfiles;
my $ad;
for $ad (keys %alldirs) {
$alldirs{$ad} = 1 while $ad =~ s/\/[^\/]+$//;
}
for (keys %files) {
next if $cfiles{$_};
my $fn = $_;
if ($moves{$fn}) {
delete $alldirs{$moves{$fn}};
} else {
delete $alldirs{"$prefix$fn"};
}
}
delete $alldirs{$_} for keys %symlinks;
$ad = $prefix;
delete $alldirs{$ad};
delete $alldirs{$ad} while $ad =~ s/\/[^\/]+$//;
delete $alldirs{$_} for @filesystem;
print "$rname($target): writing specfile...\n";
my ($fh, $specfile) = tempfile(SUFFIX => ".spec");
open(SPEC, ">&=", $fh) || die("open: $!\n");
for my $p (@preamble) {
my $pt = uc($p);
next unless $res{$pt};
my $d = $res{$pt}->[0];
$d =~ s/%/%%/g;
if ($p eq 'Name') {
print SPEC "Name: $sname\n";
next;
}
if ($p eq 'Version') {
print SPEC "Version: $sversion\n";
next;
}
if ($p eq 'Release') {
print SPEC "Release: $srelease\n";
next;
}
if ($p eq 'Disturl') {
print SPEC "%define disturl $d\n";
next;
}
print SPEC "$p: $d\n";
}
print SPEC "Source: $rpm\n";
print SPEC "NoSource: 0\n" if $res{'SOURCERPM'}->[0] =~ /\.nosrc\.rpm$/;
print SPEC "BuildRoot: %{_tmppath}/baselibs-%{name}-%{version}-build\n";
print SPEC "%define _target_cpu $targetarch\n";
print SPEC "%define __os_install_post %{nil}\n";
print SPEC "%description\nUnneeded main package. Ignore.\n\n";
print SPEC "%package -n $targetname\n";
for my $p (@preamble) {
next if $p eq 'Name' || $p eq 'Disturl';
my $pt = uc($p);
next unless $res{$pt};
my $d = $res{$pt}->[0];
$d =~ s/%/%%/g;
if ($pt eq 'VERSION' && $legacyversion) {
$d = $legacyversion;
} elsif ($pt eq 'RELEASE' && $legacyversion) {
my @bt = localtime($res{'BUILDTIME'}->[0]);
$bt[5] += 1900;
$bt[4] += 1;
$d = sprintf("%04d%02d%02d%02d%02d\n", @bt[5,4,3,2,1]);
}
print SPEC "$p: $d\n";
}
print SPEC "Autoreqprov: $autoreqprov\n";
for my $ar ([\@provides, 'provides'],
[\@prerequires, 'prereq'],
[\@requires, 'requires'],
[\@recommends, 'recommends'],
[\@supplements, 'supplements'],
[\@obsoletes, 'obsoletes'],
[\@conflicts, 'conflicts']) {
my @a = @{$ar->[0]};
my @na = ();
for (@a) {
if (substr($_, 0, 1) eq '"') {
die("bad $ar->[1] rule: $_\n") unless /^\"(.*)\"$/;
push @na, $1;
} elsif (substr($_, 0, 1) eq '-') {
my $ra = substr($_, 1);
@na = grep {!/$ra/} @na;
} else {
die("bad $ar->[1] rule: $_\n");
}
}
print SPEC ucfirst($ar->[1]).": $_\n" for @na;
}
my $cpiopre = '';
$cpiopre = './' if $res{'RPMVERSION'}->[0] !~ /^3/;
my $d = $res{'DESCRIPTION'}->[0];
$d =~ s/%/%%/g;
if ($legacyversion) {
$d = "This rpm was re-packaged from $res{'NAME'}->[0]-$res{'VERSION'}->[0]-$res{'RELEASE'}->[0]\n\n$d";
}
print SPEC "\n%description -n $targetname\n";
print SPEC "$d\n";
print SPEC "%prep\n";
print SPEC "%build\n";
print SPEC "%install\n";
print SPEC "rm -rf \$RPM_BUILD_ROOT\n";
print SPEC "mkdir \$RPM_BUILD_ROOT\n";
print SPEC "cd \$RPM_BUILD_ROOT\n";
my @cfl = grep {!$cfiles{$_} && !$moves{$_}} sort keys %files;
if (@cfl) {
if ($prefix ne '') {
print SPEC "mkdir -p \$RPM_BUILD_ROOT$prefix\n";
print SPEC "pushd \$RPM_BUILD_ROOT$prefix\n";
}
print SPEC "cat <.filelist\n";
print SPEC "$_\n" for map {$cpiopre.substr($_, 1)} @cfl;
print SPEC "EOFL\n";
print SPEC "mkdir -p \$RPM_BUILD_ROOT$prefix$_\n" for sort keys %cpiodirs;
print SPEC "rpm2cpio $rpm | cpio -i -d -v -E .filelist\n";
print SPEC "rm .filelist\n";
if (%ghosts) {
for my $fn (grep {$ghosts{$_}} @cfl) {
my $fnm = $fn;
$fnm = '.' unless $fnm =~ s/\/[^\/]+$//;
print SPEC "mkdir -p \$RPM_BUILD_ROOT$prefix$fnm\n";
print SPEC "touch \$RPM_BUILD_ROOT$prefix$fn\n";
}
}
if ($prefix ne '') {
print SPEC "popd\n";
}
}
if (%cfiles || %moves) {
print SPEC "mkdir -p .cfiles\n";
print SPEC "pushd .cfiles\n";
print SPEC "cat <.filelist\n";
print SPEC "$_\n" for map {$cpiopre.substr($_, 1)} grep {$cfiles{$_} || $moves{$_}} sort keys %files;
print SPEC "EOFL\n";
print SPEC "rpm2cpio $rpm | cpio -i -d -v -E .filelist\n";
print SPEC "popd\n";
if (%cfiles) {
print SPEC "mkdir -p \$RPM_BUILD_ROOT$configdir\n";
print SPEC "mv .cfiles$_ \$RPM_BUILD_ROOT$configdir\n" for sort keys %cfiles;
}
for my $fn (sort keys %moves) {
my $fnm = $moves{$fn};
$fnm = '.' unless $fnm =~ s/\/[^\/]+$//;
print SPEC "mkdir -p \$RPM_BUILD_ROOT$fnm\n";
print SPEC "mv .cfiles$fn \$RPM_BUILD_ROOT$moves{$fn}\n";
}
print SPEC "rm -rf .cfiles\n";
}
for my $fn (sort keys %symlinks) {
my $fnm = $fn;
$fnm = '.' unless $fnm =~ s/\/[^\/]+$//;
print SPEC "mkdir -p \$RPM_BUILD_ROOT$fnm\n";
print SPEC "ln -s $symlinks{$fn} \$RPM_BUILD_ROOT$fn\n";
}
if ($prefix ne '' && grep {/\.so.*$/} @cfl) {
@postin = () if @postin == 1 && $postin[0] =~ /^\"-p.*ldconfig/;
unshift @postin, "\"/sbin/ldconfig -r $prefix\"";
}
if (@prein) {
print SPEC "%pre -n $targetname";
print SPEC $prein[0] =~ /^\"-p/ ? " " : "\n";
for (@prein) {
die("bad prein rule: $_\n") unless /^\"(.*)\"$/;
print SPEC "$1\n";
}
}
if (@postin) {
print SPEC "%post -n $targetname";
print SPEC $postin[0] =~ /^\"-p/ ? " " : "\n";
for (@postin) {
die("bad postin rule: $_\n") unless /^\"(.*)\"$/;
print SPEC "$1\n";
}
}
if (@preun) {
print SPEC "%preun -n $targetname";
print SPEC $preun[0] =~ /^\"-p/ ? " " : "\n";
for (@preun) {
die("bad preun rule: $_\n") unless /^\"(.*)\"$/;
print SPEC "$1\n";
}
}
if (@postun) {
print SPEC "%postun -n $targetname";
print SPEC $postun[0] =~ /^\"-p/ ? " " : "\n";
for (@postun) {
die("bad postun rule: $_\n") unless /^\"(.*)\"$/;
print SPEC "$1\n";
}
}
print SPEC "\n%clean\n";
print SPEC "\nrm -rf \$RPM_BUILD_ROOT\n\n";
print SPEC "%files -n $targetname\n";
for my $file (sort keys %alldirs) {
print SPEC "%dir %attr(0755,root,root) $file\n";
}
for my $file (keys %files) {
my $fi = $files{$file};
my $fm = $res{'FILEMODES'}->[$fi];
my $fv = $res{'FILEVERIFYFLAGS'}->[$fi];
my $ff = $res{'FILEFLAGS'}->[$fi];
if (POSIX::S_ISDIR($fm)) {
print SPEC "%dir ";
}
if ($ff & ((1 << 3) | (1 << 4))) {
print SPEC "%config(missingok noreplace) ";
} elsif ($ff & (1 << 3)) {
print SPEC "%config(missingok) ";
} elsif ($ff & (1 << 4)) {
print SPEC "%config(noreplace) ";
} elsif ($ff & (1 << 0)) {
print SPEC "%config ";
}
print SPEC "%doc " if $ff & (1 << 1);
print SPEC "%ghost " if $ff & (1 << 6);
print SPEC "%license " if $ff & (1 << 7);
print SPEC "%readme " if $ff & (1 << 8);
if ($fv != 4294967295) {
print SPEC "%verify(";
if ($fv & 2147483648) {
print SPEC "not ";
$fv ^= 4294967295;
}
print SPEC "md5 " if $fv & (1 << 0);
print SPEC "size " if $fv & (1 << 1);
print SPEC "link " if $fv & (1 << 2);
print SPEC "user " if $fv & (1 << 3);
print SPEC "group " if $fv & (1 << 4);
print SPEC "mtime " if $fv & (1 << 5);
print SPEC "mode " if $fv & (1 << 6);
print SPEC "rdev " if $fv & (1 << 7);
print SPEC ") ";
}
#sigh, no POSIX::S_ISLNK ...
if (($fm & 0170000) == 0120000) {
printf SPEC "%%attr(-,%s,%s) ", $res{'FILEUSERNAME'}->[$fi], $res{'FILEGROUPNAME'}->[$fi];
} else {
printf SPEC "%%attr(%03o,%s,%s) ", $fm & 07777, $res{'FILEUSERNAME'}->[$fi], $res{'FILEGROUPNAME'}->[$fi];
}
if ($cfiles{$file}) {
my $fn = $file;
$fn =~ s/.*\///;
print SPEC "$configdir/$fn\n";
} else {
if ($moves{$file}) {
print SPEC "$moves{$file}\n";
} else {
print SPEC "$prefix$file\n";
}
}
}
for (keys %symlinks) {
printf SPEC "%%attr(-,root,root) $_\n";
}
if ($res{'CHANGELOGTEXT'}) {
print SPEC "\n%changelog -n $targetname\n";
my @ct = @{$res{'CHANGELOGTIME'}};
my @cn = @{$res{'CHANGELOGNAME'}};
my @wdays = qw{Sun Mon Tue Wed Thu Fri Sat};
my @months = qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec};
for my $cc (@{$res{'CHANGELOGTEXT'}}) {
my @lt = localtime($ct[0]);
my $cc2 = $cc;
my $cn2 = $cn[0];
$cc2 =~ s/%/%%/g;
$cn2 =~ s/%/%%/g;
printf SPEC "* %s %s %02d %04d %s\n%s\n", $wdays[$lt[6]], $months[$lt[4]], $lt[3], 1900 + $lt[5], $cn2, $cc2;
shift @ct;
shift @cn;
}
}
close(SPEC) || die("$specfile: $!\n");
print "$rname($target): running build...\n";
if (system("rpmbuild -bb $specfile".($verbose ? '' : '>/dev/null 2>&1'))) {
print "rpmbuild failed: $?\n";
print "re-running in verbose mode:\n";
system("rpmbuild -bb $specfile 2>&1");
exit(1);
}
unlink($specfile);
}
}
}
################################################################
sub handle_debs {
eval {
require Parse::DebControl;
};
if ($@){
print "mkbaselibs needs the perl module Parse::DebControl\n".
"Error. baselibs-deb.conf specified but mkbaselibs can't run\n".
"Please ensure that 'osc meta prjconf' contains the following line:\n".
" Support: libparse-debcontrol-perl\n";
return;
};
# for each deb:
# look in the config file to see if we should be doing anything
#
# Unpack the deb control data using dpkg-deb
# for each target
# Unpack the deb control data *and* file data using dpkg-deb
# process the config file for this package modifying control and moving files
# repackage the target deb
for my $deb (@_) {
# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
# unpack the outer loop control file - this gives us eg: the arch
my $base = tempdir() || die("tempdir: $!\n");
system "dpkg -e $deb ${base}/DEBIAN" || die "dpkg -e failed on $deb";
my $controlParser = new Parse::DebControl;
$controlParser->DEBUG();
my $keys = $controlParser->parse_file("${base}/DEBIAN/control");
# print Dumper($keys);
# DebControl supports multiple paragraphs of control data but
# debian/control in a .deb only has one (whereas a debian/control
# in a build root contains many)
# So extract the ref to the first one.
my %control = %{@{$keys}[0]};
# Validate this is a binary deb and get the control data
my $d_name = $control{'Package'};
my $d_version = $control{'Version'};
$arch = $control{'Architecture'}; # set global $arch
# examine the
# arch targets [:] [[:]...]
# line and get a list of target_arch-es
my @targets = get_targets($arch, $config);
if (!@targets) {
print "no targets for arch $arch, skipping $d_name\n";
next; # there may be more debs to handle
}
for my $target (@targets) {
next unless parse_config($target, $d_name, $d_version);
die("targetname not set\n") unless $targetname; # set in the global_conf
$target_matched{$target} = 1;
my $baseTarget = "${base}/$target";
# Unpack a .deb to work on. We have to do this each time as we
# manipulate the unpacked files.
system "mkdir ${base}/$target";
system "dpkg -e $deb ${baseTarget}/DEBIAN" || die "dpkg -e failed on $deb";
# Note that extracting to $prefix does the clever move to /lib-x86/ or whatever
system "dpkg -x $deb ${baseTarget}/$prefix" || die "dpkg -x failed on $deb";
# Reset the control data
$keys = $controlParser->parse_file("${baseTarget}/DEBIAN/control");
%control = %{@{$keys}[0]};
# Force the architecture
$control{'Architecture'} = $targetarch;
# Currently this script does not manipulate any files
# If needed they are all unpacked in ${baseTarget}
# we don't need a dsc/spec file.. all done by just moving files around
# and running dpkg -b ${base} $NEW_DEB
#
# my $dscfile = "/usr/src/packages/DSCS/mkbaselibs$$.dsc";
print "$d_name($target): writing dscfile...\n";
# We can Use Parse::DebControl write_file to create the new control file
# just modify tags in there
# We'll use requires -> Depends:
map s/^"(.*)"$/$1/, @requires; # remove leading/trailing "s
$control{"Depends"} = @requires ? join(", ", @requires) : ""; # join array if exists or reset it to ""
map s/^"(.*)"$/$1/, @prerequires;
$control{"Pre-Depends"} = @prerequires ? join(", ", @prerequires) : "";
map s/^"(.*)"$/$1/, @provides;
$control{"Provides"} = @provides ? join(", ", @provides) : "";
map s/^"(.*)"$/$1/, @recommends;
$control{"Recommends"} = @recommends ? join(", ", @recommends) : "";
map s/^"(.*)"$/$1/, @suggests;
$control{"Suggests"} = @suggests ? join(", ", @suggests) : "";
map s/^"(.*)"$/$1/, @obsoletes;
$control{"Replaces"} = @obsoletes ? join(", ", @obsoletes) : "";
map s/^"(.*)"$/$1/, @conflicts;
$control{"Conflicts"} = @conflicts ? join(", ", @conflicts) : "";
map s/^"(.*)"$/$1/, @supplements;
$control{"Enhances"} = @supplements ? join(", ", @supplements) : "";
# Tidy up the various control files.
# the md5sums are regenerated by dpkg-deb when building
foreach my $c_file ( qw(conffiles postins postrm preinst prerm) ) {
unlink "${baseTarget}/DEBIAN/$c_file";
}
# Create them if needed
if (@prein) {
map s/^"(.*)"$/$1/, @prein; # remove leading/trailing "s
open(my $SCRIPT, ">${baseTarget}/DEBIAN/preinst");
print $SCRIPT join("\n", @prein) ;
chmod(0755, $SCRIPT);
close($SCRIPT);
}
if (@postin) {
map s/^"(.*)"$/$1/, @postin;
open(my $SCRIPT, ">${baseTarget}/DEBIAN/postinst");
print $SCRIPT join("\n", @postin) ;
chmod(0755, $SCRIPT);
close($SCRIPT);
}
if (@preun) {
map s/^"(.*)"$/$1/, @preun;
open(my $SCRIPT, ">${baseTarget}/DEBIAN/prerm");
print $SCRIPT join("\n", @preun) ;
chmod(0755, $SCRIPT);
close($SCRIPT);
}
if (@postun) {
map s/^"(.*)"$/$1/, @postun;
open(my $SCRIPT, ">${baseTarget}/DEBIAN/postrm");
print $SCRIPT join("\n", @postun) ;
chmod(0755, $SCRIPT);
close($SCRIPT);
}
# Don't forget to rename the package - or it will replace/uninstall the /-based one
$control{"Package"} = "${d_name}-${targettype}";
$controlParser->write_file("${baseTarget}/DEBIAN/control", \%control, {clobberFile => 1, addNewline=>1 } );
system "dpkg -b ${baseTarget} /usr/src/packages/DEBS/${d_name}-${targettype}_${d_version}_${targetarch}.deb" || die "dpkg -b failed on $deb";
system "rm -rf ${baseTarget}";
}
system "rm -rf ${base}";
}
}
# args is a list of full pathnames to rpm/deb files
die("Usage: mkbaselibs \n") unless @ARGV;
if ($ARGV[0] eq '-v') {
$verbose = 1;
shift @ARGV;
}
while ($ARGV[0] eq '-c') {
shift @ARGV;
read_config($ARGV[0]);
shift @ARGV;
}
my %goodpkgs = map {$_ => 1} get_pkgnames(); # These are packages named in the config file
my @pkgs = @ARGV;
my @rpms;
my @debugrpms;
for my $rpm (@pkgs) {
my $rpmn = $rpm;
unless (-f $rpm) {
warn ("$rpm does not exist, skipping\n");
next;
}
my @rpmfiles = `rpm -qp --queryformat "[%{FILENAMES}\n]" $rpm`;
if (!@rpmfiles) {
warn ("$rpm is empty, skipping\n");
next;
}
next if $rpm =~ /\.(no)?src\.rpm$/; # ignore source rpms
next if $rpm =~ /\.spm$/;
$rpmn =~ s/.*\///; # Remove leading path info
$rpmn =~ s/-[^-]+-[^-]+\.[^\.]+\.rpm$/\.rpm/; # remove all version info
$rpmn =~ s/\.rpm$//; # remove extension
push @rpms, $rpm if $goodpkgs{$rpmn};
if ($rpmn =~ s/-debuginfo$//) {
push @debugrpms, $rpm if $goodpkgs{$rpmn};
}
}
for (@rpms) {
die("$_: need absolute path to package\n") unless /^\//;
}
my %debs_to_process = map {$_ => 1} get_debpkgnames(); # These are packages named in the config file
my @debs;
for my $deb (@pkgs) {
my $debn = $deb;
next unless $debn =~ /\.deb$/;
my @debfiles = `dpkg --contents $deb`;
if (!@debfiles) {
warn ("$deb is empty, skipping\n");
next;
}
$debn =~ s/.*\///; # Remove leading path info
$debn =~ s/_[^_]+_[^_]+\.deb$//; # remove all version info and extension
push @debs, $deb if $debs_to_process{$debn};
print "ignoring $deb as $debn not in baselibs.conf\n" if !$debs_to_process{$debn};
}
for (@debs) {
die("$_: need absolute path to package\n") unless /^\//;
}
exit 0 unless @rpms or @debs;
if (@rpms) {
@filesystem = split("\n", `rpm -ql filesystem 2>/dev/null`);
die("filesystem rpm is not installed\n") unless @filesystem;
handle_rpms(@rpms);
handle_rpms(@debugrpms);
}
if (@debs) {
handle_debs(@debs);
}
obs-build-20170201/emulator/ 0000755 0001750 0001750 00000000000 13044631422 014055 5 ustar alee alee obs-build-20170201/emulator/emulator.sh 0000755 0001750 0001750 00000002647 13044631422 016255 0 ustar alee alee #!/bin/bash
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
echo "ERROR: the emulator.sh script needs to be changed to support your emulator!"
exit 1
###
### Example for the aarch64 emulator:
###
LOG=$(mktemp)
./Foundation_v8 --image ./img-foundation.axf \
--block-device "$1" \
--network=none &> $LOG &
while test 0$(grep -c terminal_0: $LOG ) -lt 1; do
echo ".."
sleep 1
done
cat $LOG
# terminal_0: Listening for serial connection on port 5012
PORT=$(grep terminal_0: $LOG | head -n 1 | cut -d " " -f 8)
rm -f $LOG
# telnet dies when emulator is quiting
telnet 127.0.0.1 $PORT || exit 0
obs-build-20170201/build-vm-emulator 0000644 0001750 0001750 00000004712 13044631422 015521 0 ustar alee alee #
# generic emulator specific functions
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
vm_verify_options_emulator() {
if test -f "$BUILD_DIR/emulator/verify-options.sh"; then
. "$BUILD_DIR/emulator/verify-options.sh"
else
VM_SWAP=
fi
}
vm_startup_emulator() {
pushd "$BUILD_DIR/emulator"
if test -z "$EMULATOR_SCRIPT" ; then
EMULATOR_SCRIPT=./emulator.sh
elif test "${EMULATOR_SCRIPT:0:1}" != / ; then
EMULATOR_SCRIPT="./$EMULATOR_SCRIPT"
fi
set -- "$EMULATOR_SCRIPT" "$VM_IMAGE" "$VM_SWAP"
echo "$@"
if ! "$@"; then
popd
cleanup_and_exit 3 "ERROR: The emulator returned with a failure"
fi
popd
test -n "$VM_SWAP" && return
# Emulators may not offer to use a second swap space.
# So we just mount the filesystem.
# WARNING: This is not safe against attacks.
mkdir -p $BUILD_ROOT/.build.packages
cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
mkdir -p .mount
mount $VM_IMAGE -o loop .mount
if test -e .mount/.build.packages ; then
cp -a .mount/.build.packages/* .
fi
exitcode=`cat .mount/.build/_exitcode`
umount .mount
rmdir .mount
cleanup_and_exit "$exitcode"
}
vm_kill_emulator() {
if ! fuser -k -TERM "$VM_IMAGE" ; then
cleanup_and_exit 1 "could not kill build in $VM_IMAGE"
fi
}
vm_fixup_emulator() {
# emulator may not be able to hand over kernel parameters
ln -sf /.build/build $BUILD_ROOT/sbin/init
}
vm_attach_root_emulator() {
:
}
vm_attach_swap_emulator() {
:
}
vm_detach_root_emulator() {
:
}
vm_detach_swap_emulator() {
:
}
vm_cleanup_emulator() {
:
}
vm_wipe_emulator() {
:
}
obs-build-20170201/common_functions 0000755 0001750 0001750 00000011311 13044631422 015530 0 ustar alee alee #!/bin/bash
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
build_host_arch() {
: ${BUILD_HOST_ARCH:=`uname -m`}
# the linux kernel only knows armv7l, armv7hl is a userland definition
test armv7l == "$BUILD_HOST_ARCH" && BUILD_HOST_ARCH=armv7hl
BUILD_INITVM_ARCH="$BUILD_HOST_ARCH"
# avoid multiple initvm.* helpers for i586 and i686
test i686 != "$BUILD_INITVM_ARCH" || BUILD_INITVM_ARCH=i586
}
extend_build_arch() {
case $BUILD_ARCH in
aarch64) BUILD_ARCH="aarch64:aarch64_ilp32:armv8l" ;;
aarch64_ilp32) BUILD_ARCH="aarch64_ilp32:aarch64:armv8l" ;;
armv8l) BUILD_ARCH="armv8l" ;; # armv8l is aarch64 in 32bit mode. not a superset of armv7
armv7hl) BUILD_ARCH="armv7hl:armv7l:armv6hl:armv6l:armv5tel" ;;
armv7l) BUILD_ARCH="armv7l:armv6l:armv5tel" ;;
armv6hl) BUILD_ARCH="armv6hl:armv6l:armv5tel" ;;
armv6l) BUILD_ARCH="armv6l:armv5tel" ;;
armv5tel) BUILD_ARCH="armv5tel" ;;
m68k) BUILD_ARCH="m68k" ;;
mips64) BUILD_ARCH="mips64:mips" ;;
mips) BUILD_ARCH="mips" ;;
i686) BUILD_ARCH="i686:i586:i486:i386" ;;
i586) BUILD_ARCH="i586:i486:i386" ;;
i486) BUILD_ARCH="i486:i386" ;;
i386) BUILD_ARCH="i386" ;;
ia64) BUILD_ARCH="ia64" ;;
parisc64) BUILD_ARCH="hppa64:hppa" ;;
parisc) BUILD_ARCH="hppa" ;;
ppc) BUILD_ARCH="ppc" ;;
ppc64) BUILD_ARCH="ppc64:ppc" ;;
ppc64le) BUILD_ARCH="ppc64le" ;;
s390x) BUILD_ARCH="s390x:s390" ;;
s390) BUILD_ARCH="s390" ;;
sparc64v) BUILD_ARCH="sparc64v:sparc64:sparcv9v:sparcv9:sparcv8:sparc" ;;
sparc64) BUILD_ARCH="sparc64:sparcv9:sparcv8:sparc" ;;
sparcv9v) BUILD_ARCH="sparcv9v:sparcv9:sparcv8:sparc" ;;
sparcv9) BUILD_ARCH="sparcv9:sparcv8:sparc" ;;
sparcv8) BUILD_ARCH="sparcv8:sparc" ;;
sparc) BUILD_ARCH="sparc" ;;
x86_64) BUILD_ARCH="x86_64:i686:i586:i486:i386" ;;
esac
}
set_build_arch() {
build_host_arch
if test -z "$BUILD_ARCH" ; then
BUILD_ARCH="$BUILD_HOST_ARCH"
fi
extend_build_arch
if test "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
cpuflags=`grep ^flags /proc/cpuinfo`
cpuflags="$cpuflags "
if test "$cpuflags" = "${cpuflags/ cx8 /}" -o "$cpuflags" = "${cpuflags/ cmov /}"; then
echo "Your cpu doesn't support i686 rpms. Exit."
cleanup_and_exit 1
fi
fi
}
check_exit() {
if test -e $BUILD_ROOT/exit; then
echo "exit ..."
cleanup_and_exit 1
fi
}
check_use_emulator() {
INITVM_NAME=
# check if the extended host arch contains the build arch
local old_build_arch="$BUILD_ARCH"
local arch="${BUILD_ARCH%%:*}"
BUILD_ARCH="$BUILD_HOST_ARCH"
extend_build_arch
BUILD_ARCH=":$BUILD_ARCH:"
if test "$BUILD_ARCH" != "${BUILD_ARCH/:$arch:/}" ; then
# native supported arch, no emulator
BUILD_ARCH="$old_build_arch"
return 1
fi
BUILD_ARCH="$old_build_arch"
# to run the qemu initialization in the vm, we need to
# register it with a static program or shell script
INITVM_NAME="initvm.$BUILD_INITVM_ARCH"
if test -e "$BUILD_DIR/$INITVM_NAME" -a -e "$BUILD_DIR/qemu-reg" ; then
chmod 0755 "$BUILD_DIR/$INITVM_NAME"
return 0 # chroot build, we need to run
fi
# XXX: error?
echo "Warning: cross compile not possible due to missing static binaries. please install build-initvm package for that purpose."
echo " check that the right architecture is available for your build host, you need $INITVM_NAME for this one."
INITVM_NAME=
return 1
}
# usage:
# progress_setup LIST
# for I in $LIST; do
# progress_step LIST
# action $I
# done
# $1 name of a textual list
progress_setup() {
eval "$1__ARRAY__=(\$$1)"
eval "$1__INDEX__=1"
eval "$1__LENGTH__=\${#$1__ARRAY__[@]}"
}
# $1 name of a textual list
# $2 optional, printf format for 2 numeric arguments (current, total)
progress_step() {
local IDX=$1__INDEX__
local LEN=$1__LENGTH__
printf "${2-[%d/%d] }" $(($IDX++)) ${!LEN}
}
obs-build-20170201/createyastdeps 0000755 0001750 0001750 00000004253 13044631422 015177 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use Build ':rpm';
use Build::Susetags;
use Getopt::Long;
use File::Path qw(mkpath);
use strict;
Getopt::Long::Configure("no_ignore_case");
my $opt_zypp;
my $cachedir = "/var/cache/build";
GetOptions ("zypp=s" => \$opt_zypp, "cachedir=s" => \$cachedir) or exit(1);
for my $url (@ARGV) {
# XXX: use descrdir/datadir from content file
my $descrdir = 'suse/setup/descr';
my $datadir = 'suse';
my $dir;
my $baseurl = $url;
if ($opt_zypp) {
$dir = $opt_zypp;
} elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
my $repoid = Digest::MD5::md5_hex($url);
$dir = "$cachedir/$repoid/";
$baseurl .= '/' unless $baseurl =~ /\/$/;
mkpath($dir);
system("$INC[0]/download", "$dir/", "${baseurl}$descrdir/packages.gz");
$descrdir = '.';
} else {
$dir = $url;
}
$dir .= '/' unless $dir =~ /\/$/;
$baseurl .= '/' unless $baseurl =~ /\/$/;
my $packages = "$dir$descrdir/packages";
$packages = "$packages.gz" if ! -e $packages && -e "$packages.gz";
Build::Susetags::parse($packages, sub {
my $xurl = $baseurl;
# multi cd support hack
$xurl =~ s/1\/$/$_[0]->{'medium'}/ if $_[0]->{'medium'};
$xurl .= "$datadir/" if $datadir;
Build::writedeps(\*STDOUT, $_[0], $xurl);
}, 'addselfprovides' => 1);
}
obs-build-20170201/debtransformzip 0000755 0001750 0001750 00000002032 13044631422 015361 0 ustar alee alee #! /bin/bash
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
if test $# -ne 2; then
exit 1
fi
zip="$1"
tar="$2"
tmp=$(mktemp -d)
unzip -q -d "$tmp" -- "$zip" || exit 1
( cd "$tmp" && tar czO * ) >"$tar" || exit 1
rm -r "$tmp"
exit 0
obs-build-20170201/order 0000755 0001750 0001750 00000005054 13044631422 013272 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use Build;
use strict;
my ($dist, $archs, $configdir, $manifest);
$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
while (@ARGV) {
if ($ARGV[0] eq '--dist') {
shift @ARGV;
$dist = shift @ARGV;
next;
}
if ($ARGV[0] eq '--archpath') {
shift @ARGV;
$archs = shift @ARGV;
next;
}
if ($ARGV[0] eq '--configdir') {
shift @ARGV;
$configdir = shift @ARGV;
next;
}
if (@ARGV && $ARGV[0] eq '--manifest') {
shift @ARGV;
$manifest = shift @ARGV;
next;
}
last;
}
die("usage: order [--manifest manifest] cachedir [packages...]\n") unless @ARGV;
my $cachedir = shift @ARGV;
my @p;
if ($manifest) {
if ($manifest eq '-') {
@p = ;
} else {
local *F;
open(F, '<', $manifest) || die("$manifest: $!\n");
@p = ;
close F;
}
chomp @p;
}
push @p, @ARGV;
my $config = Build::read_config_dist($dist, $archs, $configdir);
my %deps;
my %bins;
for my $p (@p) {
my $q;
for my $suf ('rpm', 'deb', 'arch') {
next unless -f "$cachedir/$p.$suf";
if (! -s "$cachedir/$p.$suf") {
$q = {'provides' => [], 'requires' => []}; # package from preinstallimage, no need to order
last;
}
$q = Build::query("$cachedir/$p.$suf", 'filelist' => 1, 'alldeps' => 1, 'addselfprovides' => 1, 'normalizedeps' => 1);
die("bad binary: $p.$suf\n") unless $q;
push @{$q->{'provides'}}, @{$q->{'filelist'}} if $suf eq 'rpm' && $q->{'filelist'};
delete $q->{'filelist'};
last;
}
die("binary not found: $p\n") unless $q;
$deps{$p} = $q;
}
Build::readdeps($config, undef, \%deps);
@p = Build::order($config, @p);
print "@p\n";
obs-build-20170201/createdirdeps 0000755 0001750 0001750 00000005732 13044631422 015000 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use Build;
use Getopt::Long;
use strict;
Getopt::Long::Configure("no_ignore_case");
my $oldfile;
GetOptions ("oldfile=s" => \$oldfile) or exit(1);
sub queryfromfilename {
my ($fn) = @_;
$fn =~ s/.*\///;
return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+\.([^\. ]+)\.rpm$/;
return {'name' => $1, 'arch' => $2} if $fn =~ /^([^_]*)_(?:[^_]*)_([^_]*)\.deb$/;
return {'name' => $1, 'arch' => $2} if $fn =~ /^(.*)-[^-]+-[^-]+-([^-]+)\.pkg\.tar\.[gx]z$/;
return undef;
}
######################################################################
my %old;
if (defined($oldfile) && open(F, '<', $oldfile)) {
while () {
chomp;
$old{$1} = $_ if /^([PRrCOI]:[^ ]+): /;
}
close F;
}
my %seen;
for my $dir (@ARGV) {
my $cmd = "find $dir -follow -type f \\( -name \"*.rpm\" -o -name \"*.deb\" -o -name \"*.pkg.tar.gz\" -o -name \"*.pkg.tar.xz\" \\) -a ! -name \"*src.rpm\" -printf '\%T@/\%s/\%i \%p\\n'";
open(F, '-|', $cmd) or next;
while () {
chomp;
next unless /^([\d\.]+\/\d+\/\d+) (.*)$/;
my $id = $1;
my $path = $2;
# newer find version add a fraction part to %T@, strip it
$id =~ s/^(\d+)\.\d+/$1/;
next if $path =~ /\.(?:patch|delta)\.rpm$/; # not good for building...
if (%old) {
my $q = queryfromfilename($path);
if ($q && defined($q->{'name'}) && defined($q->{'arch'})) {
my $idx = "$q->{'name'}.$q->{'arch'}-$id";
if ($old{"I:$idx"} && $old{"P:$idx"}) {
# reuse old data
next if $seen{$idx};
$seen{$idx} = 1;
print "F:$idx: $path\n";
for (qw{P R C O I r s}) {
print $old{"$_:$idx"}."\n" if $old{"$_:$idx"};
}
next;
}
}
}
my $q = Build::query($path, 'addselfprovides' => 1, 'conflicts' => 1, 'evra' => 1, 'buildtime' => 1, 'weakdeps' => 1);
next unless $q && defined($q->{'name'}) && defined($q->{'arch'}) && defined($q->{'version'});
my $idx = "$q->{'name'}.$q->{'arch'}-$id";
next if $seen{$idx};
$seen{$idx} = 1;
$q->{'id'} = $id;
$q->{'location'} = $path;
Build::writedeps(\*STDOUT, $q);
}
close F;
}
obs-build-20170201/build-vm 0000644 0001750 0001750 00000073236 13044631422 013702 0 ustar alee alee #
# VM specific functions for the build script
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
# defaults for vm_img_mkfs
vm_img_mkfs_ext4_options='-O ^has_journal,^huge_file,^resize_inode,sparse_super'
vm_img_mkfs_ext4_extra='-E lazy_itable_init,discard'
vm_img_mkfs_ext4="mkfs.ext4 -m 0 -q -F $vm_img_mkfs_ext4_options"
vm_img_tunefs_ext4='tune2fs -c 0'
vm_img_mkfs_ext3='mkfs.ext3 -m 0 -q -F'
vm_img_tunefs_ext3='tune2fs -c 0 -o journal_data_writeback'
vm_img_mkfs_ext2='mkfs.ext2 -m 0 -q -F'
vm_img_tunefs_ext2='tune2fs -c 0'
vm_img_mkfs_reiserfs='mkreiserfs -q -f'
vm_img_mkfs_btrfs='mkfs.btrfs'
vm_img_mkfs_xfs='mkfs.xfs -f'
# guest visible swap device
VM_SWAPDEV=/dev/hda2
VM_TYPE=
VM_IMAGE=
VM_SWAP=
VM_KERNEL=
VM_INITRD=
VM_WORKER=
VM_SERVER=
VM_MEMSIZE=
VM_NETOPT=()
VM_NETDEVOPT=()
VM_DEVICEOPT=()
VM_TELNET=
VM_CONSOLE_INPUT=
VM_USER=
VMDISK_ROOTSIZE=4096
VMDISK_SWAPSIZE=1024
VMDISK_FILESYSTEM=
VMDISK_MOUNT_OPTIONS=__default
VMDISK_CLEAN=
VM_VOLUME_NAME=
VM_VOLUME_SWAP=
VM_HOSTNAME=
# zvm specific?
VM_WORKER_NR=
# kvm specific?
HUGETLBFSPATH=
VM_CUSTOMOPT=
# emulator specific?
EMULATOR_SCRIPT=
for i in ec2 emulator kvm lxc openstack qemu uml xen zvm docker pvm; do
. "$BUILD_DIR/build-vm-$i"
done
VM_WATCHDOG=
VM_WATCHDOG_PID=
# the following functions just call the corresponding vm versions
vm_kill() {
vm_kill_$VM_TYPE "$@"
}
vm_verify_options() {
vm_verify_options_$VM_TYPE "$@"
}
vm_attach_root() {
vm_attach_root_$VM_TYPE "$@"
}
vm_attach_swap() {
vm_attach_swap_$VM_TYPE "$@"
}
vm_detach_root() {
vm_detach_root_$VM_TYPE "$@"
}
vm_detach_swap() {
vm_detach_swap_$VM_TYPE "$@"
}
vm_fixup() {
vm_fixup_$VM_TYPE "$@"
}
vm_startup() {
vm_startup_$VM_TYPE "$@"
}
vm_kill() {
vm_kill_$VM_TYPE "$@"
}
vm_cleanup() {
kill_watchdog
vm_cleanup_$VM_TYPE "$@"
}
vm_parse_options() {
case ${PARAM/#--/-} in
-vm-emulator-script|-emulator-script)
needarg
EMULATOR_SCRIPT="$ARG"
shift
;;
-xen|-kvm|-uml|-qemu|-emulator)
VM_TYPE=${PARAM##*-}
test -z "$VM_IMAGE" && VM_IMAGE=1
if test -n "$ARG" ; then
VM_IMAGE="$ARG"
shift
fi
;;
-zvm|-lxc)
VM_TYPE=${PARAM##*-}
shift
;;
-vm-type)
needarg
VM_TYPE="$ARG"
case "$VM_TYPE" in
lxc|docker) ;;
ec2|xen|kvm|uml|qemu|emulator|openstack|zvm|pvm)
test -z "$VM_IMAGE" && VM_IMAGE=1
;;
none|chroot) VM_TYPE= ;;
*)
cleanup_and_exit 1 "VM '$VM_TYPE' is not supported"
;;
esac
shift
;;
-vm-worker)
needarg
VM_WORKER="$ARG"
shift
;;
-vm-worker-nr|-vm-worker-no)
needarg
VM_WORKER_NR="$ARG"
shift
;;
-vm-server|-vm-region)
needarg
VM_SERVER="$ARG"
shift
;;
-vm-volumes)
needarg
VM_VOLUME_NAME="$ARG"
shift
ARG="$1"
test "$ARG" = "${ARG#-}" || ARG=
needarg
VM_VOLUME_SWAP="$ARG"
shift
;;
-vm-disk)
needarg
VM_IMAGE="$ARG"
shift
;;
-vm-swap|-xenswap|-swap)
needarg
VM_SWAP="$ARG"
shift
;;
-vm-memory|-xenmemory|-memory)
needarg
VM_MEMSIZE="$ARG"
shift
;;
-vm-kernel)
needarg
VM_KERNEL="$ARG"
shift
;;
-vm-initrd)
needarg
VM_INITRD="$ARG"
shift
;;
-vm-disk-size|-vmdisk-rootsize)
needarg
VMDISK_ROOTSIZE="$ARG"
shift
;;
-vm-swap-size|-vmdisk-swapsize)
needarg
VMDISK_SWAPSIZE="$ARG"
shift
;;
-vm-disk-filesystem|-vmdisk-filesystem)
needarg
VMDISK_FILESYSTEM="$ARG"
shift
;;
-vm-disk-mount-options|-vmdisk-mount-options)
needarg
# options needs to be quoted to handle argument which might start with "-o ..."
VMDISK_MOUNT_OPTIONS=$(echo $ARG | sed 's/^\"\(.*\)\"$/\1/g')
shift
;;
-vm-disk-clean|-vmdisk-clean)
# delete old root/swap to get rid of the old blocks
VMDISK_CLEAN=true
;;
-vm-hugetlbfs|-hugetlbfs)
needarg
HUGETLBFSPATH="$ARG"
shift
;;
-vm-watchdog)
VM_WATCHDOG=true
;;
-vm-user)
needarg
VM_USER="$ARG"
shift
;;
-vm-enable-console)
VM_CONSOLE_INPUT=true
;;
-vm-telnet)
needarg
VM_TELNET="$ARG"
shift
;;
-vm-net)
needarg
VM_NETOPT=("${VM_NETOPT[@]}" "$ARG")
shift
;;
-vm-netdev)
needarg
VM_NETDEVOPT=("${VM_NETDEVOPT[@]}" "$ARG")
shift
;;
-vm-device)
needarg
VM_DEVICEOPT=("${VM_DEVICEOPT[@]}" "$ARG")
shift
;;
-vm-custom-opt)
needarg
VM_CUSTOMOPT="$ARG"
shift
;;
-*)
return 1
;;
esac
nextargs=("$@")
return 0
}
#
# shutdown the system from inside the VM
#
vm_shutdown() {
test -n "$VM_WATCHDOG" && echo "### VM INTERACTION START ###"
cd /
test -n "$1" || set 1
if test -n "$VM_SWAP" -a -e "$VM_SWAP" ; then
swapoff "$VM_SWAP" 2>/dev/null
echo -n "BUILDSTATUS$1" >"$VM_SWAP"
fi
exec >&0 2>&0 # so that the logging tee finishes
sleep 1 # wait till tee terminates
test "$VM_TYPE" = lxc -o "$VM_TYPE" = docker && exit $1
kill -9 -1 # goodbye cruel world
if ! test -x /sbin/halt ; then
test -e /proc/sysrq-trigger || mount -n -tproc none /proc
sync
sleep 2 # like halt does
if test -e /proc/sysrq-trigger; then
echo o > /proc/sysrq-trigger
sleep 5 # wait for sysrq to take effect
else
echo "Warning: VM doesn't support sysrq and /sbin/halt not installed"
fi
else
sync # halt from systemd is not syncing anymore.
halt -f -p
fi
echo "Warning: clean shut down of the VM didn't work"
exit $1 # init died...
}
vm_img_create() {
local img="$1"
local size="$2"
if test -e "${img}" ; then
local origsize=$(cat "${img}.size" 2> /dev/null)
if test -z "$origsize" -o "$origsize" != "$size" ; then
echo "Resizing $img (${size}M)"
fi
else
echo "Creating $img (${size}M)"
rm -f "${img}.size"
fi
mkdir -p "${img%/*}" || cleanup_and_exit 3
# truncate file to the desired size
dd if=/dev/zero of="$img" bs=1M count=0 seek="$size" || cleanup_and_exit 3
echo "$size" > "${img}.size"
# allocate blocks
if type -p fallocate > /dev/null ; then
fallocate -p -l "${size}M" "$img" 2> /dev/null
errout=$( fallocate -l "${size}M" "$img" 2>&1 )
if test $? != 0; then
echo $errout
if test "${errout/Operation not supported/}" = "$errout"; then
# Do not fail on not support file systems, eg ext2 or ext3
cleanup_and_exit 3
fi
fi
fi
}
vm_img_wipe() {
vm_wipe_$VM_TYPE "$@"
if test -n "$VM_IMAGE" -a "$VM_IMAGE" != __not_attached__ -a ! -b "$VM_IMAGE" ; then
rm -f "$VM_IMAGE"
fi
if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a ! -b "$VM_SWAP" ; then
rm -f "$VM_SWAP"
fi
}
vm_img_mkfs() {
local fs="$1"
local img="$2"
local mkfs tunefs
eval "mkfs=\"\$vm_img_mkfs_${fs}\""
eval "mkfs_exta_options=\"\$vm_img_mkfs_${fs}_extra\""
eval "tunefs=\"\$vm_img_tunefs_${fs}\""
if test -z "$mkfs"; then
cleanup_and_exit 3 "filesystem \"$fs\" is not supported"
fi
echo "Creating $fs filesystem on $img"
export MKE2FS_SYNC=0
if ! $mkfs $mkfs_exta_options "$img"; then
if test -z "$mkfs_exta_options"; then
cleanup_and_exit 3
else
echo "Format call failed, trying again without extra options..."
$mkfs "$img" || cleanup_and_exit 3
fi
fi
if test -n "$tunefs" ; then
$tunefs "$img" || cleanup_and_exit 3
fi
}
background_monitor_process() {
max_disk=0
max_mem=0
while sleep 5; do
test -e /.build/_statistics.exit && exit 0
# memory usage
if test -e /proc/meminfo ; then
memtotal=0
while read key value unit; do
case $key in
MemTotal:|SwapTotal:) memtotal=$(( $memtotal + $value )) ;;
MemFree:|SwapFree:|SwapCached:|Cached:|Buffers:) memtotal=$(( $memtotal - $value )) ;;
esac
done < /proc/meminfo
if test ${memtotal} -gt $max_mem ; then
max_mem="${memtotal}"
echo -n $(( $max_mem / 1024 )) > /.build/_statistics.memory.new && mv /.build/_statistics.memory.new /.build/_statistics.memory
fi
fi
# disk storage usage
if type -p df >& /dev/null; then
c=(`df -m / 2>/dev/null | tail -n 1`)
if test ${c[2]} -gt $max_disk ; then
max_disk="${c[2]}"
echo -n $max_disk > /.build/_statistics.df.new && mv /.build/_statistics.df.new /.build/_statistics.df
fi
fi
done
}
background_watchdog() {
WATCHDOG_START=
WATCHDOG_TIMEOUT=300
BUILD_OPTIONS_PARSED=
while sleep 5 ; do
WATCH=`grep -a "### VM INTERACTION" "$LOGFILE" | tail -n 1`
case $WATCH in
*VM\ INTERACTION\ START*) test -n "$WATCHDOG_START" || WATCHDOG_START=`date +%s` ;;
*VM\ INTERACTION\ END*) WATCHDOG_START= ;;
esac
if test -n "$WATCHDOG_START" ; then
NOW=`date +%s`
ELAPSED=$((NOW-WATCHDOG_START))
if test $ELAPSED -gt $WATCHDOG_TIMEOUT ; then
# kill the VM
echo "### WATCHDOG TRIGGERED, KILLING VM ###"
vm_kill
exit 0
fi
fi
done
}
start_watchdog() {
local wf=$(mktemp)
( background_watchdog & echo $! > "$wf" )
read VM_WATCHDOG_PID < "$wf"
rm -f "$wf"
}
kill_watchdog() {
test -n "$VM_WATCHDOG_PID" && kill "$VM_WATCHDOG_PID"
VM_WATCHDOG_PID=
}
vm_set_personality_syscall() {
local archname
archname=`perl -V:archname 2>/dev/null`
archname="${archname#archname=?}"
case "$archname" in
x86_64*) PERSONALITY_SYSCALL=135 ;;
alpha*) PERSONALITY_SYSCALL=324 ;;
sparc*) PERSONALITY_SYSCALL=191 ;;
ia64*) PERSONALITY_SYSCALL=1140 ;;
i?86*|ppc*|aarch64*|arm*|sh4|cris|m68k*|s390*|unicore32|microblaze) PERSONALITY_SYSCALL=136 ;;
*) cleanup_and_exit 1 "Unknown architecture personality: '$archname'" ;;
esac
}
# used before calling kvm or xen
linux64() {
perl -e 'syscall('$PERSONALITY_SYSCALL', 0); exec(@ARGV) || die("$ARGV[0]: $!\n")' "$@"
}
vm_detect_2nd_stage() {
if test ! -e /.build/build.data -o -n "$BUILD_IGNORE_2ND_STAGE" ; then
return 1
fi
. /.build/build.data
if test -z "$VM_TYPE" ; then
return 1
fi
BUILD_OPTIONS_PARSED=true
if test $$ -eq 1 || test $$ -eq 2 ; then
# ignore special init signals if we're init
# we're using ' ' instead of '' so that the signal handlers
# are reset in the child processes
trap ' ' HUP TERM
$0 "$@"
cleanup_and_exit $?
fi
test -n "$VM_WATCHDOG" -a -z "$PERSONALITY_SET" && echo "### VM INTERACTION END ###"
echo "2nd stage started in virtual machine"
# fedora packages sometimes do not have the needed links
ldconfig
BUILD_ROOT=/
BUILD_DIR=/.build
echo "machine type: `uname -m`"
if test "$PERSONALITY" != 0 -a -z "$PERSONALITY_SET" ; then
export PERSONALITY_SET=true
echo "switching personality to $PERSONALITY..."
# this is 32bit perl/glibc, thus the 32bit syscall number
exec perl -e 'syscall(136, '$PERSONALITY') == -1 && warn("personality: $!\n");exec "/.build/build" || die("/.build/build: $!\n")'
fi
RUNNING_IN_VM=true
test -e /proc/version || mount -orw -n -tproc none /proc
if test "$VM_TYPE" != lxc -a "$VM_TYPE" != docker ; then
mount -n ${VMDISK_MOUNT_OPTIONS},remount,rw /
fi
umount /run >/dev/null 2>&1
# mount /sys
if ! test -e /sys/block; then
mkdir -p /sys
mount -orw -n -tsysfs sysfs /sys
# Docker already has sysfs mounted ro elsewhere,
# need to remount rw explicitly.
mount -o remount,rw sysfs /sys
fi
# qemu inside of xen does not work, check again with kvm later before enabling this
# if test -e /dev/kqemu ; then
# # allow abuild user to run qemu
# chmod 0666 /dev/kqemu
# fi
test -d /dev/shm || rm -f /dev/shm
mkdir -p /dev/pts
mkdir -p /dev/shm
mount -n -tdevpts -omode=0620,gid=5 none /dev/pts
mount -n -ttmpfs none /dev/shm
if test -n "$VM_SWAP" ; then
if "$VM_SWAP" != "${VM_SWAP#LABEL=}" ; then
i=$(blkid -l -o device -t "$VM_SWAP")
if test "$i" = "${i#/}" ; then
cleanup_and_exit 1 "could not find swap device with $VM_SWAP"
fi
echo "resolved swap device $VM_SWAP to $i"
VM_SWAP=$i
fi
for i in 1 2 3 4 5 6 7 8 9 10 ; do
test -e "$VM_SWAP" && break
test $i = 1 && echo "waiting for $VM_SWAP to appear"
echo -n .
sleep 1
done
test $i = 1 || echo
# recreate the swap device manually if it didn't exist for some
# reason, hardcoded to hda2 atm
if ! test -b "$VM_SWAP" ; then
rm -f "$VM_SWAP"
umask 027
mknod "$VM_SWAP" b 3 2
umask 022
fi
# Do not rely on external system writing the signature, it might differ...
mkswap "$VM_SWAP"
swapon -v "$VM_SWAP" || exit 1
fi
HOST="$VM_HOSTNAME"
# repair dracut damage, see bsc#922676
test -L /var/run -a ! -e /var/run && rm -f /var/run
test -L /var/lock -a ! -e /var/lock && rm -f /var/lock
# fork a process monitoring max filesystem usage during build
if test "$DO_STATISTICS" = 1 ; then
rm -f /.build/_statistics.exit
( background_monitor_process & )
fi
if test ! -e /dev/.udev ; then
echo "WARNING: udev not running, creating extra device nodes"
test -e /dev/fd || ln -sf /proc/self/fd /dev/fd
test -e /etc/mtab || ln -sf /proc/mounts /etc/mtab
fi
# set date to build start on broken systems (now < build start)
if test $(date '+%s') -lt $(date -r /.build/.date '+%s') ; then
echo -n "WARNING: system has a broken clock, setting it to a newer time: "
date -s `cat /.build/.date`
fi
return 0
}
vm_set_filesystem_type() {
if test -z "$VMDISK_FILESYSTEM" -a -n "$BUILD_DIST" ; then
VMDISK_FILESYSTEM=`queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags vmfstype`
fi
test -n "$VMDISK_FILESYSTEM" || VMDISK_FILESYSTEM=ext3
}
vm_set_mount_options() {
if test "$VMDISK_MOUNT_OPTIONS" = __default; then
if test "$VMDISK_FILESYSTEM" = reiserfs ; then
VMDISK_MOUNT_OPTIONS='-o data=writeback,commit=150,noatime'
elif test "$VMDISK_FILESYSTEM" = btrfs ; then
VMDISK_MOUNT_OPTIONS='-o nobarrier,noatime'
elif test "$VMDISK_FILESYSTEM" = "ext4" ; then
VMDISK_MOUNT_OPTIONS='-o noatime'
elif test "$VMDISK_FILESYSTEM" = "ext3" ; then
VMDISK_MOUNT_OPTIONS='-o data=writeback,nobarrier,commit=150,noatime'
elif test "$VMDISK_FILESYSTEM" = "ext2" ; then
VMDISK_MOUNT_OPTIONS='-o noacl,noatime'
elif test "$VMDISK_FILESYSTEM" = "xfs" ; then
VMDISK_MOUNT_OPTIONS='-o noatime'
else
VMDISK_MOUNT_OPTIONS='-o noatime'
fi
fi
}
#
# create file system and swap space, mount file system to $BUILD_ROOT
#
vm_setup() {
vm_set_filesystem_type
vm_set_mount_options
if test "$VM_IMAGE" = 1 ; then
VM_IMAGE="$BUILD_ROOT.img"
if test -z "$VM_SWAP" -a "$VM_TYPE" != emulator ; then
VM_SWAP="$BUILD_ROOT.swap"
fi
fi
echo "VM_IMAGE: $VM_IMAGE, VM_SWAP: $VM_SWAP"
vm_attach_root
# this should not be needed, but sometimes a xen instance got lost
test "$VM_TYPE" = xen && vm_purge_xen
if test -n "$VMDISK_CLEAN" ; then
# delete old root/swap to get rid of the old blocks
if test -n "$VM_IMAGE" -a "$VM_IMAGE" != __not_attached__ -a -f "$VM_IMAGE" ; then
echo "Deleting old $VM_IMAGE"
rm -rf "$VM_IMAGE"
fi
if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a -f "$VM_SWAP" ; then
echo "Deleting old $VM_SWAP"
rm -rf "$VM_SWAP"
fi
fi
if test ! -b "$VM_IMAGE" ; then
vm_img_create "$VM_IMAGE" "$VMDISK_ROOTSIZE"
fi
if test -z "$CLEAN_BUILD" ; then
vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE"
fi
if test -n "$VM_SWAP" -a "$VM_SWAP" != __not_attached__ -a ! -b "$VM_SWAP" ; then
vm_img_create "$VM_SWAP" "$VMDISK_SWAPSIZE"
fi
if test ! -e "$VM_IMAGE" ; then
cleanup_and_exit 3 "you need to create $VM_IMAGE first"
fi
if test -n "$CLEAN_BUILD" ; then
vm_img_mkfs "$VMDISK_FILESYSTEM" "$VM_IMAGE" || cleanup_and_exit 3
fi
# now mount root/swap
mkdir_build_root
if test -w /root ; then
if test -b $VM_IMAGE ; then
# mount device directly
mount $VMDISK_MOUNT_OPTIONS $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
else
mount ${VMDISK_MOUNT_OPTIONS},loop $VM_IMAGE $BUILD_ROOT || cleanup_and_exit 3
fi
else
if ! mount $BUILD_ROOT; then
echo "mounting the build root failed. An fstab entry is probably missing or incorrect."
echo "/etc/fstab should contain an entry like this:"
echo "$VM_IMAGE $BUILD_ROOT auto noauto,user,loop 0 0"
cleanup_and_exit 3
fi
fi
if test -n "$VM_SWAP" ; then
vm_attach_swap
dd if=/dev/zero of="$VM_SWAP" bs=1024 count=1 conv=notrunc 2>/dev/null
if "$VM_SWAPDEV" != "${VM_SWAPDIR#LABEL=}"; then
# call mkswap to set a label
mkswap -L "${VM_SWAPDIR#LABEL=}" "$VM_SWAP"
fi
vm_detach_swap
# mkswap happens inside of the vm
fi
}
vm_update_hostarch() {
local kernel="$vm_kernel"
local hostarchfile
local newhostarch
if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
kernel="$BUILD_ROOT/.build.kernel.$VM_TYPE"
hostarchfile="$BUILD_ROOT/.build.hostarch.$VM_TYPE"
elif test -n "$kernel" -a -e "$kernel" -a -e "$kernel.hostarch" ; then
hostarchfile="$kernel.hostarch"
fi
if test -n "$hostarchfile" -a -e "$hostarchfile"; then
newhostarch=`cat "$hostarchfile"`
elif test -n "$kernel" -a -e "$kernel" ; then
case `objdump -f "$kernel" | sed -ne 's/.*file format //p'` in
elf64-powerpcle) newhostarch=ppc64le ;;
elf64-powerpc) newhostarch=ppc64 ;;
esac
fi
if test -n "$newhostarch" -a "$newhostarch" != "$BUILD_HOST_ARCH" ; then
echo "setting hostarch to $newhostarch"
BUILD_HOST_ARCH="$newhostarch"
# update BUILD_INITVM_ARCH
build_host_arch
fi
}
#
# prepare for vm startup
#
vm_first_stage() {
vm_set_personality_syscall
rm -rf "$BUILD_ROOT/.build"
mkdir -p "$BUILD_ROOT/.build"
TIME_PREINSTALL=
if test "$DO_INIT" = true ; then
# do first stage of init_buildsystem
rm -f $BUILD_ROOT/.build.success
set -- init_buildsystem --configdir "$CONFIG_DIR" --cachedir "$CACHE_DIR" --prepare "${definesnstuff[@]}" "${repos[@]}" $CLEAN_BUILD $USEUSEDFORBUILD $RPMLIST "$MYSRCDIR/$RECIPEFILE" $ADDITIONAL_PACKS
echo "$* ..."
start_time=`date +%s`
"$@" || cleanup_and_exit 1
check_exit
TIME_PREINSTALL=$(( `date +%s` - $start_time ))
unset start_time
if test ! -w /root ; then
# remove setuid bit if files belong to user to make e.g. mount work
find $BUILD_ROOT/{bin,sbin,usr/bin,usr/sbin} -type f -uid $UID -perm +4000 -print0 | xargs -0 --no-run-if-empty chmod -s
fi
copy_oldpackages
fi
# start up VM, rerun ourself
cp -a $BUILD_DIR/. $BUILD_ROOT/.build
if ! test "$MYSRCDIR" = $BUILD_ROOT/.build-srcdir ; then
rm -rf "$BUILD_ROOT/.build-srcdir"
mkdir "$BUILD_ROOT/.build-srcdir"
if test "$BUILDTYPE" = kiwi ; then
cp -pRL "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
else
cp -p "$MYSRCDIR"/* $BUILD_ROOT/.build-srcdir
fi
MYSRCDIR=$BUILD_ROOT/.build-srcdir
else
# cwd is at $BUILD_ROOT/.build-srcdir which we want to
# umount later so step aside
cd "$SRCDIR"
fi
# do vm specific fixups
vm_fixup
# update the hostarch
if test -n "$VM_IMAGE" ; then
vm_update_hostarch
fi
# the watchdog needs a log file
test -n "$LOGFILE" || VM_WATCHDOG=
# put our config into .build/build.data
Q="'\''"
echo "RECIPEFILE='${RECIPEFILE//"'"/$Q}'" > $BUILD_ROOT/.build/build.data
echo "BUILD_JOBS='${BUILD_JOBS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_ARCH='${BUILD_ARCH//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_RPMS='${BUILD_RPMS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
case $BUILD_DIST in
*/*)
cp $BUILD_DIST $BUILD_ROOT/.build/build.dist
BUILD_DIST=/.build/build.dist
;;
esac
echo "BUILD_DIST='${BUILD_DIST//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "RELEASE='${RELEASE//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "BUILD_DEBUG='${BUILD_DEBUG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "SIGNDUMMY='${SIGNDUMMY//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_LINT='${DO_LINT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_CHECKS='${DO_CHECKS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "NOROOTFORBUILD='${NOROOTFORBUILD//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "CREATE_BASELIBS='$CREATE_BASELIBS'" >> $BUILD_ROOT/.build/build.data
echo "REASON='${REASON//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "CHANGELOG='${CHANGELOG//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "INCARNATION='${INCARNATION//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DISTURL='${DISTURL//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_INIT='${DO_INIT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "DO_INIT_TOPDIR='${DO_INIT_TOPDIR//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "KIWI_PARAMETERS='${KIWI_PARAMETERS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "VM_TELNET='${VM_TELNET//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
echo "VM_CONSOLE_INPUT='${VM_CONSOLE_INPUT//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
test -n "$VM_SWAP" && echo "VM_SWAP='${VM_SWAPDEV//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
test -n "$VMDISK_MOUNT_OPTIONS" && echo "VMDISK_MOUNT_OPTIONS='${VMDISK_MOUNT_OPTIONS//"'"/$Q}'" >> $BUILD_ROOT/.build/build.data
PERSONALITY=0
test -n "$PERSONALITY_SYSCALL" && PERSONALITY=`perl -e 'print syscall('$PERSONALITY_SYSCALL', 0)."\n"'`
test "$PERSONALITY" = -1 && PERSONALITY=0 # syscall failed?
case $(uname -m) in
ppc|ppcle|s390) PERSONALITY=8 ;; # ppc/s390 kernel never tells us if a 32bit personality is active, assume we run on 64bit
aarch64) test "$BUILD_ARCH" != "${BUILD_ARCH#armv[567]}" && PERSONALITY=8 ;; # workaround, to be removed
esac
test "$VM_TYPE" = lxc -o "$VM_TYPE" = docker && PERSONALITY=0
echo "PERSONALITY='$PERSONALITY'" >> $BUILD_ROOT/.build/build.data
echo "VM_HOSTNAME='$HOST'" >> $BUILD_ROOT/.build/build.data
echo -n "definesnstuff=(" >> $BUILD_ROOT/.build/build.data
shellquote "${definesnstuff[@]}" >> $BUILD_ROOT/.build/build.data
echo ")" >> $BUILD_ROOT/.build/build.data
echo -n "repos=(" >> $BUILD_ROOT/.build/build.data
shellquote "${repos[@]}" >> $BUILD_ROOT/.build/build.data
echo ")" >> $BUILD_ROOT/.build/build.data
echo "VM_TYPE='$VM_TYPE'" >> $BUILD_ROOT/.build/build.data
echo "RUN_SHELL='$RUN_SHELL'" >> $BUILD_ROOT/.build/build.data
echo "DO_STATISTICS='$DO_STATISTICS'" >> $BUILD_ROOT/.build/build.data
echo "TIME_PREINSTALL='$TIME_PREINSTALL'" >> $BUILD_ROOT/.build/build.data
echo "VM_WATCHDOG='$VM_WATCHDOG'" >> $BUILD_ROOT/.build/build.data
echo "BUILDENGINE='$BUILDENGINE'" >> $BUILD_ROOT/.build/build.data
echo "CCACHE='$CCACHE'" >> $BUILD_ROOT/.build/build.data
echo "ABUILD_TARGET='$ABUILD_TARGET'" >> $BUILD_ROOT/.build/build.data
# fallback time for broken hosts
date '+@%s' > $BUILD_ROOT/.build/.date
# we're done with the root file system, unmount
umount -n $BUILD_ROOT/proc/sys/fs/binfmt_misc 2> /dev/null || true
umount -n $BUILD_ROOT/proc 2> /dev/null || true
umount -n $BUILD_ROOT/dev/pts 2> /dev/null || true
umount -n $BUILD_ROOT/dev/shm 2> /dev/null || true
umount -n $BUILD_ROOT/mnt 2> /dev/null || true
vm_init_script="/.build/build"
if check_use_emulator ; then
vm_init_script="/.build/$INITVM_NAME"
fi
if test -n "$VM_IMAGE" ; then
# copy out kernel & initrd (if they exist) during unmounting VM image
KERNEL_TEMP_DIR=
if test -z "$VM_KERNEL" -a -e "$BUILD_ROOT/.build.kernel.$VM_TYPE" ; then
KERNEL_TEMP_DIR=`mktemp -d`
cp "$BUILD_ROOT/.build.kernel.$VM_TYPE" "$KERNEL_TEMP_DIR/kernel"
if test -e "$BUILD_ROOT/.build.initrd.$VM_TYPE" ; then
cp "$BUILD_ROOT/.build.initrd.$VM_TYPE" "$KERNEL_TEMP_DIR/initrd"
fi
fi
check_exit
# needs to work otherwise we have a corrupted file system
if ! umount $BUILD_ROOT; then
rm -rf "$KERNEL_TEMP_DIR"
cleanup_and_exit 3
fi
# copy back the kernel and set it for VM
if test -n "$KERNEL_TEMP_DIR" ; then
mkdir -p "$BUILD_ROOT/boot"
mv "$KERNEL_TEMP_DIR/kernel" "$BUILD_ROOT/boot/kernel"
vm_kernel="$BUILD_ROOT/boot/kernel"
if test -e "$KERNEL_TEMP_DIR/initrd" ; then
mv "$KERNEL_TEMP_DIR/initrd" "$BUILD_ROOT/boot/initrd"
test -z "$VM_INITRD" && vm_initrd="$BUILD_ROOT/boot/initrd"
fi
rmdir "$KERNEL_TEMP_DIR"
fi
fi
vm_detach_root
echo "booting $VM_TYPE..."
# start watchdog if requested
if test -n "$VM_WATCHDOG" ; then
start_watchdog
echo "### VM INTERACTION START ###"
fi
vm_startup
# kill watchdog again
if test -n "$VM_WATCHDOG" ; then
echo "### VM INTERACTION END ###"
kill_watchdog
fi
vm_attach_root
if test -n "$VM_SWAP" ; then
vm_attach_swap
BUILDSTATUS=`dd if="$VM_SWAP" bs=12 count=1 2>/dev/null`
case $BUILDSTATUS in
BUILDSTATUS[02])
mkdir -p $BUILD_ROOT/.build.packages
cd $BUILD_ROOT/.build.packages || cleanup_and_exit 1
echo "build: extracting built packages..."
extractbuild --disk "$VM_IMAGE" --input "$VM_SWAP" --skip 512 -v || cleanup_and_exit 3
if test "$DO_STATISTICS" = 1 ; then
mkdir -p OTHER
TIME_TOTAL=$(( `date +%s` - $TIME_START_TIME ))
echo "TIME_total: $TIME_TOTAL" >> OTHER/_statistics
fi
cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
;;
BUILDSTATUS*)
cleanup_and_exit ${BUILDSTATUS#BUILDSTATUS}
;;
*)
echo "No buildstatus set, either the base system is broken (kernel/initrd/udev/glibc/bash/perl)"
echo "or the build host has a kernel or hardware problem..."
cleanup_and_exit 3
;;
esac
cleanup_and_exit 1
fi
}
vm_save_statistics() {
echo "... saving statistics"
local sys_mounted otherdir
otherdir="$BUILD_ROOT$TOPDIR/OTHER"
test -n "$TIME_PREINSTALL" && echo "TIME_preinstall: $TIME_PREINSTALL" >> $otherdir/_statistics
test -n "$TIME_INSTALL" && echo "TIME_install: $TIME_INSTALL" >> $otherdir/_statistics
if test -e /.build/_statistics.df ; then
echo -n "MAX_mb_used_on_disk: " >> $otherdir/_statistics
cat /.build/_statistics.df >> $otherdir/_statistics
echo "" >> $otherdir/_statistics
rm /.build/_statistics.df
fi
if test -e /.build/_statistics.memory ; then
echo -n "MAX_mb_used_memory: " >> $otherdir/_statistics
cat /.build/_statistics.memory >> $otherdir/_statistics
echo "" >> $otherdir/_statistics
rm /.build/_statistics.memory
fi
if ! test -e /sys/block; then
mkdir -p /sys
mount -n sys /sys -t sysfs
sys_mounted=1
fi
device="hda1"
test -e /dev/sda && device="sda"
test -e /dev/vda && device="vda"
test -e /dev/xvda && device="xvda" # in newer XEN setups
test -e /dev/dasda && device="dasda" # in z/VM
test -e /dev/nfhd0 && device="nfhd0" # in aranym
if test -e /sys/block/${device}/stat ; then
disk=(`cat /sys/block/${device}/stat`)
test "0${disk[0]}" -gt 0 && echo "IO_requests_read: ${disk[0]}" >> $otherdir/_statistics
test "0${disk[2]}" -gt 0 && echo "IO_sectors_read: ${disk[2]}" >> $otherdir/_statistics
test "0${disk[4]}" -gt 0 && echo "IO_requests_write: ${disk[4]}" >> $otherdir/_statistics
test "0${disk[6]}" -gt 0 && echo "IO_sectors_write: ${disk[6]}" >> $otherdir/_statistics
else
echo "ERROR: no root disk device found, yet another new device name?"
ls -l /sys/block/
fi
test -n "$sys_mounted" && umount /sys
}
# args: resultdirs
vm_wrapup_build() {
test "$DO_STATISTICS" = 1 && vm_save_statistics
if test -n "$VM_SWAP"; then
echo "... saving built packages"
swapoff "$VM_SWAP"
pushd "$BUILD_ROOT$TOPDIR" >/dev/null
find "$@" -print0 | computeblocklists --padstart 512 --padend 512 -v --manifest - -0 > "$VM_SWAP"
popd >/dev/null
fi
}
vm_setup_network() {
if test -x /sbin/ip ; then
ip addr add 127.0.0.1/8 dev lo
ip addr add ::1/128 dev lo
ip link set lo up
else
ifconfig lo 127.0.0.1 up
ifconfig lo add ::1/128
fi
if test -n "$VM_TELNET"; then
VM_TELNET_DEVICE=$( cd /sys/class/net/; echo * )
VM_TELNET_DEVICE=${VM_TELNET_DEVICE#lo }
VM_TELNET_DEVICE=${VM_TELNET_DEVICE%% *}
if test -z "$VM_TELNET_DEVICE" ; then
cleanup_and_exit 1 "ERROR: no network device found for telnet server"
fi
if test -x /sbin/ip ; then
ip addr add 10.0.2.15/8 dev ${VM_TELNET_DEVICE}
ip addr add ::1/24 dev ${VM_TELNET_DEVICE}
ip link set ${VM_TELNET_DEVICE} up
elif test -x /sbin/ifconfig ; then
ifconfig ${VM_TELNET_DEVICE} 10.0.2.15 up
ifconfig ${VM_TELNET_DEVICE} add ::1/24
else
cleanup_and_exit 1 "ERROR: neither /sbin/ifconfig nor /sbin/ip is installed, please specify correct package via -x option"
fi
fi
if test -n "$VM_HOSTNAME" ; then
hostname "$VM_HOSTNAME"
fi
if test -n "$VM_TELNET"; then
echo WARNING: telnet option used, setting up telnet server ${VM_TELNET_DEVICE}
if test -x /usr/sbin/in.telnetd; then
( /usr/sbin/in.telnetd -L /.build/telnet_login_wrapper -debug 23 & )
else
cleanup_and_exit 1 "ERROR: /usr/sbin/in.telnetd is not installed, please specify correct package via -x option"
fi
fi
}
obs-build-20170201/computeblocklists 0000755 0001750 0001750 00000011550 13044631422 015723 0 ustar alee alee #!/usr/bin/perl -w
# compute the blocks used by a file
# usage:
# computeblocklists [options]
# options:
# --padstart NUM, --padend NUM, --verbose
#
# output:
#
#
# a block is either a number or a range (start-end)
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
use strict;
my ($opt_padstart, $opt_padend, $opt_verbose, $opt_manifest, $opt_mani0);
$opt_verbose = 0;
while (@ARGV) {
if ($ARGV[0] eq '--padstart') {
shift @ARGV;
$opt_padstart = shift @ARGV;
next;
}
if ($ARGV[0] eq '--padend') {
shift @ARGV;
$opt_padend = shift @ARGV;
next;
}
if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
shift @ARGV;
$opt_verbose++;
next;
}
if ($ARGV[0] eq '-0') {
shift @ARGV;
$opt_mani0 = 1;
next;
}
if ($ARGV[0] eq '--manifest') {
shift @ARGV;
$opt_manifest = shift @ARGV;
next;
}
last;
}
print "\n"x$opt_padstart if $opt_padstart;
if ($opt_manifest) {
if ($opt_manifest eq '-') {
open(MANIFEST, '<&STDIN') || die("STDIN dup: $!\n");
} else {
open(MANIFEST, '<', $opt_manifest) || die("$opt_manifest: $!\n");
}
}
while (1) {
my $file;
if (@ARGV) {
$file = shift @ARGV;
} elsif ($opt_manifest) {
if ($opt_mani0) {
local $/ = "\0";
$file = ;
last unless defined $file;
$file =~ s/\0$//s;
} else {
$file = ;
last unless defined $file;
chomp $file;
}
} else {
last;
}
my $n = $file;
$n =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
if (-l $file) {
print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
my $c = readlink($file);
die("$file: readlink: $!\n") unless defined $c;
if ("/$c/" =~ /\/\.?\//s) {
print STDERR "$file: bad symlink ($c) ignored\n";
next;
}
if ("/$c/" =~ /^(\/\.\.)+\/(.*?)$/s) {
my ($head, $tail) = ($1, $2);
if (("/$tail/" =~ /\/\.\.\//s) || (($head =~ y!/!!) > ($file =~ y!/!!))) {
print STDERR "$file: bad symlink ($c) ignored\n";
next;
}
} else {
if ("/$c/" =~ /\/\.\.\//s) {
print STDERR "$file: bad symlink ($c) ignored\n";
next;
}
}
$c =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
print "l $n $c\n";
next;
} elsif (-d _) {
print STDERR "$file\n" if $opt_verbose && $opt_verbose > 1;
my @stat = stat(_);
print "d $n\n";
next;
} elsif (!-f _) {
next;
}
print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
if (!open(F, '<', $file)) {
print STDERR "$file: $!";
next;
}
my @stat = stat(F);
die unless @stat;
my $st_size = $stat[7];
if ($st_size == 0) {
print "f $n 0\n";
close F;
next;
}
my $bsize = 'xxxx';
ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n");
$bsize = unpack("L", $bsize);
die("$file: empty blocksize\n") unless $bsize != 0;
print "f $n $st_size $bsize";
my $blocks = int(($st_size+$bsize-1)/$bsize);
my ($firstblock, $lastblock);
for ($b = 0; $b < $blocks; ++$b) {
my $block = pack('I', $b);
if (not defined ioctl(F, 1, $block)) {
if (not defined ioctl(F, 536870913, $block)) {
die "$file: $!\n";
}
}
$block = unpack('I', $block);
if (!$firstblock && defined($firstblock)) {
# last block was hole
if (!$block) {
$lastblock++; # count holes, 0-2 means three hole blocks
} else {
# switch back from 'hole mode' into normal mode
printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
print " $block";
$firstblock = $lastblock = $block;
}
next;
}
if (!$firstblock || $lastblock + 1 != $block) {
# start of a new run
printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
print " $block";
$firstblock = $block;
}
$lastblock = $block;
}
# finish last run
printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
close F;
print "\n";
}
print "\n"x$opt_padend if $opt_padend;
obs-build-20170201/livebuild_pre_run.template 0000755 0001750 0001750 00000004161 13044631422 017500 0 ustar alee alee #!/bin/bash
#
# This is a template for a livebuild_pre_run script. These scripts are
# executed by build_livebuild.sh in the chroot environment.
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
fix_debootstrap()
{
# debootstrap in Debian 7.0 does not like dash
if [ -x /usr/sbin/debootstrap ] ; then
sed -i 's|^#!/bin/sh|#!/bin/bash|' /usr/sbin/debootstrap
fi
}
fix_lb_bootstrap_archive-keys()
{
if [ -e /usr/lib/live/build/bootstrap_archive-keys ] ; then
sed -i '/apt-get update/{ s/^/#/ }' \
/usr/lib/live/build/bootstrap_archive-keys
fi
}
#
# main
#
: ${TOPDIR:=/usr/src/packages}
# Distribution and live-build specific hooks
fix_debootstrap
fix_lb_bootstrap_archive-keys
# Expand configuration based on defaults
cd $TOPDIR/LIVEBUILD_ROOT && lb config || exit 1
# Replace all occurances of LB_MIRROR with local repository
sed -i "s|^\(LB_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \
$TOPDIR/LIVEBUILD_ROOT/config/bootstrap
sed -i "s|^\(LB_PARENT_MIRROR_[^=]\+=\).*|\1\"file:$TOPDIR/SOURCES/repos/\"|" \
$TOPDIR/LIVEBUILD_ROOT/config/bootstrap
# Prevent debootstrap from cleaning our cache
sed -i 's|^\(LB_CACHE_PACKAGES=\).*|\1"false"|' \
$TOPDIR/LIVEBUILD_ROOT/config/common
# Disable GPG checking
sed -i 's|^\(LB_APT_SECURE=\).*|\1"false"|' \
$TOPDIR/LIVEBUILD_ROOT/config/common
obs-build-20170201/runservices 0000755 0001750 0001750 00000006343 13044631422 014531 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use POSIX;
use File::Temp ();
use File::Copy ();
use strict;
use Build::SimpleXML;
my $servicedir = '/usr/lib/obs/service';
my $buildroot = '';
sub ls {
local *D;
opendir(D, $_[0]) || return ();
my @r = grep {$_ ne '.' && $_ ne '..'} readdir(D);
closedir D;
return @r;
}
sub run_services {
my ($xml) = @_;
my $servicexml = Build::SimpleXML::parse($xml);
die("not a valid _service file\n") unless $servicexml && $servicexml->{'services'};
$servicexml = $servicexml->{'services'}->[0];
my $tempdir;
if ($buildroot ne '') {
$tempdir = File::Temp::tempdir('CLEANUP' => 1, 'DIR' => "$buildroot/tmp");
die("bad tempdir\n") unless $tempdir =~ s/^\Q$buildroot\E//;
} else {
$tempdir = File::Temp::tempdir('CLEANUP' => 1);
}
# take default version setting
for my $s (@{$servicexml->{'service'} || []}) {
# buildtime only is default
next unless $s->{'mode'} && $s->{'mode'} eq 'buildtime';
die("missing name in service\n") unless $s->{'name'};
if (! -x "$buildroot$servicedir/$s->{'name'}") {
die("service '$s->{'name'}' configured to run, but is not available\n");
}
my @run;
push @run, "$servicedir/$s->{'name'}";
for my $param (@{$s->{'param'}}) {
next if $param->{'name'} eq 'outdir';
next unless $param->{'_content'};
push @run, "--$param->{'name'}";
push @run, $param->{'_content'};
}
push @run, "--outdir";
push @run, $tempdir;
my $pid = fork();
die("fork: $!\n") unless defined $pid;
if ($pid == 0) {
if ($buildroot ne '') {
chroot($buildroot) || die("chroot $buildroot: $!\n");
}
exec(@run);
die("$run[0]: $!\n");
}
1 while waitpid($pid, 0) != $pid;
die("service run failed for service '$s->{'name'}'\n") if $?;
# copy back
for my $file (grep {!/^[:\.]/} ls("$buildroot$tempdir")) {
File::Copy::move("$buildroot$tempdir/$file", $file) if -f "$buildroot$tempdir/$file";
}
}
}
if (@ARGV > 1 && $ARGV[0] eq '--buildroot') {
shift @ARGV;
$buildroot = shift @ARGV;
$buildroot = '' if $buildroot && $buildroot eq '/';
die("bad buildroot\n") unless $buildroot eq '' || $buildroot =~ /^\//;
}
local *F;
open(F, '<', '_service') || die("_service: $!\n");
my $xml = '';
1 while sysread(F, $xml, 4096, length($xml)) > 0;
close F;
run_services($xml);
obs-build-20170201/build.conf.example 0000644 0001750 0001750 00000001540 13044631422 015625 0 ustar alee alee # Example configuration for buildroot and parameter whitelisting.
# Can be used to make multi-user environments more secure. Everything is
# allowed by default if no whitelist is defined.
#
# List of whitelisted build roots.
# %user will be replaced with $SUDO_USER (or $USER when running without sudo)
#
# ALLOW_BUILD_ROOT: /var/tmp/%user/build-root
# ALLOW_BUILD_ROOT: /var/tmp/build-root
# List of whitelisted parameters. Allowed parameters
# must be listed in double dash format.
#
# ALLOW_PARAM: --arch
# ALLOW_PARAM: --changelog
# ALLOW_PARAM: --clean
# ALLOW_PARAM: --dist
# ALLOW_PARAM: --jobs
# ALLOW_PARAM: --noinit
# ALLOW_PARAM: --norootforbuild
# ALLOW_PARAM: --root
# ALLOW_PARAM: --rpmlist
#
# Specific parameter arguments can be whitelisted (other arguments
# are not allowed in that case):
#
# ALLOW_PARAM: --jobs 1
obs-build-20170201/createmdkdeps 0000755 0001750 0001750 00000003203 13044631422 014764 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 2015 SUSE Linux GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
# Mandriva/Mageia support
BEGIN {
unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build");
}
use strict;
use Build ':mdk';
use Build::Mdkrepo;
use Digest::MD5 ();
use File::Path;
use Getopt::Long;
Getopt::Long::Configure("no_ignore_case");
my $cachedir = "/var/cache/build";
GetOptions("cachedir=s" => \$cachedir) or exit(1);
for my $url (@ARGV) {
die("$url: not an remote mandriva/mageia repo") unless $url =~ /^(:?ftps?|https?):\/\/([^\/]*)\/?/;
my $repoid = Digest::MD5::md5_hex($url);
my $dir = "$cachedir/$repoid";
$url .= '/' unless $url =~ /\/$/;
File::Path::mkpath($dir);
system("$INC[0]/download", $dir, "${url}media_info/synthesis.hdlist.cz");
Build::Mdkrepo::parse("$dir/synthesis.hdlist.cz", sub { Build::writedeps(\*STDOUT, $_[0], $url) }, 'addselfprovides' => 1);
}
obs-build-20170201/spectool 0000755 0001750 0001750 00000025234 13044631422 014011 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
=head1 spectool
spectool - tool to work with rpm spec files
=head1 SYNOPSIS
spectool [options] specfiles...
=head1 OPTIONS
=over 4
=item B<--help>
display help as manpage
=item B<--dist>=I
set distribution, e.g. "11.1-i586" or path to config
=item B<--archpath>=I
compatible architecture separated by colon, e.g. C.
Autotected if missing.
=item B<--configdir>=I
path to config files if B<--dist> didn't specify a full path
=item B<--define>=I
=item B<--with>=I
=item B<--without>=I
same meaning as in rpmbuild
=item B<--tag>=I
print tag from spec file, e.g. C. Regexp is also possible,
e.g. C
=item B<--sources>
print package source files. If a file C or
C.sources> is present verify the checksums against
that.
=over 4
=item B<--update>
update the checksums
=item B<--download>
download missing sources
=back
=back
=head1 DESCRIPTION
The B<--sources> option allows to manage a sources file in a way
similar to Fedora. The sources file lists the check sums and file
names of the binary files specified in the spec file.
B<--sources> without further options compares the check sums of all
files and prints a report consisting of a character that describes
the status of the file and the file name. Meaning of the characters
is as follows:
=over 4
=item B<.> check sum matches
=item B check sum broken
=item B file is missing, checksum known. Can be verified after download
=item B<-> file is missing and checksum unknown
=item B<_> file is present but checksum unknown
=item B text file, will be skipped for check sums
=item B> check sum known but not referenced from spec file
=back
Additionally specifying B<--update> recomputes all check sums and
updates the sources file.
With B<--download> all missing files are downloaded if the spec file
has an http or ftp url.
=head2 FORMAT OF THE SOURCES FILE
Lines of the form
=head2 NAME OF THE SOURCES FILE
A file named C is preferred if present for compatibility
with Fedora. It only contains md5 sums. If that file is not present
the C<.spec> suffix of the spec file is replaced with C<.sources>
and the this name used as sources file (e.g. C ->
C). In this file sha1 is preferred. Also, the name of
the algorithm is prepended with colon to the check sum.
=cut
my $builddir;
BEGIN {
$builddir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
unshift @INC, $builddir;
}
use strict;
use Build;
use Pod::Usage;
use Getopt::Long;
Getopt::Long::Configure("no_ignore_case");
my (@opt_showtag, $opt_sources, $opt_update, $opt_download);
sub parse_depfile;
my ($dist, $rpmdeps, $archs, $configdir, $useusedforbuild);
my %options;
GetOptions (
\%options,
"help" => sub { pod2usage(-exitstatus => 0, -verbose => 2) },
"dist=s" => \$dist,
"archpath=s" => \$archs,
"configdir=s" => \$configdir,
"define=s" => sub { Build::define($_[1]) },
"with=s" => sub { Build::define("_with_".$_[1]." --with-".$_[1]) },
"without=s" => sub { Build::define("_without_".$_[1]." --without-".$_[1]) },
"tag=s" => \@opt_showtag,
"sources" => \$opt_sources,
"update" => \$opt_update,
"download" => \$opt_download,
"download-force",
"download-recompress=s",
"download-outdir=s",
"download-compare=s",
"download-delete-identical",
) or pod2usage(1);
pod2usage(1) unless @ARGV;
my $ua;
my @specs = @ARGV;
die "--download must be used together with --sources\n" if ($opt_download && !$opt_sources);
die "--update must be used together with --sources\n" if ($opt_update && !$opt_sources);
$options{'download-recompress'} ||= 'auto';
$options{'download-outdir'}.='/' if ($options{'download-outdir'} && $options{'download-outdir'} !~ /\/$/);
$options{'download-outdir'} ||= '';
$options{'download-compare'}.='/' if ($options{'download-compare'} && $options{'download-compare'} !~ /\/$/);
$options{'download-compare'} ||= '';
my @archs;
if (!defined $archs) {
use POSIX qw/uname/;
my %archmap = qw/x86_64 i686 i686 i586 i586 i486 i486 i386/;
my @a = uname();
push @archs, $a[4];
while(exists $archmap{$archs[-1]}) {
push @archs, $archmap{$archs[-1]};
}
} else {
@archs = split(':', $archs);
}
push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
unless ($dist) {
$dist = 'spectool';
# $dist = `rpm -q --qf '%{DISTRIBUTION}' rpm 2>/dev/null`;
# $dist = Build::dist_canon($dist||'', $archs[0]);
}
if($dist !~ /\// && !defined $configdir) {
if($0 =~ /^\//) {
use File::Basename qw/dirname/;
$configdir = dirname($0).'/configs';
undef $configdir unless -e $configdir.'/sl11.3.conf';
} else {
$configdir = $builddir.'/configs';
undef $configdir unless -e $configdir.'/sl11.3.conf';
}
if(!defined $configdir) {
print STDERR "please specify config dir\n";
}
}
#######################################################################
# param: array to fill, spec file
# return: file name
sub read_sources_digests($$)
{
my $files = shift;
my $spec = shift;
my $srcfile = 'sources';
if (! -r $srcfile) {
$srcfile = $spec;
$srcfile =~ s/spec$/sources/;
}
if (open (F, '<', $srcfile)) {
while() {
chomp;
my ($sum, $file) = split(/ +/, $_, 2);
$files->{$file} = $sum;
}
close F;
}
return $srcfile;
}
# param: file, oldsum
# return: newsum or undef if match
sub check_sum($$)
{
my $file = shift;
my $oldsum = shift || 'sha1:';
my $sum;
my $type = 'md5:';
if($oldsum =~ /^(\S+:)/) {
$type = $1;
} else {
$oldsum = $type.$oldsum;
}
if ($type eq 'md5:') {
$sum = $type.`md5sum $file` || die "md5sum failed\n";
} elsif ($type eq 'sha1:') {
$sum = $type.`sha1sum $file` || die "sha1sum failed\n";
} else {
die "unsupported digest type '$type'\n";
}
$sum =~ s/ .*//s;
if($sum ne $oldsum) {
return $sum;
}
return undef;
}
sub download($$)
{
my ($url, $dest) = @_;
my $retry = 3;
while ($retry--) {
my $res = $ua->mirror($url, $dest);
last if $res->is_success;
# if it's a redirect we probably got a bad mirror and should just retry
return 0 unless $retry && $res->previous;
warn "retrying $url\n";
}
return 1;
}
#######################################################################
my $ret = 0;
for my $spec (@specs) {
my $cf = Build::read_config_dist($dist, $archs[0], $configdir);
my $parsed = Build::parse($cf, $spec);
if (!defined $parsed) {
die "can't parse $spec\n";
}
for my $tag (@opt_showtag) {
if($tag =~ /^\/(.+)\/$/) {
my $expr = $1;
for my $t (keys %$parsed) {
if ($t =~ $expr) {
push @opt_showtag, $t;
}
}
} else {
if(exists $parsed->{lc $tag}) {
print $tag, ": ";
my $v = $parsed->{lc $tag};
$v = join(' ', @$v) if (ref $v eq 'ARRAY');
print $v, "\n";
} else {
print STDERR "$tag does not exist\n";
}
}
}
if ($opt_sources) {
my $files = {};
my $srcfile = read_sources_digests($files, $spec);
if ($opt_download) {
unless ($ua) {
use LWP::UserAgent;
$ua = LWP::UserAgent->new(
agent => "openSUSE build service",
env_proxy => 1,
timeout => 42);
}
for my $t (keys %$parsed) {
next unless ($t =~ /^(?:source|patch)\d*/);
my $url = $parsed->{$t};
next unless $url =~ /^(?:https?|ftp):\/\//;
my $file = $url;
$file =~ s/.*\///;
my $src = $options{'download-compare'}.$file;
next if -e $src && !($options{'download-force'} || $options{'download-delete-identical'});
print "Downloading $file...\n";
my $dest = $options{'download-outdir'}.$file;
print "$url -> $dest\n";
if(!download($url, $dest) && $options{'download-recompress'} ne 'no') {
# TODO
# let's see if the file was recompressed
if($url =~ s/\.bz2$/.gz/ && $file =~ s/\.bz2$/.gz/
&& !download($url, $dest)) {
if(system('bznew', $dest) == 0) {
print STDERR "Used $file and recompressed to bz2 instead\n";
} else {
unlink $dest;
}
} else {
print STDERR "Downloading $file failed\n";
}
}
if ($options{'download-delete-identical'} && $options{'download-outdir'}
&& system('cmp', '-s', $dest, $src) == 0) {
unlink($dest);
}
}
}
if ($opt_update) {
my $changed;
for my $t (keys %$parsed) {
next unless ($t =~ /^(?:source|patch)\d*/);
my $file = $parsed->{$t};
$file =~ s/.*\///;
next unless -B $file;
my $sum = check_sum($file, ($files->{$file} || ($srcfile eq 'sources'?'md5:':'sha1:')));
if($sum) {
print STDERR "update $file\n";
$files->{$file} = $sum;
$changed = 1;
}
}
if($changed) {
if(open(F, '>', $srcfile)) {
for my $file (keys %$files) {
$files->{$file} =~ s/^md5:// if $srcfile eq 'sources';
print F $files->{$file}, ' ', $file, "\n";
}
close F;
}
}
} else {
for my $t (keys %$parsed) {
next unless ($t =~ /^(?:source|patch)\d*/);
my $file = $parsed->{$t};
$file =~ s/.*\///;
if (!exists $files->{$file}) {
if (! -e $file) {
print '- ';
} elsif (-B $file) {
print '_ ';
} else {
print 't ';
}
} elsif (! -e $file) {
print 'd ';
delete $files->{$file};
} else {
my $sum = check_sum($file, $files->{$file});
if($sum) {
print '! ';
$ret = 1;
} else {
print '. ';
}
delete $files->{$file};
}
print $parsed->{$t}, "\n";
}
for my $file (keys %$files) {
print "? $file\n";
}
}
}
}
exit $ret;
obs-build-20170201/build-recipe-preinstallimage 0000644 0001750 0001750 00000004652 13044631422 017701 0 ustar alee alee #
# preinstall specific functions.
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
recipe_setup_preinstallimage() {
# should never be called
cleanup_and_exit 1
}
recipe_prepare_preinstallimage() {
:
}
recipe_build_preinstallimage() {
echo "creating preinstall image..."
test -d "$BUILD_ROOT/.preinstall_image" || cleanup_and_exit 1
cd $BUILD_ROOT || cleanup_and_exit 1
TAR="tar"
if test -x /usr/bin/bsdtar; then
TAR="/usr/bin/bsdtar --format gnutar --chroot"
fi
TOPDIRS=
for DIR in .* * ; do
case "$DIR" in
.|..) continue ;;
.build.kernel*) ;; # to be packaged
.build.initrd*) ;; # to be packaged
.build*) continue ;;
.preinstallimage*) continue ;;
.srcfiles*) continue ;;
.pkgs) continue ;;
.rpm-cache) continue ;;
installed-pkg) continue ;;
proc|sys) continue ;;
esac
TOPDIRS="$TOPDIRS $DIR"
done
if ! $TAR -czf .preinstallimage.$$.tar.gz --one-file-system $TOPDIRS ; then
cleanup_and_exit 1
fi
echo "image created."
TOPDIR=/usr/src/packages
mkdir -p $BUILD_ROOT$TOPDIR/OTHER
rm -f $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
for PKG in $BUILD_ROOT/.preinstall_image/* ; do
PKG=${PKG##*/}
read PKG_HDRMD5 PKGID < $BUILD_ROOT/.preinstall_image/$PKG
test -n "$PKG_HDRMD5" || cleanup_and_exit 1
echo "$PKG_HDRMD5 $PKG" >> $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.info
done
mv $BUILD_ROOT/.preinstallimage.$$.tar.gz $BUILD_ROOT$TOPDIR/OTHER/preinstallimage.tar.gz
rm -f $BUILD_ROOT/.build.packages
ln -s ${TOPDIR#/} $BUILD_ROOT/.build.packages
test -d "$SRCDIR" && cd "$SRCDIR"
}
recipe_resultdirs_preinstallimage() {
:
}
obs-build-20170201/build-vm-qemu 0000644 0001750 0001750 00000002525 13044631422 014640 0 ustar alee alee #
# qemu specific functions
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
# just forward everything to kvm...
vm_verify_options_qemu() {
vm_verify_options_kvm
}
vm_startup_qemu() {
vm_startup_kvm
}
vm_kill_qemu() {
vm_kill_kvm
}
vm_fixup_qemu() {
vm_setup_kvm
}
vm_attach_root_qemu() {
vm_attach_root_kvm
}
vm_attach_swap_qemu() {
vm_attach_swap_kvm
}
vm_detach_root_qemu() {
vm_detach_root_kvm
}
vm_detach_swap_qemu() {
vm_detach_swap_kvm
}
vm_cleanup_qemu() {
vm_cleanup_kvm
}
vm_wipe_qemu() {
:
}
obs-build-20170201/build-recipe-debbuild 0000644 0001750 0001750 00000003307 13044631422 016267 0 ustar alee alee #
# debbuild specific functions.
#
################################################################
#
# Copyright (c) 2015 SUSE Linux GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
recipe_setup_debbuild() {
TOPDIR=`chroot $BUILD_ROOT su -c "debbuild --eval '%_topdir'" - $BUILD_USER`
if test -z "$TOPDIR"; then
cleanup_and_exit 1 "Error: TOPDIR empty"
fi
test "$DO_INIT_TOPDIR" = false || rm -rf "$BUILD_ROOT$TOPDIR"
mkdir -p "$BUILD_ROOT$TOPDIR"
mkdir -p "$BUILD_ROOT$TOPDIR/OTHER"
mkdir -p "$BUILD_ROOT$TOPDIR/SOURCES"
mkdir -p "$BUILD_ROOT$TOPDIR/DEBS"
mkdir -p "$BUILD_ROOT$TOPDIR/SDEBS"
mkdir -p "$BUILD_ROOT$TOPDIR/BUILD"
test -e "$BUILD_ROOT$TOPDIR/SPECS" || ln -s SOURCES "$BUILD_ROOT$TOPDIR/SPECS"
chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
}
recipe_prepare_debbuild() {
recipe_prepare_spec "$@"
}
recipe_build_debbuild() {
recipe_build_spec "$@"
}
recipe_resultdirs_debbuild() {
echo DEBS SDEBS
}
obs-build-20170201/Build/ 0000755 0001750 0001750 00000000000 13044631422 013264 5 ustar alee alee obs-build-20170201/Build/Collax.pm 0000644 0001750 0001750 00000003105 13044631422 015043 0 ustar alee alee #
# Copyright 2015 Zarafa B.V. and its licensors
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
package Build::Collax;
use strict;
sub parse {
my($buildconf, $fn) = @_;
my @bscript;
if (ref($fn) eq "ARRAY") {
@bscript = @$fn;
$fn = undef;
} elsif (ref($fn) ne "") {
die "Unhandled ref type in collax";
} else {
local *FH;
if (!open(FH, "<", $fn)) {
return {"error" => "$fn: $!"};
}
@bscript = ;
chomp(@bscript);
close(FH);
}
my $ret = {"deps" => []};
for (my $i = 0; $i <= $#bscript; ++$i) {
next unless $bscript[$i] =~ m{^\w+=};
my $key = lc(substr($&, 0, -1));
my $value = $';
if ($value =~ m{^([\'\"])}) {
$value = substr($value, 1);
while ($value !~ m{[\'\"]}) {
my @cut = splice(@bscript, $i + 1, 1);
$value .= $cut[0];
}
$value =~ s{[\'\"]}{}s;
$value =~ s{\n}{ }gs;
}
if ($key eq "package") {
$ret->{"name"} = $value;
} elsif ($key eq "version") {
$ret->{$key} = $value;
} elsif ($key eq "builddepends" || $key eq "extradepends") {
$value =~ s{^\s+}{}gs;
$value =~ s{\s+$}{}gs;
$value =~ s{,}{ }gs;
push(@{$ret->{"deps"}}, split(/\s+/, $value));
}
}
return $ret;
}
1;
obs-build-20170201/Build/Rpm.pm 0000644 0001750 0001750 00000104732 13044631422 014367 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Rpm;
our $unfilteredprereqs = 0;
our $conflictdeps = 0;
use strict;
use Digest::MD5;
sub expr {
my $expr = shift;
my $lev = shift;
$lev ||= 0;
my ($v, $v2);
$expr =~ s/^\s+//;
my $t = substr($expr, 0, 1);
if ($t eq '(') {
($v, $expr) = expr(substr($expr, 1), 0);
return undef unless defined $v;
return undef unless $expr =~ s/^\)//;
} elsif ($t eq '!') {
($v, $expr) = expr(substr($expr, 1), 5);
return undef unless defined $v;
$v = 0 if $v && $v eq '\"\"';
$v =~ s/^0+/0/ if $v;
$v = !$v;
} elsif ($t eq '-') {
($v, $expr) = expr(substr($expr, 1), 5);
return undef unless defined $v;
$v = -$v;
} elsif ($expr =~ /^([0-9]+)(.*?)$/) {
$v = $1;
$expr = $2;
} elsif ($expr =~ /^([a-zA-Z_0-9]+)(.*)$/) {
$v = "\"$1\"";
$expr = $2;
} elsif ($expr =~ /^(\".*?\")(.*)$/) {
$v = $1;
$expr = $2;
} else {
return;
}
return ($v, $expr) if $lev >= 5;
while (1) {
$expr =~ s/^\s+//;
if ($expr =~ /^&&/) {
return ($v, $expr) if $lev > 1;
($v2, $expr) = expr(substr($expr, 2), 1);
return undef unless defined $v2;
$v = 0 if $v && $v eq '\"\"';
$v =~ s/^0+/0/;
$v2 = 0 if $v2 && $v2 eq '\"\"';
$v2 =~ s/^0+/0/;
$v &&= $v2;
} elsif ($expr =~ /^\|\|/) {
return ($v, $expr) if $lev > 1;
($v2, $expr) = expr(substr($expr, 2), 1);
return undef unless defined $v2;
$v = 0 if $v && $v eq '\"\"';
$v =~ s/^0+/0/;
$v2 = 0 if $v2 && $v2 eq '\"\"';
$v2 =~ s/^0+/0/;
$v ||= $v2;
} elsif ($expr =~ /^>=/) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 2), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v ge $v2 : $v >= $v2) ? 1 : 0;
} elsif ($expr =~ /^>/) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 1), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v gt $v2 : $v > $v2) ? 1 : 0;
} elsif ($expr =~ /^<=/) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 2), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v le $v2 : $v <= $v2) ? 1 : 0;
} elsif ($expr =~ /^) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 1), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v lt $v2 : $v < $v2) ? 1 : 0;
} elsif ($expr =~ /^==/) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 2), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v eq $v2 : $v == $v2) ? 1 : 0;
} elsif ($expr =~ /^!=/) {
return ($v, $expr) if $lev > 2;
($v2, $expr) = expr(substr($expr, 2), 2);
return undef unless defined $v2;
$v = (($v =~ /^\"/) ? $v ne $v2 : $v != $v2) ? 1 : 0;
} elsif ($expr =~ /^\+/) {
return ($v, $expr) if $lev > 3;
($v2, $expr) = expr(substr($expr, 1), 3);
return undef unless defined $v2;
$v += $v2;
} elsif ($expr =~ /^-/) {
return ($v, $expr) if $lev > 3;
($v2, $expr) = expr(substr($expr, 1), 3);
return undef unless defined $v2;
$v -= $v2;
} elsif ($expr =~ /^\*/) {
($v2, $expr) = expr(substr($expr, 1), 4);
return undef unless defined $v2;
$v *= $v2;
} elsif ($expr =~ /^\//) {
($v2, $expr) = expr(substr($expr, 1), 4);
return undef unless defined $v2 && 0 + $v2;
$v /= $v2;
} elsif ($expr =~ /^([=&|])/) {
warn("syntax error while parsing $1$1\n");
return ($v, $expr);
} else {
return ($v, $expr);
}
}
}
sub adaptmacros {
my ($macros, $optold, $optnew) = @_;
for (keys %$optold) {
delete $macros->{$_};
}
for (keys %$optnew) {
$macros->{$_} = $optnew->{$_};
}
return $optnew;
}
sub grabargs {
my ($macname, $getopt, @args) = @_;
my %m;
$m{'0'} = $macname;
$m{'**'} = join(' ', @args);
my %go;
%go = ($getopt =~ /(.)(:*)/sg) if defined $getopt;
while (@args && $args[0] =~ s/^-//) {
my $o = shift @args;
last if $o eq '-';
while ($o =~ /^(.)(.*)$/) {
if ($go{$1}) {
my $arg = $2;
$arg = shift(@args) if @args && $arg eq '';
$m{"-$1"} = "-$1 $arg";
$m{"-$1*"} = $arg;
last;
}
$m{"-$1"} = "-$1";
$o = $2;
}
}
$m{'#'} = scalar(@args);
my $i = 1;
for (@args) {
$m{$i} = $_;
$i++;
}
$m{'*'} = join(' ', @args);
return \%m;
}
# xspec may be passed as array ref to return the parsed spec files
# an entry in the returned array can be
# - a string: verbatim line from the original file
# - a two element array ref:
# - [0] original line
# - [1] undef: line unused due to %if
# - [1] scalar: line after macro expansion. Only set if it's a build deps
# line and build deps got modified or 'save_expanded' is set in
# config
sub parse {
my ($config, $specfile, $xspec) = @_;
my $packname;
my $exclarch;
my $badarch;
my @subpacks;
my @packdeps;
my @prereqs;
my $hasnfb;
my $nfbline;
my %macros;
my %macros_args;
my $ret = {};
my $ifdeps;
my $specdata;
local *SPEC;
if (ref($specfile) eq 'GLOB') {
*SPEC = *$specfile;
} elsif (ref($specfile) eq 'ARRAY') {
$specdata = [ @$specfile ];
} elsif (!open(SPEC, '<', $specfile)) {
warn("$specfile: $!\n");
$ret->{'error'} = "open $specfile: $!";
return $ret;
}
my @macros = @{$config->{'macros'}};
my $skip = 0;
my $main_preamble = 1;
my $preamble = 1;
my $inspec = 0;
my $hasif = 0;
my $lineno = 0;
while (1) {
my $line;
if (@macros) {
$line = shift @macros;
$hasif = 0 unless @macros;
} elsif ($specdata) {
$inspec = 1;
last unless @$specdata;
$line = shift @$specdata;
++$lineno;
if (ref $line) {
$line = $line->[0]; # verbatim line
push @$xspec, $line if $xspec;
$xspec->[-1] = [ $line, undef ] if $xspec && $skip;
next;
}
} else {
$inspec = 1;
$line = ;
last unless defined $line;
chomp $line;
++$lineno;
}
push @$xspec, $line if $inspec && $xspec;
if ($line =~ /^#\s*neededforbuild\s*(\S.*)$/) {
if (defined $hasnfb) {
$xspec->[-1] = [ $xspec->[-1], undef ] if $inspec && $xspec;
next;
}
$hasnfb = $1;
$nfbline = \$xspec->[-1] if $inspec && $xspec;
next;
}
if ($line =~ /^\s*#/) {
next unless $line =~ /^#!Build(?:Ignore|Conflicts)\s*:/i;
}
my $expandedline = '';
if (!$skip && ($line =~ /%/)) {
my $tries = 0;
my @expandstack;
my $optmacros = {};
# newer perls: \{((?:(?>[^{}]+)|(?2))*)\}
reexpand:
while ($line =~ /^(.*?)%(\{([^\}]+)\}|[\?\!]*[0-9a-zA-Z_]+|%|\*\*?|#|\()(.*?)$/) {
if ($tries++ > 1000) {
print STDERR "Warning: spec file parser ",($lineno?" line $lineno":''),": macro too deeply nested\n" if $config->{'warnings'};
$line = 'MACRO';
last;
}
$expandedline .= $1;
$line = $4;
my $macname = defined($3) ? $3 : $2;
my $macorig = $2;
my $macdata;
my $macalt;
if (defined($3)) {
if ($macname =~ /{/) { # {
while (($macname =~ y/{/{/) > ($macname =~ y/}/}/)) {
last unless $line =~ /^([^}]*)}(.*)$/;
$macname .= "}$1";
$macorig .= "$1}";
$line = $2;
}
}
$macdata = '';
if ($macname =~ /^([^\s:]+)([\s:])(.*)$/) {
$macname = $1;
if ($2 eq ':') {
$macalt = $3;
} else {
$macdata = $3;
}
}
}
my $mactest = 0;
if ($macname =~ /^\!\?/ || $macname =~ /^\?\!/) {
$mactest = -1;
} elsif ($macname =~ /^\?/) {
$mactest = 1;
}
$macname =~ s/^[\!\?]+//;
if ($macname eq '%') {
$expandedline .= '%';
next;
} elsif ($macname eq '(') {
print STDERR "Warning: spec file parser",($lineno?" line $lineno":''),": can't expand %(...)\n" if $config->{'warnings'};
$line = 'MACRO';
last;
} elsif ($macname eq 'define' || $macname eq 'global') {
if ($line =~ /^\s*([0-9a-zA-Z_]+)(?:\(([^\)]*)\))?\s*(.*?)$/) {
my $macname = $1;
my $macargs = $2;
my $macbody = $3;
if (defined $macargs) {
$macros_args{$macname} = $macargs;
} else {
delete $macros_args{$macname};
}
$macros{$macname} = $macbody;
}
$line = '';
last;
} elsif ($macname eq 'defined' || $macname eq 'with' || $macname eq 'undefined' || $macname eq 'without' || $macname eq 'bcond_with' || $macname eq 'bcond_without') {
my @args;
if ($macorig =~ /^\{(.*)\}$/) {
@args = split(' ', $1);
shift @args;
} else {
@args = split(' ', $line);
$line = '';
}
next unless @args;
if ($macname eq 'bcond_with') {
$macros{"with_$args[0]"} = 1 if exists $macros{"_with_$args[0]"};
next;
}
if ($macname eq 'bcond_without') {
$macros{"with_$args[0]"} = 1 unless exists $macros{"_without_$args[0]"};
next;
}
$args[0] = "with_$args[0]" if $macname eq 'with' || $macname eq 'without';
$line = ((exists($macros{$args[0]}) ? 1 : 0) ^ ($macname eq 'undefined' || $macname eq 'without' ? 1 : 0)).$line;
} elsif ($macname eq 'expand') {
$macalt = $macros{$macname} unless defined $macalt;
$macalt = '' if $mactest == -1;
push @expandstack, ($expandedline, $line, undef);
$line = $macalt;
$expandedline = '';
} elsif (exists($macros{$macname})) {
if (!defined($macros{$macname})) {
print STDERR "Warning: spec file parser",($lineno?" line $lineno":''),": can't expand '$macname'\n" if $config->{'warnings'};
$line = 'MACRO';
last;
}
if (defined($macros_args{$macname})) {
# macro with args!
if (!defined($macdata)) {
$line =~ /^\s*([^\n]*).*$/;
$macdata = $1;
$line = '';
}
push @expandstack, ($expandedline, $line, $optmacros);
$optmacros = adaptmacros(\%macros, $optmacros, grabargs($macname, $macros_args{$macname}, split(' ', $macdata)));
$line = $macros{$macname};
$expandedline = '';
next;
}
$macalt = $macros{$macname} unless defined $macalt;
$macalt = '' if $mactest == -1;
if ($macalt =~ /%/) {
push @expandstack, ('', $line, 1) if $line ne '';
$line = $macalt;
} else {
$expandedline .= $macalt;
}
} elsif ($mactest) {
$macalt = '' if !defined($macalt) || $mactest == 1;
if ($macalt =~ /%/) {
push @expandstack, ('', $line, 1) if $line ne '';
$line = $macalt;
} else {
$expandedline .= $macalt;
}
} else {
$expandedline .= "%$macorig" unless $macname =~ /^-/;
}
}
$line = $expandedline . $line;
if (@expandstack) {
my $m = pop(@expandstack);
if ($m) {
$optmacros = adaptmacros(\%macros, $optmacros, $m) if ref $m;
$expandstack[-2] .= $line;
$line = pop(@expandstack);
$expandedline = pop(@expandstack);
} else {
my $todo = pop(@expandstack);
$expandedline = pop(@expandstack);
push @expandstack, ('', $todo, 1) if $todo ne '';
}
goto reexpand;
}
}
if ($line =~ /^\s*%else\b/) {
$skip = 1 - $skip if $skip < 2;
next;
}
if ($line =~ /^\s*%endif\b/) {
$skip-- if $skip;
next;
}
$skip++ if $skip && $line =~ /^\s*%if/;
if ($skip) {
$xspec->[-1] = [ $xspec->[-1], undef ] if $xspec;
$ifdeps = 1 if $line =~ /^(BuildRequires|BuildPrereq|BuildConflicts|\#\!BuildIgnore|\#\!BuildConflicts)\s*:\s*(\S.*)$/i;
next;
}
if ($line =~ /^\s*%ifarch(.*)$/) {
my $arch = $macros{'_target_cpu'} || 'unknown';
my @archs = grep {$_ eq $arch} split(/\s+/, $1);
$skip = 1 if !@archs;
$hasif = 1;
next;
}
if ($line =~ /^\s*%ifnarch(.*)$/) {
my $arch = $macros{'_target_cpu'} || 'unknown';
my @archs = grep {$_ eq $arch} split(/\s+/, $1);
$skip = 1 if @archs;
$hasif = 1;
next;
}
if ($line =~ /^\s*%ifos(.*)$/) {
my $os = $macros{'_target_os'} || 'unknown';
my @oss = grep {$_ eq $os} split(/\s+/, $1);
$skip = 1 if !@oss;
$hasif = 1;
next;
}
if ($line =~ /^\s*%ifnos(.*)$/) {
my $os = $macros{'_target_os'} || 'unknown';
my @oss = grep {$_ eq $os} split(/\s+/, $1);
$skip = 1 if @oss;
$hasif = 1;
next;
}
if ($line =~ /^\s*%if(.*)$/) {
my ($v, $r) = expr($1);
$v = 0 if $v && $v eq '\"\"';
$v =~ s/^0+/0/ if $v;
$skip = 1 unless $v;
$hasif = 1;
next;
}
if ($main_preamble) {
if ($line =~ /^(Name|Version|Disttag|Release)\s*:\s*(\S+)/i) {
$ret->{lc $1} = $2;
$macros{lc $1} = $2;
} elsif ($line =~ /^ExclusiveArch\s*:\s*(.*)/i) {
$exclarch ||= [];
push @$exclarch, split(' ', $1);
} elsif ($line =~ /^ExcludeArch\s*:\s*(.*)/i) {
$badarch ||= [];
push @$badarch, split(' ', $1);
}
}
if (@subpacks && $preamble && exists($ret->{'version'}) && $line =~ /^Version\s*:\s*(\S+)/i) {
$ret->{'multiversion'} = 1 if $ret->{'version'} ne $1;
}
if ($line =~ /^(?:Requires\(pre\)|Requires\(post\)|PreReq)\s*:\s*(\S.*)$/i) {
my $deps = $1;
my @deps = $deps =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?(\s+\[[^\]]+\])?[\s,]*/g;
while (@deps) {
my ($pack, $vers, $qual) = splice(@deps, 0, 3);
if (!$unfilteredprereqs && $pack =~ /^\//) {
$ifdeps = 1;
next unless $config->{'fileprovides'}->{$pack};
}
push @prereqs, $pack unless grep {$_ eq $pack} @prereqs;
}
next;
}
if ($preamble && ($line =~ /^(BuildRequires|BuildPrereq|BuildConflicts|\#\!BuildIgnore|\#\!BuildConflicts)\s*:\s*(\S.*)$/i)) {
my $what = $1;
my $deps = $2;
$ifdeps = 1 if $hasif;
# XXX: weird syntax addition. can append arch or project to dependency
# BuildRequire: foo > 17 [i586,x86_64]
# BuildRequire: foo [home:bar]
# BuildRequire: foo [!home:bar]
my @deps = $deps =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?(\s+\[[^\]]+\])?[\s,]*/g;
my $replace = 0;
my @ndeps = ();
while (@deps) {
my ($pack, $vers, $qual) = splice(@deps, 0, 3);
if (defined($qual)) {
$replace = 1;
my $arch = $macros{'_target_cpu'} || '';
my $proj = $macros{'_target_project'} || '';
$qual =~ s/^\s*\[//;
$qual =~ s/\]$//;
my $isneg = 0;
my $bad;
for my $q (split('[\s,]', $qual)) {
$isneg = 1 if $q =~ s/^\!//;
$bad = 1 if !defined($bad) && !$isneg;
if ($isneg) {
if ($q eq $arch || $q eq $proj) {
$bad = 1;
last;
}
} elsif ($q eq $arch || $q eq $proj) {
$bad = 0;
}
}
next if $bad;
}
$vers = '' unless defined $vers;
$vers =~ s/=(>|<)/$1=/;
push @ndeps, "$pack$vers";
}
$replace = 1 if grep {/^-/} @ndeps;
if (lc($what) ne 'buildrequires' && lc($what) ne 'buildprereq') {
if ($conflictdeps && $what =~ /conflict/i) {
push @packdeps, map {"!$_"} @ndeps;
next;
}
push @packdeps, map {"-$_"} @ndeps;
next;
}
if (defined($hasnfb)) {
if ((grep {$_ eq 'glibc' || $_ eq 'rpm' || $_ eq 'gcc' || $_ eq 'bash'} @ndeps) > 2) {
# ignore old generated BuildRequire lines.
$xspec->[-1] = [ $xspec->[-1], undef ] if $xspec;
next;
}
}
push @packdeps, @ndeps;
next unless $xspec && $inspec;
if ($replace) {
my @cndeps = grep {!/^-/} @ndeps;
if (@cndeps) {
$xspec->[-1] = [ $xspec->[-1], "$what: ".join(' ', @cndeps) ];
} else {
$xspec->[-1] = [ $xspec->[-1], ''];
}
}
next;
} elsif ($preamble && $line =~ /^(Source\d*|Patch\d*|Url|Icon)\s*:\s*(\S+)/i) {
my ($tag, $val) = (lc($1), $2);
# associate url and icon tags with the corresponding subpackage
$tag .= scalar @subpacks if ($tag eq 'url' || $tag eq 'icon') && @subpacks;
if ($tag =~ /icon/) {
# there can be a gif and xpm icon
push @{$ret->{$tag}}, $val;
} else {
$ret->{$tag} = $val;
}
}
if ($line =~ /^\s*%package\s+(-n\s+)?(\S+)/) {
if ($1) {
push @subpacks, $2;
} else {
push @subpacks, $ret->{'name'}.'-'.$2 if defined $ret->{'name'};
}
$preamble = 1;
$main_preamble = 0;
}
if ($line =~ /^\s*%(prep|build|install|check|clean|preun|postun|pretrans|posttrans|pre|post|files|changelog|description|triggerpostun|triggerun|triggerin|trigger|verifyscript)/) {
$main_preamble = 0;
$preamble = 0;
}
# do this always?
if ($xspec && @$xspec && $config->{'save_expanded'}) {
$xspec->[-1] = [ $xspec->[-1], $line ];
}
}
close SPEC unless ref $specfile;
if (defined($hasnfb)) {
if (!@packdeps) {
@packdeps = split(' ', $hasnfb);
} elsif ($nfbline) {
$$nfbline = [$$nfbline, undef ];
}
}
unshift @subpacks, $ret->{'name'} if defined $ret->{'name'};
$ret->{'subpacks'} = \@subpacks;
$ret->{'exclarch'} = $exclarch if defined $exclarch;
$ret->{'badarch'} = $badarch if defined $badarch;
$ret->{'deps'} = \@packdeps;
$ret->{'prereqs'} = \@prereqs if @prereqs;
$ret->{'configdependent'} = 1 if $ifdeps;
return $ret;
}
###########################################################################
my %rpmstag = (
"SIGTAG_SIZE" => 1000, # Header+Payload size in bytes. */
"SIGTAG_PGP" => 1002, # RSA signature over Header+Payload
"SIGTAG_MD5" => 1004, # MD5 hash over Header+Payload
"SIGTAG_GPG" => 1005, # DSA signature over Header+Payload
"NAME" => 1000,
"VERSION" => 1001,
"RELEASE" => 1002,
"EPOCH" => 1003,
"SUMMARY" => 1004,
"DESCRIPTION" => 1005,
"BUILDTIME" => 1006,
"ARCH" => 1022,
"OLDFILENAMES" => 1027,
"SOURCERPM" => 1044,
"PROVIDENAME" => 1047,
"REQUIREFLAGS" => 1048,
"REQUIRENAME" => 1049,
"REQUIREVERSION" => 1050,
"NOSOURCE" => 1051,
"NOPATCH" => 1052,
"SOURCEPACKAGE" => 1106,
"PROVIDEFLAGS" => 1112,
"PROVIDEVERSION" => 1113,
"DIRINDEXES" => 1116,
"BASENAMES" => 1117,
"DIRNAMES" => 1118,
"DISTURL" => 1123,
"CONFLICTFLAGS" => 1053,
"CONFLICTNAME" => 1054,
"CONFLICTVERSION" => 1055,
"OBSOLETENAME" => 1090,
"OBSOLETEFLAGS" => 1114,
"OBSOLETEVERSION" => 1115,
"OLDSUGGESTSNAME" => 1156,
"OLDSUGGESTSVERSION" => 1157,
"OLDSUGGESTSFLAGS" => 1158,
"OLDENHANCESNAME" => 1159,
"OLDENHANCESVERSION" => 1160,
"OLDENHANCESFLAGS" => 1161,
"RECOMMENDNAME" => 5046,
"RECOMMENDVERSION" => 5047,
"RECOMMENDFLAGS" => 5048,
"SUGGESTNAME" => 5049,
"SUGGESTVERSION" => 5050,
"SUGGESTFLAGS" => 5051,
"SUPPLEMENTNAME" => 5052,
"SUPPLEMENTVERSION" => 5053,
"SUPPLEMENTFLAGS" => 5054,
"ENHANCENAME" => 5055,
"ENHANCEVERSION" => 5056,
"ENHANCEFLAGS" => 5057,
);
sub rpmq {
my ($rpm, @stags) = @_;
my @sigtags = grep {/^SIGTAG_/} @stags;
@stags = grep {!/^SIGTAG_/} @stags;
my $dosigs = @sigtags && !@stags;
@stags = @sigtags if $dosigs;
my $need_filenames = grep { $_ eq 'FILENAMES' } @stags;
push @stags, 'BASENAMES', 'DIRNAMES', 'DIRINDEXES', 'OLDFILENAMES' if $need_filenames;
@stags = grep { $_ ne 'FILENAMES' } @stags if $need_filenames;
my %stags = map {0 + ($rpmstag{$_} || $_) => $_} @stags;
my ($magic, $sigtype, $headmagic, $cnt, $cntdata, $lead, $head, $index, $data, $tag, $type, $offset, $count);
local *RPM;
my $forcebinary;
if (ref($rpm) eq 'ARRAY') {
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $rpm->[0]);
if ($headmagic != 0x8eade801) {
warn("Bad rpm\n");
return ();
}
if (length($rpm->[0]) < 16 + $cnt * 16 + $cntdata) {
warn("Bad rpm\n");
return ();
}
$index = substr($rpm->[0], 16, $cnt * 16);
$data = substr($rpm->[0], 16 + $cnt * 16, $cntdata);
} else {
if (ref($rpm) eq 'GLOB') {
*RPM = *$rpm;
} elsif (!open(RPM, '<', $rpm)) {
warn("$rpm: $!\n");
return ();
}
if (read(RPM, $lead, 96) != 96) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
($magic, $sigtype) = unpack('N@78n', $lead);
if ($magic != 0xedabeedb || $sigtype != 5) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
$forcebinary = 1 if unpack('@6n', $lead) != 1;
if (read(RPM, $head, 16) != 16) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
if ($headmagic != 0x8eade801) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
$cntdata = ($cntdata + 7) & ~7;
if (read(RPM, $data, $cntdata) != $cntdata) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
}
my %res = ();
if (@sigtags && !$dosigs) {
%res = &rpmq(["$head$index$data"], @sigtags);
}
if (ref($rpm) eq 'ARRAY' && !$dosigs && @$rpm > 1) {
my %res2 = &rpmq([ $rpm->[1] ], @stags);
%res = (%res, %res2);
return %res;
}
if (ref($rpm) ne 'ARRAY' && !$dosigs) {
if (read(RPM, $head, 16) != 16) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
($headmagic, $cnt, $cntdata) = unpack('N@8NN', $head);
if ($headmagic != 0x8eade801) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
if (read(RPM, $index, $cnt * 16) != $cnt * 16) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
if (read(RPM, $data, $cntdata) != $cntdata) {
warn("Bad rpm $rpm\n");
close RPM unless ref($rpm);
return ();
}
}
close RPM unless ref($rpm);
# return %res unless @stags;
while($cnt-- > 0) {
($tag, $type, $offset, $count, $index) = unpack('N4a*', $index);
$tag = 0+$tag;
if ($stags{$tag} || !@stags) {
eval {
my $otag = $stags{$tag} || $tag;
if ($type == 0) {
$res{$otag} = [ '' ];
} elsif ($type == 1) {
$res{$otag} = [ unpack("\@${offset}c$count", $data) ];
} elsif ($type == 2) {
$res{$otag} = [ unpack("\@${offset}c$count", $data) ];
} elsif ($type == 3) {
$res{$otag} = [ unpack("\@${offset}n$count", $data) ];
} elsif ($type == 4) {
$res{$otag} = [ unpack("\@${offset}N$count", $data) ];
} elsif ($type == 5) {
$res{$otag} = [ undef ];
} elsif ($type == 6) {
$res{$otag} = [ unpack("\@${offset}Z*", $data) ];
} elsif ($type == 7) {
$res{$otag} = [ unpack("\@${offset}a$count", $data) ];
} elsif ($type == 8 || $type == 9) {
my $d = unpack("\@${offset}a*", $data);
my @res = split("\0", $d, $count + 1);
$res{$otag} = [ splice @res, 0, $count ];
} else {
$res{$otag} = [ undef ];
}
};
if ($@) {
warn("Bad rpm $rpm: $@\n");
return ();
}
}
}
if ($forcebinary && $stags{1044} && !$res{$stags{1044}} && !($stags{1106} && $res{$stags{1106}})) {
$res{$stags{1044}} = [ '(none)' ]; # like rpm does...
}
if ($need_filenames) {
if ($res{'OLDFILENAMES'}) {
$res{'FILENAMES'} = [ @{$res{'OLDFILENAMES'}} ];
} else {
my $i = 0;
$res{'FILENAMES'} = [ map {"$res{'DIRNAMES'}->[$res{'DIRINDEXES'}->[$i++]]$_"} @{$res{'BASENAMES'}} ];
}
}
return %res;
}
sub add_flagsvers {
my ($res, $name, $flags, $vers) = @_;
return unless $res && $res->{$name};
my @flags = @{$res->{$flags} || []};
my @vers = @{$res->{$vers} || []};
for (@{$res->{$name}}) {
if (@flags && ($flags[0] & 0xe) && @vers) {
$_ .= ' ';
$_ .= '<' if $flags[0] & 2;
$_ .= '>' if $flags[0] & 4;
$_ .= '=' if $flags[0] & 8;
$_ .= " $vers[0]";
}
shift @flags;
shift @vers;
}
}
sub filteroldweak {
my ($res, $name, $flags, $data, $strong, $weak) = @_;
return unless $res && $res->{$name};
my @flags = @{$res->{$flags} || []};
my @strong;
my @weak;
for (@{$res->{$name}}) {
if (@flags && ($flags[0] & 0x8000000)) {
push @strong, $_;
} else {
push @weak, $_;
}
shift @flags;
}
$data->{$strong} = \@strong if @strong;
$data->{$weak} = \@weak if @weak;
}
sub verscmp_part {
my ($s1, $s2) = @_;
if (!defined($s1)) {
return defined($s2) ? -1 : 0;
}
return 1 if !defined $s2;
return 0 if $s1 eq $s2;
while (1) {
$s1 =~ s/^[^a-zA-Z0-9~]+//;
$s2 =~ s/^[^a-zA-Z0-9~]+//;
if ($s1 =~ s/^~//) {
next if $s2 =~ s/^~//;
return -1;
}
return 1 if $s2 =~ /^~/;
if ($s1 eq '') {
return $s2 eq '' ? 0 : -1;
}
return 1 if $s2 eq '';
my ($x1, $x2, $r);
if ($s1 =~ /^([0-9]+)(.*?)$/) {
$x1 = $1;
$s1 = $2;
$s2 =~ /^([0-9]*)(.*?)$/;
$x2 = $1;
$s2 = $2;
return 1 if $x2 eq '';
$x1 =~ s/^0+//;
$x2 =~ s/^0+//;
$r = length($x1) - length($x2) || $x1 cmp $x2;
} elsif ($s1 ne '' && $s2 ne '') {
$s1 =~ /^([a-zA-Z]*)(.*?)$/;
$x1 = $1;
$s1 = $2;
$s2 =~ /^([a-zA-Z]*)(.*?)$/;
$x2 = $1;
$s2 = $2;
return -1 if $x1 eq '' || $x2 eq '';
$r = $x1 cmp $x2;
}
return $r > 0 ? 1 : -1 if $r;
}
}
sub verscmp {
my ($s1, $s2, $dtest) = @_;
return 0 if $s1 eq $s2;
my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e1 = 0 unless defined $e1;
my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e2 = 0 unless defined $e2;
if ($e1 ne $e2) {
my $r = verscmp_part($e1, $e2);
return $r if $r;
}
return 0 if $dtest && ($v1 eq '' || $v2 eq '');
if ($v1 ne $v2) {
my $r = verscmp_part($v1, $v2);
return $r if $r;
}
$r1 = '' unless defined $r1;
$r2 = '' unless defined $r2;
return 0 if $dtest && ($r1 eq '' || $r2 eq '');
if ($r1 ne $r2) {
return verscmp_part($r1, $r2);
}
return 0;
}
sub query {
my ($handle, %opts) = @_;
my @tags = qw{NAME SOURCERPM NOSOURCE NOPATCH SIGTAG_MD5 PROVIDENAME PROVIDEFLAGS PROVIDEVERSION REQUIRENAME REQUIREFLAGS REQUIREVERSION SOURCEPACKAGE};
push @tags, qw{EPOCH VERSION RELEASE ARCH};
push @tags, qw{FILENAMES} if $opts{'filelist'};
push @tags, qw{SUMMARY DESCRIPTION} if $opts{'description'};
push @tags, qw{DISTURL} if $opts{'disturl'};
push @tags, qw{BUILDTIME} if $opts{'buildtime'};
push @tags, qw{CONFLICTNAME CONFLICTVERSION CONFLICTFLAGS OBSOLETENAME OBSOLETEVERSION OBSOLETEFLAGS} if $opts{'conflicts'};
push @tags, qw{RECOMMENDNAME RECOMMENDVERSION RECOMMENDFLAGS SUGGESTNAME SUGGESTVERSION SUGGESTFLAGS SUPPLEMENTNAME SUPPLEMENTVERSION SUPPLEMENTFLAGS ENHANCENAME ENHANCEVERSION ENHANCEFLAGS OLDSUGGESTSNAME OLDSUGGESTSVERSION OLDSUGGESTSFLAGS OLDENHANCESNAME OLDENHANCESVERSION OLDENHANCESFLAGS} if $opts{'weakdeps'};
my %res = rpmq($handle, @tags);
return undef unless %res;
my $src = $res{'SOURCERPM'}->[0];
$src = '' unless defined $src;
$src =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm//;
add_flagsvers(\%res, 'PROVIDENAME', 'PROVIDEFLAGS', 'PROVIDEVERSION');
add_flagsvers(\%res, 'REQUIRENAME', 'REQUIREFLAGS', 'REQUIREVERSION');
my $data = {
name => $res{'NAME'}->[0],
hdrmd5 => unpack('H32', $res{'SIGTAG_MD5'}->[0]),
};
if ($opts{'alldeps'}) {
$data->{'provides'} = [ @{$res{'PROVIDENAME'} || []} ];
$data->{'requires'} = [ @{$res{'REQUIRENAME'} || []} ];
} else {
$data->{'provides'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'PROVIDENAME'} || []} ];
$data->{'requires'} = [ grep {!/^rpmlib\(/ && !/^\//} @{$res{'REQUIRENAME'} || []} ];
}
if ($opts{'conflicts'}) {
add_flagsvers(\%res, 'CONFLICTNAME', 'CONFLICTFLAGS', 'CONFLICTVERSION');
add_flagsvers(\%res, 'OBSOLETENAME', 'OBSOLETEFLAGS', 'OBSOLETEVERSION');
$data->{'conflicts'} = [ @{$res{'CONFLICTNAME'}} ] if $res{'CONFLICTNAME'};
$data->{'obsoletes'} = [ @{$res{'OBSOLETENAME'}} ] if $res{'OBSOLETENAME'};
}
if ($opts{'weakdeps'}) {
for (qw{RECOMMEND SUGGEST SUPPLEMENT ENHANCE}) {
next unless $res{"${_}NAME"};
add_flagsvers(\%res, "${_}NAME", "${_}FLAGS", "${_}VERSION");
$data->{lc($_)."s"} = [ @{$res{"${_}NAME"}} ];
}
if ($res{'OLDSUGGESTSNAME'}) {
add_flagsvers(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', 'OLDSUGGESTSVERSION');
filteroldweak(\%res, 'OLDSUGGESTSNAME', 'OLDSUGGESTSFLAGS', $data, 'recommends', 'suggests');
}
if ($res{'OLDENHANCESNAME'}) {
add_flagsvers(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', 'OLDENHANCESVERSION');
filteroldweak(\%res, 'OLDENHANCESNAME', 'OLDENHANCESFLAGS', $data, 'supplements', 'enhances');
}
}
# rpm3 compatibility: retrofit missing self provides
if ($src ne '') {
my $haveselfprovides;
if (@{$data->{'provides'}}) {
if ($data->{'provides'}->[-1] =~ /^\Q$res{'NAME'}->[0]\E =/) {
$haveselfprovides = 1;
} elsif (@{$data->{'provides'}} > 1 && $data->{'provides'}->[-2] =~ /^\Q$res{'NAME'}->[0]\E =/) {
$haveselfprovides = 1;
}
}
if (!$haveselfprovides) {
my $evr = "$res{'VERSION'}->[0]-$res{'RELEASE'}->[0]";
$evr = "$res{'EPOCH'}->[0]:$evr" if $res{'EPOCH'} && $res{'EPOCH'}->[0];
push @{$data->{'provides'}}, "$res{'NAME'}->[0] = $evr";
}
}
$data->{'source'} = $src eq '(none)' ? $data->{'name'} : $src if $src ne '';
if ($opts{'evra'}) {
my $arch = $res{'ARCH'}->[0];
$arch = $res{'NOSOURCE'} || $res{'NOPATCH'} ? 'nosrc' : 'src' unless $src ne '';
$data->{'version'} = $res{'VERSION'}->[0];
$data->{'release'} = $res{'RELEASE'}->[0];
$data->{'arch'} = $arch;
$data->{'epoch'} = $res{'EPOCH'}->[0] if exists $res{'EPOCH'};
}
if ($opts{'filelist'}) {
$data->{'filelist'} = $res{'FILENAMES'};
}
if ($opts{'description'}) {
$data->{'summary'} = $res{'SUMMARY'}->[0];
$data->{'description'} = $res{'DESCRIPTION'}->[0];
}
$data->{'buildtime'} = $res{'BUILDTIME'}->[0] if $opts{'buildtime'};
$data->{'disturl'} = $res{'DISTURL'}->[0] if $opts{'disturl'} && $res{'DISTURL'};
return $data;
}
sub queryhdrmd5 {
my ($bin, $leadsigp) = @_;
local *F;
open(F, '<', $bin) || die("$bin: $!\n");
my $buf = '';
my $l;
while (length($buf) < 96 + 16) {
$l = sysread(F, $buf, 4096, length($buf));
if (!$l) {
warn("$bin: read error\n");
close(F);
return undef;
}
}
my ($magic, $sigtype) = unpack('N@78n', $buf);
if ($magic != 0xedabeedb || $sigtype != 5) {
warn("$bin: not a rpm (bad magic of header type)\n");
close(F);
return undef;
}
my ($headmagic, $cnt, $cntdata) = unpack('@96N@104NN', $buf);
if ($headmagic != 0x8eade801) {
warn("$bin: not a rpm (bad sig header magic)\n");
close(F);
return undef;
}
my $hlen = 96 + 16 + $cnt * 16 + $cntdata;
$hlen = ($hlen + 7) & ~7;
while (length($buf) < $hlen) {
$l = sysread(F, $buf, 4096, length($buf));
if (!$l) {
warn("$bin: read error\n");
close(F);
return undef;
}
}
close F;
$$leadsigp = Digest::MD5::md5_hex(substr($buf, 0, $hlen)) if $leadsigp;
my $idxarea = substr($buf, 96 + 16, $cnt * 16);
if ($idxarea !~ /\A(?:.{16})*\000\000\003\354\000\000\000\007(....)\000\000\000\020/s) {
warn("$bin: no md5 signature header\n");
return undef;
}
my $md5off = unpack('N', $1);
if ($md5off >= $cntdata) {
warn("$bin: bad md5 offset\n");
return undef;
}
$md5off += 96 + 16 + $cnt * 16;
return unpack("\@${md5off}H32", $buf);
}
sub queryinstalled {
my ($root, %opts) = @_;
$root = '' if !defined($root) || $root eq '/';
local *F;
my $dochroot = $root ne '' && !$opts{'nochroot'} && !$< && (-x "$root/usr/bin/rpm" || -x "$root/bin/rpm") ? 1 : 0;
my $pid = open(F, '-|');
die("fork: $!\n") unless defined $pid;
if (!$pid) {
if ($dochroot && chroot($root)) {
chdir('/') || die("chdir: $!\n");
$root = '';
}
my @args;
unshift @args, '--nodigest', '--nosignature' if -e "$root/usr/bin/rpmquery ";
unshift @args, '--dbpath', "$root/var/lib/rpm" if $root ne '';
push @args, '--qf', '%{NAME}/%{ARCH}/%|EPOCH?{%{EPOCH}}:{0}|/%{VERSION}/%{RELEASE}/%{BUILDTIME}\n';
if (-x "$root/usr/bin/rpm") {
exec("$root/usr/bin/rpm", '-qa', @args);
die("$root/usr/bin/rpm: $!\n");
}
if (-x "$root/bin/rpm") {
exec("$root/bin/rpm", '-qa', @args);
die("$root/bin/rpm: $!\n");
}
die("rpm: command not found\n");
}
my @pkgs;
while () {
chomp;
my @s = split('/', $_);
next unless @s >= 5;
my $q = {'name' => $s[0], 'arch' => $s[1], 'version' => $s[3], 'release' => $s[4]};
$q->{'epoch'} = $s[2] if $s[2];
$q->{'buildtime'} = $s[5] if $s[5];
push @pkgs, $q;
}
if (!close(F)) {
return queryinstalled($root, %opts, 'nochroot' => 1) if !@pkgs && $dochroot;
die("rpm: exit status $?\n");
}
return \@pkgs;
}
# return (lead, sighdr, hdr [, hdrmd5]) of a rpm
sub getrpmheaders {
my ($path, $withhdrmd5) = @_;
my $hdrmd5;
local *F;
open(F, '<', $path) || die("$path: $!\n");
my $buf = '';
my $l;
while (length($buf) < 96 + 16) {
$l = sysread(F, $buf, 4096, length($buf));
die("$path: read error\n") unless $l;
}
die("$path: not a rpm\n") unless unpack('N', $buf) == 0xedabeedb && unpack('@78n', $buf) == 5;
my ($headmagic, $cnt, $cntdata) = unpack('@96N@104NN', $buf);
die("$path: not a rpm (bad sig header)\n") unless $headmagic == 0x8eade801 && $cnt < 16384 && $cntdata < 1048576;
my $hlen = 96 + 16 + $cnt * 16 + $cntdata;
$hlen = ($hlen + 7) & ~7;
while (length($buf) < $hlen + 16) {
$l = sysread(F, $buf, 4096, length($buf));
die("$path: read error\n") unless $l;
}
if ($withhdrmd5) {
my $idxarea = substr($buf, 96 + 16, $cnt * 16);
die("$path: no md5 signature header\n") unless $idxarea =~ /\A(?:.{16})*\000\000\003\354\000\000\000\007(....)\000\000\000\020/s;
my $md5off = unpack('N', $1);
die("$path: bad md5 offset\n") unless $md5off;
$md5off += 96 + 16 + $cnt * 16;
$hdrmd5 = unpack("\@${md5off}H32", $buf);
}
($headmagic, $cnt, $cntdata) = unpack('N@8NN', substr($buf, $hlen));
die("$path: not a rpm (bad header)\n") unless $headmagic == 0x8eade801 && $cnt < 1048576 && $cntdata < 33554432;
my $hlen2 = $hlen + 16 + $cnt * 16 + $cntdata;
while (length($buf) < $hlen2) {
$l = sysread(F, $buf, 4096, length($buf));
die("$path: read error\n") unless $l;
}
close F;
return (substr($buf, 0, 96), substr($buf, 96, $hlen - 96), substr($buf, $hlen, $hlen2 - $hlen), $hdrmd5);
}
1;
obs-build-20170201/Build/Rpmmd.pm 0000644 0001750 0001750 00000016352 13044631422 014710 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Rpmmd;
use strict;
use XML::Parser;
sub generic_parse {
my ($how, $in, $res, %options) = @_;
$res ||= [];
my @cursor = ([undef, $how, undef, $res, undef, \%options]);
my $p = new XML::Parser(Handlers => {
Start => sub {
my ($p, $el) = @_;
my $h = $cursor[-1]->[1];
return unless exists $h->{$el};
$h = $h->{$el};
push @cursor, [$el, $h];
$cursor[-1]->[2] = '' if $h->{'_text'};
$h->{'_start'}->($h, \@cursor, @_) if exists $h->{'_start'};
},
End => sub {
my ($p, $el) = @_;
if ($cursor[-1]->[0] eq $el) {
my $h = $cursor[-1]->[1];
$h->{'_end'}->($h, \@cursor, @_) if exists $h->{'_end'};
pop @cursor;
}
},
Char => sub {
my ($p, $text) = @_;
$cursor[-1]->[2] .= $text if defined $cursor[-1]->[2];
},
}, ErrorContext => 2);
if (ref($in)) {
$p->parse($in);
} else {
$p->parsefile($in);
}
return $res;
}
sub generic_store_text {
my ($h, $c, $p, $el) = @_;
my $data = $c->[0]->[4];
$data->{$h->{'_tag'}} = $c->[-1]->[2] if defined $c->[-1]->[2];
}
sub generic_store_attr {
my ($h, $c, $p, $el, %attr) = @_;
my $data = $c->[0]->[4];
$data->{$h->{'_tag'}} = $attr{$h->{'_attr'}} if defined $attr{$h->{'_attr'}};
}
sub generic_new_data {
my ($h, $c, $p, $el, %attr) = @_;
$c->[0]->[4] = {};
generic_store_attr(@_) if $h->{'_attr'};
}
sub generic_add_result {
my ($h, $c, $p, $el) = @_;
my $data = $c->[0]->[4];
return unless $data;
my $res = $c->[0]->[3];
if (ref($res) eq 'CODE') {
$res->($data);
} else {
push @$res, $data;
}
undef $c->[0]->[4];
}
my $repomdparser = {
repomd => {
data => {
_start => \&generic_new_data,
_attr => 'type',
_tag => 'type',
_end => \&generic_add_result,
location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'},
checksum => { _start => \&generic_store_attr, _attr => 'type', _tag => 'checksum', _text => 1, _end => \&primary_handle_checksum },
size => { _text => 1, _end => \&generic_store_text, _tag => 'size'},
},
},
};
my $primaryparser = {
metadata => {
'package' => {
_start => \&generic_new_data,
_attr => 'type',
_tag => 'type',
_end => \&primary_add_result,
name => { _text => 1, _end => \&generic_store_text, _tag => 'name' },
arch => { _text => 1, _end => \&generic_store_text, _tag => 'arch' },
version => { _start => \&primary_handle_version },
checksum => { _start => \&generic_store_attr, _attr => 'type', _tag => 'checksum', _text => 1, _end => \&primary_handle_checksum },
'time' => { _start => \&primary_handle_time },
format => {
'rpm:provides' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'provides' }, },
'rpm:requires' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'requires' }, },
'rpm:conflicts' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'conflicts' }, },
'rpm:recommends' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'recommends' }, },
'rpm:suggests' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'suggests' }, },
'rpm:supplements' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'supplements' }, },
'rpm:enhances' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'enhances' }, },
'rpm:obsoletes' => { 'rpm:entry' => { _start => \&primary_handle_dep , _tag => 'obsoletes' }, },
'rpm:buildhost' => { _text => 1, _end => \&generic_store_text, _tag => 'buildhost' },
'rpm:sourcerpm' => { _text => 1, _end => \&primary_handle_sourcerpm , _tag => 'source' },
### currently commented out, as we ignore file provides in expanddeps
# file => { _text => 1, _end => \&primary_handle_file_end, _tag => 'provides' },
},
location => { _start => \&generic_store_attr, _attr => 'href', _tag => 'location'},
},
},
};
sub primary_handle_sourcerpm {
my ($h, $c, $p, $el, %attr) = @_;
my $data = $c->[0]->[4];
return unless defined $c->[-1]->[2];
$c->[-1]->[2] =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm$//;
$data->{$h->{'_tag'}} = $c->[-1]->[2];
}
sub primary_handle_version {
my ($h, $c, $p, $el, %attr) = @_;
my $data = $c->[0]->[4];
$data->{'epoch'} = $attr{'epoch'} if $attr{'epoch'};
$data->{'version'} = $attr{'ver'};
$data->{'release'} = $attr{'rel'};
}
sub primary_handle_time {
my ($h, $c, $p, $el, %attr) = @_;
my $data = $c->[0]->[4];
$data->{'filetime'} = $attr{'file'} if $attr{'file'};
$data->{'buildtime'} = $attr{'build'} if $attr{'build'};
}
sub primary_handle_checksum {
my ($h, $c, $p, $el) = @_;
my $data = $c->[0]->[4];
my $type = lc(delete($data->{$h->{'_tag'}}) || '');
$type = 'sha1' if $type eq 'sha';
if ($type eq 'md5' || $type eq 'sha1' || $type eq 'sha256' || $type eq 'sha512') {
$data->{$h->{'_tag'}} = "$type:$c->[-1]->[2]" if defined $c->[-1]->[2];
}
}
sub primary_handle_file_end {
my ($h, $c, $p, $el) = @_;
primary_handle_dep($h, $c, $p, $el, 'name', $c->[-1]->[2]);
}
my %flagmap = ( EQ => '=', LE => '<=', GE => '>=', GT => '>', LT => '<', NE => '!=' );
sub primary_handle_dep {
my ($h, $c, $p, $el, %attr) = @_;
my $dep = $attr{'name'};
return if $dep =~ /^rpmlib\(/;
if(exists $attr{'flags'}) {
my $evr = $attr{'ver'};
return unless defined($evr) && exists($flagmap{$attr{'flags'}});
$evr = "$attr{'epoch'}:$evr" if $attr{'epoch'};
$evr .= "-$attr{'rel'}" if defined $attr{'rel'};
$dep .= " $flagmap{$attr{'flags'}} $evr";
}
my $data = $c->[0]->[4];
push @{$data->{$h->{'_tag'}}}, $dep;
}
sub primary_add_result {
my ($h, $c, $p, $el) = @_;
my $options = $c->[0]->[5] || {};
my $data = $c->[0]->[4];
if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) {
if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') {
my $evr = $data->{'version'};
$evr = "$data->{'epoch'}:$evr" if $data->{'epoch'};
$evr = "$evr-$data->{'release'}" if defined $data->{'release'};
my $s = "$data->{'name'} = $evr";
push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []};
}
}
delete $data->{'checksum'} unless $options->{'withchecksum'};
return generic_add_result(@_);
}
sub parse_repomd {
return generic_parse($repomdparser, @_);
}
sub parse {
return generic_parse($primaryparser, @_);
}
1;
obs-build-20170201/Build/LiveBuild.pm 0000644 0001750 0001750 00000005427 13044631422 015511 0 ustar alee alee ################################################################
#
# Author: Jan Blunck
#
# This file is part of build.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
#################################################################
package Build::LiveBuild;
use strict;
eval { require Archive::Tar; };
*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
sub filter {
my ($content) = @_;
return '' unless defined $content;
$content =~ s/^#.*$//mg;
$content =~ s/^!.*$//mg;
$content =~ s/^\s*//mg;
return $content;
}
sub parse_package_list {
my ($content) = @_;
my @packages = split /\n/, filter($content);
return @packages;
};
sub parse_archive {
my ($content) = @_;
my @repos;
my @lines = split /\n/, filter($content);
for (@lines) {
next if /^deb-src /;
die("bad path using not obs:/ URL: $_\n") unless $_ =~ /^deb\s+obs:\/\/\/?([^\s\/]+)\/([^\s\/]+)\/?\s+.*$/;
push @repos, "$1/$2";
}
return @repos;
}
sub unify {
my %h = map {$_ => 1} @_;
return grep(delete($h{$_}), @_);
}
sub parse {
my ($config, $filename, @args) = @_;
my $ret = {};
# check that filename is a tar
my $tar = Archive::Tar->new;
unless($tar->read($filename)) {
warn("$filename: " . $tar->error . "\n");
$ret->{'error'} = "$filename: " . $tar->error;
return $ret;
}
# check that directory layout matches live-build directory structure
for my $file ($tar->list_files('')) {
next unless $file =~ /^(.*\/)?config\/archives\/.*\.list.*/;
warn("$filename: config/archives/*.list* files not allowed!\n");
$ret->{'error'} = "$filename: config/archives/*.list* files not allowed!";
return $ret;
}
# always require the list of packages required by live-boot for
# bootstrapping the target distribution image (e.g. with debootstrap)
my @packages = ( 'live-build-desc' );
for my $file ($tar->list_files('')) {
next unless $file =~ /^(.*\/)?config\/package-lists\/.*\.list.*/;
push @packages, parse_package_list($tar->get_content($file));
}
($ret->{'name'} = $filename) =~ s/\.[^.]+$//;
$ret->{'deps'} = [ unify(@packages) ];
return $ret;
}
1;
obs-build-20170201/Build/SimpleXML.pm 0000644 0001750 0001750 00000005511 13044631422 015436 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2016 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::SimpleXML;
use strict;
# very simple xml parser, just good enough to parse kiwi and _service files...
# can't use standard XML parsers, unfortunatelly, as the build script
# must not rely on external libraries
#
sub parse {
my ($xml) = @_;
my @nodestack;
my $node = {};
my $c = '';
$xml =~ s/^\s*\<\?.*?\?\>//s;
while ($xml =~ /^(.*?)\//s;
next;
}
die("bad xml\n") unless $xml =~ /(.*?\>)/s;
my $tag = $1;
$xml = substr($xml, length($tag));
my $mode = 0;
if ($tag =~ s/^\<\///s) {
chop $tag;
$mode = 1; # end
} elsif ($tag =~ s/\/\>$//s) {
$mode = 2; # start & end
$tag = substr($tag, 1);
} else {
$tag = substr($tag, 1);
chop $tag;
}
my @tag = split(/(=(?:\"[^\"]*\"|\'[^\']*\'|[^\"\s]*))?\s+/, "$tag ");
$tag = shift @tag;
shift @tag;
push @tag, undef if @tag & 1;
my %atts = @tag;
for (values %atts) {
next unless defined $_;
s/^=\"([^\"]*)\"$/=$1/s or s/^=\'([^\']*)\'$/=$1/s;
s/^=//s;
s/<//g;
s/&/&/g;
s/'/\'/g;
s/"/\"/g;
}
if ($mode == 0 || $mode == 2) {
my $n = {};
push @{$node->{$tag}}, $n;
for (sort keys %atts) {
$n->{$_} = $atts{$_};
}
if ($mode == 0) {
push @nodestack, [ $tag, $node, $c ];
$c = '';
$node = $n;
}
} else {
die("element '$tag' closes without open\n") unless @nodestack;
die("element '$tag' closes, but I expected '$nodestack[-1]->[0]'\n") unless $nodestack[-1]->[0] eq $tag;
$c =~ s/^\s*//s;
$c =~ s/\s*$//s;
$node->{'_content'} = $c if $c ne '';
$node = $nodestack[-1]->[1];
$c = $nodestack[-1]->[2];
pop @nodestack;
}
}
$c .= $xml;
$c =~ s/^\s*//s;
$c =~ s/\s*$//s;
$node->{'_content'} = $c if $c ne '';
return $node;
}
1;
obs-build-20170201/Build/Zypp.pm 0000644 0001750 0001750 00000004650 13044631422 014571 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Zypp;
use strict;
our $root = '';
sub parsecfg {
my ($repocfg, $reponame, $allrepos) = @_;
local *REPO;
open(REPO, '<', "$root/etc/zypp/repos.d/$repocfg") or return undef;
my $name;
my $repo = {};
while () {
chomp;
next if /^\s*#/;
s/\s+$//;
if (/^\[(.+)\]/) {
if ($allrepos && defined($name)) {
$repo->{'description'} = $repo->{'name'} if defined $repo->{'name'};
$repo->{'name'} = $name;
push @$allrepos, $repo;
undef $name;
$repo = {};
}
last if defined $name;
$name = $1 if !defined($reponame) || $reponame eq $1;
} elsif (defined($name)) {
my ($key, $value) = split(/=/, $_, 2);
$repo->{$key} = $value if defined $key;
}
}
close(REPO);
return undef unless defined $name;
$repo->{'description'} = $repo->{'name'} if defined $repo->{'name'};
$repo->{'name'} = $name;
push @$allrepos, $repo if $allrepos;
return $repo;
}
sub repofiles {
local *D;
return () unless opendir(D, "/etc/zypp/repos.d");
my @r = grep {!/^\./ && /.repo$/} readdir(D);
closedir D;
return sort(@r);
}
sub parseallrepos {
my @r;
for my $r (repofiles()) {
parsecfg($r, undef, \@r);
}
return @r;
}
sub parserepo($) {
my ($reponame) = @_;
# first try matching .repo file
if (-e "$root/etc/zypp/repos.d/$reponame.repo") {
my $repo = parsecfg("$reponame.repo", $reponame);
return $repo if $repo;
}
# then try all repo files
for my $r (repofiles()) {
my $repo = parsecfg($r, $reponame);
return $repo if $repo;
}
die("could not find repo '$reponame'\n");
}
1;
# vim: sw=2
obs-build-20170201/Build/Mdkrepo.pm 0000644 0001750 0001750 00000007124 13044631422 015227 0 ustar alee alee ################################################################
#
# Copyright (c) 2015 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Mdkrepo;
use strict;
use Data::Dumper;
sub addpkg {
my ($res, $data, $options) = @_;
if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) {
if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') {
my $evr = $data->{'version'};
$evr = "$data->{'epoch'}:$evr" if $data->{'epoch'};
$evr = "$evr-$data->{'release'}" if defined $data->{'release'};
my $s = "$data->{'name'} = $evr";
push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []};
}
}
if (ref($res) eq 'CODE') {
$res->($data);
} else {
push @$res, $data;
}
}
sub parsedeps {
my ($d) = @_;
my @d = split('@', $d);
for (@d) {
s/\[\*\]//s;
s/\[(.*)\]$/ $1/s;
s/ == / = /;
}
return \@d;
}
sub parse {
my ($in, $res, %options) = @_;
$res ||= [];
my $fd;
if (ref($in)) {
$fd = $in;
} else {
if ($in =~ /\.[gc]z$/) {
# we need to probe, as mageia uses xz for compression
open($fd, '<', $in) || die("$in: $!\n");
my $probe;
sysread($fd, $probe, 5);
close($fd);
if ($probe && $probe eq "\xFD7zXZ") {
open($fd, '-|', "xzdec", "-dc", $in) || die("$in: $!\n");
} else {
open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
}
} else {
open($fd, '<', $in) || die("$in: $!\n");
}
}
my $s = {};
while (<$fd>) {
chomp;
if (/^\@summary\@/) {
$s->{'summary'} = substr($_, 9);
} elsif (/^\@provides\@/) {
$s->{'provides'} = parsedeps(substr($_, 10));
} elsif (/^\@requires\@/) {
$s->{'requires'} = parsedeps(substr($_, 10));
} elsif (/^\@suggests\@/) {
$s->{'suggests'} = parsedeps(substr($_, 10));
} elsif (/^\@recommends\@/) {
$s->{'recommends'} = parsedeps(substr($_, 12));
} elsif (/^\@obsoletes\@/) {
$s->{'obsoletes'} = parsedeps(substr($_, 11));
} elsif (/^\@conflicts\@/) {
$s->{'conflicts'} = parsedeps(substr($_, 11));
} elsif (/^\@info\@/) {
$s ||= {};
my @s = split('@', substr($_, 6));
$s->{'location'} = "$s[0].rpm";
my $arch;
if ($s[0] =~ /\.([^\.]+)$/) {
$arch = $1;
$s[0] =~ s/\.[^\.]+$//;
}
$s->{'epoch'} = $s[1] if $s[1];
$s[0] =~ s/-\Q$s[4]\E[^-]*$//s if defined($s[4]) && $s[4] ne ''; # strip disttag
$s[0] .= ":$s[5]" if defined($s[5]) && $s[5] ne ''; # add distepoch
$s->{'arch'} = $arch || 'noarch';
if ($s[0] =~ /^(.*)-([^-]+)-([^-]+)$/s) {
($s->{'name'}, $s->{'version'}, $s->{'release'}) = ($1, $2, $3);
# fake source entry for now...
$s->{'source'} = $s->{'name'} if $s->{'arch'} ne 'src' && $s->{'arch'} ne 'nosrc';
addpkg($res, $s, \%options);
}
$s = {};
}
}
return $res;
}
1;
obs-build-20170201/Build/Kiwi.pm 0000644 0001750 0001750 00000025471 13044631422 014536 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Kiwi;
use strict;
use Build::SimpleXML;
our $bootcallback;
our $urlmapper;
sub unify {
my %h = map {$_ => 1} @_;
return grep(delete($h{$_}), @_);
}
sub findFallBackArchs {
my ($fallbackArchXML, $arch) = @_;
my @fa;
for my $a (@{$fallbackArchXML->{'arch'}||[]}) {
if ( $a->{'id'} eq $arch && $a->{'fallback'} ) {
@fa = unify( $a->{'fallback'}, findFallBackArchs($fallbackArchXML, $a->{'fallback'}));
}
}
return @fa
}
# sles10 perl does not have the version.pm
# implement own hack
sub versionstring {
my ($str) = @_;
my @xstr = split (/\./,$str);
my $result = 0;
while (my $digit = shift(@xstr)) {
$result = $result * 100;
$result += $digit;
}
return $result;
}
sub kiwiparse {
my ($xml, $arch, $count) = @_;
$count ||= 0;
die("kiwi config inclusion depth limit reached\n") if $count++ > 10;
my $ret = {};
my @types;
my @repos;
my @bootrepos;
my @packages;
my @extrasources;
my @requiredarch;
my @badarch;
my $schemaversion = 0;
my $schemaversion56 = versionstring("5.6");
my $obsexclusivearch;
my $obsexcludearch;
$obsexclusivearch = $1 if $xml =~ /^\s*\s*$/im;
$obsexcludearch = $1 if $xml =~ /^\s*\s*$/im;
my $kiwi = Build::SimpleXML::parse($xml);
die("not a kiwi config\n") unless $kiwi && $kiwi->{'image'};
$kiwi = $kiwi->{'image'}->[0];
$schemaversion = versionstring($kiwi->{'schemaversion'}) if $kiwi->{'schemaversion'};
$ret->{'filename'} = $kiwi->{'name'} if $kiwi->{'name'};
my $description = (($kiwi->{'description'} || [])->[0]) || {};
if ($description->{'specification'}) {
$ret->{'name'} = $description->{'specification'}->[0]->{'_content'};
}
# take default version setting
my $preferences = ($kiwi->{'preferences'} || []);
if ($preferences->[0]->{'version'}) {
$ret->{'version'} = $preferences->[0]->{'version'}->[0]->{'_content'};
}
for my $pref (@{$preferences || []}) {
for my $type (@{$pref->{'type'} || []}) {
next unless @{$pref->{'type'}} == 1 || !$type->{'optional'};
if (defined $type->{'image'}) {
# for kiwi 4.1 and 5.x
push @types, $type->{'image'};
push @packages, "kiwi-image:$type->{'image'}" if $schemaversion >= $schemaversion56;
} else {
# for kiwi 3.8 and before
push @types, $type->{'_content'};
}
push @packages, "kiwi-filesystem:$type->{'filesystem'}" if $type->{'filesystem'};
if (defined $type->{'boot'}) {
if ($type->{'boot'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
next unless $bootcallback;
my ($bootxml, $xsrc) = $bootcallback->($1, $2);
next unless $bootxml;
push @extrasources, $xsrc if $xsrc;
my $bret = kiwiparse($bootxml, $arch, $count);
push @bootrepos, map {"$_->{'project'}/$_->{'repository'}"} @{$bret->{'path'} || []};
push @packages, @{$bret->{'deps'} || []};
push @extrasources, @{$bret->{'extrasource'} || []};
} else {
die("bad boot reference: $type->{'boot'}\n") unless $type->{'boot'} =~ /^([^\/]+)\/([^\/]+)$/;
push @packages, "kiwi-boot:$1";
}
}
}
}
my $instsource = ($kiwi->{'instsource'} || [])->[0];
if ($instsource) {
for my $repository(sort {$a->{priority} <=> $b->{priority}} @{$instsource->{'instrepo'} || []}) {
my $kiwisource = ($repository->{'source'} || [])->[0];
if ($kiwisource->{'path'} eq 'obsrepositories:/') {
# special case, OBS will expand it.
push @repos, '_obsrepositories';
next;
}
if ($kiwisource->{'path'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
push @repos, "$1/$2";
} else {
my $prp;
$prp = $urlmapper->($kiwisource->{'path'}) if $urlmapper;
die("instsource repo url not using obs:/ scheme: $kiwisource->{'path'}\n") unless $prp;
push @repos, $prp;
}
}
$ret->{'sourcemedium'} = -1;
$ret->{'debugmedium'} = -1;
if ($instsource->{'productoptions'}) {
my $productoptions = $instsource->{'productoptions'}->[0] || {};
for my $po (@{$productoptions->{'productvar'} || []}) {
$ret->{'drop_repository'} = $po->{'_content'} if $po->{'name'} eq 'DROP_REPOSITORY';
$ret->{'version'} = $po->{'_content'} if $po->{'name'} eq 'VERSION';
}
for my $po (@{$productoptions->{'productoption'} || []}) {
$ret->{'sourcemedium'} = $po->{'_content'} if $po->{'name'} eq 'SOURCEMEDIUM';
$ret->{'debugmedium'} = $po->{'_content'} if $po->{'name'} eq 'DEBUGMEDIUM';
}
}
if ($instsource->{'architectures'}) {
my $a = $instsource->{'architectures'}->[0] || {};
for my $ra (@{$a->{'requiredarch'} || []}) {
push @requiredarch, $ra->{'ref'} if defined $ra->{'ref'};
}
}
}
# set default values for priority
for (@{$kiwi->{'repository'} || []}) {
next if defined $_->{'priority'};
if ($preferences->[0]->{'packagemanager'}->[0]->{'_content'} eq 'smart') {
$_->{'priority'} = 0;
} else {
$_->{'priority'} = 99;
}
}
my @repositories = sort {$a->{'priority'} <=> $b->{'priority'}} @{$kiwi->{'repository'} || []};
if ($preferences->[0]->{'packagemanager'}->[0]->{'_content'} eq 'smart') {
@repositories = reverse @repositories;
}
for my $repository (@repositories) {
my $kiwisource = ($repository->{'source'} || [])->[0];
next if $kiwisource->{'path'} eq '/var/lib/empty'; # grr
if ($kiwisource->{'path'} eq 'obsrepositories:/') {
push @repos, '_obsrepositories/';
next;
}
if ($kiwisource->{'path'} =~ /^obs:\/\/\/?([^\/]+)\/([^\/]+)\/?$/) {
push @repos, "$1/$2";
} else {
my $prp;
$prp = $urlmapper->($kiwisource->{'path'}) if $urlmapper;
die("repo url not using obs:/ scheme: $kiwisource->{'path'}\n") unless $prp;
push @repos, $prp;
}
}
# Find packages and possible additional required architectures
my @additionalarchs;
my @pkgs;
for my $pattern (@{$kiwi->{'opensusePatterns'}}) {
push @pkgs, @{"pattern:$pattern->{'package'}"} if $pattern->{'package'};
}
for my $packages (@{$kiwi->{'packages'}}) {
next if $packages->{'type'} and $packages->{'type'} ne 'image' and $packages->{'type'} ne 'bootstrap';
push @pkgs, @{$packages->{'package'}} if $packages->{'package'};
}
if ($instsource) {
push @pkgs, @{$instsource->{'metadata'}->[0]->{'repopackage'} || []} if $instsource->{'metadata'};
push @pkgs, @{$instsource->{'repopackages'}->[0]->{'repopackage'} || []} if $instsource->{'repopackages'};
}
@pkgs = unify(@pkgs);
for my $package (@pkgs) {
# filter packages, which are not targeted for the wanted plattform
if ($package->{'arch'}) {
my $valid=undef;
if (@requiredarch) {
# this is a product
foreach my $ma(@requiredarch) {
foreach my $pa(split(",", $package->{'arch'})) {
$valid = 1 if $ma eq $pa;
}
}
} else {
# live appliance
my $ma = $arch;
$ma =~ s/i[456]86/i386/;
foreach my $pa(split(",", $package->{'arch'})) {
$pa =~ s/i[456]86/i386/;
$valid = 1 if $ma eq $pa;
}
}
next unless $valid;
}
# not nice, but optimizes our build dependencies
# FIXME: design a real blacklist option in kiwi
if ($package->{'onlyarch'} && $package->{'onlyarch'} eq "skipit") {
push @packages, "-".$package->{'name'};
next;
}
# handle replaces as buildignore
if ($package->{'replaces'}) {
push @packages, "-".$package->{'replaces'};
}
# we need this package
push @packages, $package->{'name'};
# find the maximal superset of possible required architectures
push @additionalarchs, split(',', $package->{'addarch'}) if $package->{'addarch'};
push @additionalarchs, split(',', $package->{'onlyarch'}) if $package->{'onlyarch'};
}
@requiredarch = unify(@requiredarch, @additionalarchs);
#### FIXME: kiwi files have no informations where to get -32bit packages from
push @requiredarch, "i586" if grep {/^ia64/} @requiredarch;
push @requiredarch, "i586" if grep {/^x86_64/} @requiredarch;
push @requiredarch, "ppc" if grep {/^ppc64/} @requiredarch;
push @requiredarch, "s390" if grep {/^s390x/} @requiredarch;
my @fallbackarchs;
for my $arch (@requiredarch) {
push @fallbackarchs, findFallBackArchs($instsource->{'architectures'}[0], $arch) if $instsource->{'architectures'}[0];
}
@requiredarch = unify(@requiredarch, @fallbackarchs);
if (!$instsource) {
my $packman = $preferences->[0]->{'packagemanager'}->[0]->{'_content'};
push @packages, "kiwi-packagemanager:$packman";
} else {
push @packages, "kiwi-packagemanager:instsource";
}
push @requiredarch, split(' ', $obsexclusivearch) if $obsexclusivearch;
push @badarch , split(' ', $obsexcludearch) if $obsexcludearch;
$ret->{'exclarch'} = [ unify(@requiredarch) ] if @requiredarch;
$ret->{'badarch'} = [ unify(@badarch) ] if @badarch;
$ret->{'deps'} = [ unify(@packages) ];
$ret->{'path'} = [ unify(@repos, @bootrepos) ];
$ret->{'imagetype'} = [ unify(@types) ];
$ret->{'extrasource'} = \@extrasources if @extrasources;
for (@{$ret->{'path'}}) {
my @s = split('/', $_, 2);
$_ = {'project' => $s[0], 'repository' => $s[1]};
}
return $ret;
}
sub parse {
my ($cf, $fn) = @_;
local *F;
open(F, '<', $fn) || die("$fn: $!\n");
my $xml = '';
1 while sysread(F, $xml, 4096, length($xml)) > 0;
close F;
$cf ||= {};
my $d;
eval {
$d = kiwiparse($xml, ($cf->{'arch'} || ''));
};
if ($@) {
my $err = $@;
$err =~ s/^\n$//s;
return {'error' => $err};
}
return $d;
}
sub show {
my ($fn, $field, $arch) = @ARGV;
local $urlmapper = sub { return $_[0] };
my $cf = {'arch' => $arch};
my $d = parse($cf, $fn);
die("$d->{'error'}\n") if $d->{'error'};
my $x = $d->{$field};
$x = [ $x ] unless ref $x;
print "@$x\n";
}
# not implemented yet.
sub queryiso {
my ($handle, %opts) = @_;
return {};
}
sub queryhdrmd5 {
my ($bin) = @_;
die("Build::Kiwi::queryhdrmd5 unimplemented.\n");
}
1;
obs-build-20170201/Build/Deb.pm 0000644 0001750 0001750 00000031300 13044631422 014311 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Deb;
use strict;
use Digest::MD5;
my $have_zlib;
eval {
require Compress::Zlib;
$have_zlib = 1;
};
my %obs2debian = (
"i486" => "i386",
"i586" => "i386",
"i686" => "i386",
"ppc" => "powerpc",
"ppc64le" => "ppc64el",
"x86_64" => "amd64",
"armv4l" => "armel",
"armv5l" => "armel",
"armv6l" => "armel",
"armv7el" => "armel",
"armv7l" => "armhf",
"armv7hl" => "armhf",
"aarch64" => "arm64",
);
sub basearch {
my ($arch) = @_;
return 'all' if !defined($arch) || $arch eq 'noarch';
return $obs2debian{$arch} || $arch;
}
sub obsarch {
my ($arch) = @_;
return grep {$obs2debian{$_} eq $arch} sort keys %obs2debian;
}
sub parse {
my ($bconf, $fn) = @_;
my $ret;
my @control;
# get arch and os from macros
my ($arch, $os);
for (@{$bconf->{'macros'} || []}) {
$arch = $1 if /^%define _target_cpu (\S+)/;
$os = $1 if /^%define _target_os (\S+)/;
}
# map to debian names
$os = 'linux' if !defined($os);
$arch = basearch($arch);
if (ref($fn) eq 'ARRAY') {
@control = @$fn;
} else {
local *F;
if (!open(F, '<', $fn)) {
$ret->{'error'} = "$fn: $!";
return $ret;
}
@control = ;
close F;
chomp @control;
}
splice(@control, 0, 3) if @control > 3 && $control[0] =~ /^-----BEGIN/;
my $name;
my $version;
my @deps;
my @exclarch;
while (@control) {
my $c = shift @control;
last if $c eq ''; # new paragraph
my ($tag, $data) = split(':', $c, 2);
next unless defined $data;
$tag = uc($tag);
while (@control && $control[0] =~ /^\s/) {
$data .= "\n".substr(shift @control, 1);
}
$data =~ s/^\s+//s;
$data =~ s/\s+$//s;
if ($tag eq 'VERSION') {
$version = $data;
$version =~ s/-[^-]+$//;
} elsif ($tag eq 'ARCHITECTURE') {
my @archs = split('\s+', $data);
map { s/\Q$os\E-//; s/any-// } @archs;
next if grep { $_ eq "any" || $_ eq "all" } @archs;
@exclarch = map { obsarch($_) } @archs;
# unify
my %exclarch = map {$_ => 1} @exclarch;
@exclarch = sort keys %exclarch;
} elsif ($tag eq 'SOURCE') {
$name = $data;
} elsif ($tag eq 'BUILD-DEPENDS' || $tag eq 'BUILD-CONFLICTS' || $tag eq 'BUILD-IGNORE' || $tag eq 'BUILD-DEPENDS-INDEP') {
my @d = split(/\s*,\s*/, $data);
for my $d (@d) {
my @alts = split('\s*\|\s*', $d);
my @needed;
for my $c (@alts) {
if ($c =~ /\s+<[^>]+>$/) {
my @build_profiles; # Empty for now
my $bad = 1;
while ($c =~ s/\s+<([^>]+)>$//) {
next if (!$bad);
my $list_valid = 1;
for my $term (split(/\s+/, $1)) {
my $isneg = ($term =~ s/^\!//);
my $profile_match = grep(/^$term$/, @build_profiles);
if (( $profile_match && $isneg) ||
(!$profile_match && !$isneg)) {
$list_valid = 0;
last;
}
}
$bad = 0 if ($list_valid);
}
next if ($bad);
}
if ($c =~ /^(.*?)\s*\[(.*)\]$/) {
$c = $1;
my $isneg = 0;
my $bad;
for my $q (split('[\s,]', $2)) {
$isneg = 1 if $q =~ s/^\!//;
$bad = 1 if !defined($bad) && !$isneg;
if ($isneg) {
if ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") {
$bad = 1;
last;
}
} elsif ($q eq $arch || $q eq 'any' || $q eq "$os-$arch" || $q eq "$os-any" || $q eq "any-$arch") {
$bad = 0;
}
}
next if ($bad);
}
$c =~ s/^([^:\s]*):(any|native)(.*)$/$1$3/;
push @needed, $c;
}
next unless @needed;
$d = join(' | ', @needed);
$d =~ s/ \(([^\)]*)\)/ $1/g;
$d =~ s/>>/>/g;
$d =~ s/<{'name'} = $name;
$ret->{'version'} = $version;
$ret->{'deps'} = \@deps;
$ret->{'exclarch'} = \@exclarch if @exclarch;
return $ret;
}
sub ungzip {
my $data = shift;
local (*TMP, *TMP2);
open(TMP, "+>", undef) or die("could not open tmpfile\n");
syswrite TMP, $data;
sysseek(TMP, 0, 0);
my $pid = open(TMP2, "-|");
die("fork: $!\n") unless defined $pid;
if (!$pid) {
open(STDIN, "<&TMP");
exec 'gunzip';
die("gunzip: $!\n");
}
close(TMP);
$data = '';
1 while sysread(TMP2, $data, 1024, length($data)) > 0;
close(TMP2) || die("gunzip error");
return $data;
}
sub control2res {
my ($control) = @_;
my %res;
my @control = split("\n", $control);
while (@control) {
my $c = shift @control;
last if $c eq ''; # new paragraph
my ($tag, $data) = split(':', $c, 2);
next unless defined $data;
$tag = uc($tag);
while (@control && $control[0] =~ /^\s/) {
$data .= "\n".substr(shift @control, 1);
}
$data =~ s/^\s+//s;
$data =~ s/\s+$//s;
$res{$tag} = $data;
}
return %res;
}
sub debq {
my ($fn) = @_;
local *DEBF;
if (ref($fn) eq 'GLOB') {
*DEBF = *$fn;
} elsif (!open(DEBF, '<', $fn)) {
warn("$fn: $!\n");
return ();
}
my $data = '';
sysread(DEBF, $data, 4096);
if (length($data) < 8+60) {
warn("$fn: not a debian package - header too short\n");
close DEBF unless ref $fn;
return ();
}
if (substr($data, 0, 8+16) ne "!\ndebian-binary " &&
substr($data, 0, 8+16) ne "!\ndebian-binary/ ") {
close DEBF unless ref $fn;
return ();
}
my $len = substr($data, 8+48, 10);
$len += $len & 1;
if (length($data) < 8+60+$len+60) {
my $r = 8+60+$len+60 - length($data);
$r -= length($data);
if ((sysread(DEBF, $data, $r < 4096 ? 4096 : $r, length($data)) || 0) < $r) {
warn("$fn: unexpected EOF\n");
close DEBF unless ref $fn;
return ();
}
}
$data = substr($data, 8 + 60 + $len);
if (substr($data, 0, 16) ne 'control.tar.gz ' &&
substr($data, 0, 16) ne 'control.tar.gz/ ') {
warn("$fn: control.tar.gz is not second ar entry\n");
close DEBF unless ref $fn;
return ();
}
$len = substr($data, 48, 10);
if (length($data) < 60+$len) {
my $r = 60+$len - length($data);
if ((sysread(DEBF, $data, $r, length($data)) || 0) < $r) {
warn("$fn: unexpected EOF\n");
close DEBF unless ref $fn;
return ();
}
}
close DEBF unless ref($fn);
$data = substr($data, 60, $len);
my $controlmd5 = Digest::MD5::md5_hex($data); # our header signature
if ($have_zlib) {
$data = Compress::Zlib::memGunzip($data);
} else {
$data = ungzip($data);
}
if (!$data) {
warn("$fn: corrupt control.tar.gz file\n");
return ();
}
my $control;
while (length($data) >= 512) {
my $n = substr($data, 0, 100);
$n =~ s/\0.*//s;
my $len = oct('00'.substr($data, 124,12));
my $blen = ($len + 1023) & ~511;
if (length($data) < $blen) {
warn("$fn: corrupt control.tar.gz file\n");
return ();
}
if ($n eq './control' || $n eq "control") {
$control = substr($data, 512, $len);
last;
}
$data = substr($data, $blen);
}
my %res = control2res($control);
$res{'CONTROL_MD5'} = $controlmd5;
return %res;
}
sub query {
my ($handle, %opts) = @_;
my %res = debq($handle);
return undef unless %res;
my $name = $res{'PACKAGE'};
my $src = $name;
if ($res{'SOURCE'}) {
$src = $res{'SOURCE'};
$src =~ s/\s.*$//;
}
my @provides = split(',\s*', $res{'PROVIDES'} || '');
if ($opts{'addselfprovides'}) {
push @provides, "$name (= $res{'VERSION'})";
}
my @depends = split(',\s*', $res{'DEPENDS'} || '');
push @depends, split(',\s*', $res{'PRE-DEPENDS'} || '');
my $data = {
name => $name,
hdrmd5 => $res{'CONTROL_MD5'},
provides => \@provides,
requires => \@depends,
};
if ($opts{'conflicts'}) {
my @conflicts = split(',\s*', $res{'CONFLICTS'} || '');
push @conflicts, split(',\s*', $res{'BREAKS'} || '');
$data->{'conflicts'} = \@conflicts if @conflicts;
}
if ($opts{'weakdeps'}) {
for my $dep ('SUGGESTS', 'RECOMMENDS', 'ENHANCES') {
$data->{lc($dep)} = [ split(',\s*', $res{$dep} || '') ] if defined $res{$dep};
}
}
$data->{'source'} = $src if $src ne '';
if ($opts{'evra'}) {
$res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$data->{'epoch'} = $1 if defined $1;
$data->{'version'} = $2;
$data->{'release'} = $3 if defined $3;
$data->{'arch'} = $res{'ARCHITECTURE'};
}
if ($opts{'description'}) {
$data->{'description'} = $res{'DESCRIPTION'};
}
if ($opts{'normalizedeps'}) {
for my $dep (qw{provides requires conflicts suggests enhances recommends}) {
next unless $data->{$dep};
for (@{$data->{$dep}}) {
s/ \(([^\)]*)\)/ $1/g;
s/<>/>/g;
}
}
}
return $data;
}
sub queryhdrmd5 {
my ($bin) = @_;
local *F;
open(F, '<', $bin) || die("$bin: $!\n");
my $data = '';
sysread(F, $data, 4096);
if (length($data) < 8+60) {
warn("$bin: not a debian package - header too short\n");
close F;
return undef;
}
if (substr($data, 0, 8+16) ne "!\ndebian-binary " &&
substr($data, 0, 8+16) ne "!\ndebian-binary/ ") {
warn("$bin: not a debian package - no \"debian-binary\" entry\n");
close F;
return undef;
}
my $len = substr($data, 8+48, 10);
$len += $len & 1;
if (length($data) < 8+60+$len+60) {
my $r = 8+60+$len+60 - length($data);
$r -= length($data);
if ((sysread(F, $data, $r < 4096 ? 4096 : $r, length($data)) || 0) < $r) {
warn("$bin: unexpected EOF\n");
close F;
return undef;
}
}
$data = substr($data, 8 + 60 + $len);
if (substr($data, 0, 16) ne 'control.tar.gz ' &&
substr($data, 0, 16) ne 'control.tar.gz/ ') {
warn("$bin: control.tar.gz is not second ar entry\n");
close F;
return undef;
}
$len = substr($data, 48, 10);
if (length($data) < 60+$len) {
my $r = 60+$len - length($data);
if ((sysread(F, $data, $r, length($data)) || 0) < $r) {
warn("$bin: unexpected EOF\n");
close F;
return undef;
}
}
close F;
$data = substr($data, 60, $len);
return Digest::MD5::md5_hex($data);
}
sub verscmp_part {
my ($s1, $s2) = @_;
return 0 if $s1 eq $s2;
$s1 =~ s/([0-9]+)/substr("00000000000000000000000000000000$1", -32, 32)/ge;
$s2 =~ s/([0-9]+)/substr("00000000000000000000000000000000$1", -32, 32)/ge;
$s1 .= "\0";
$s2 .= "\0";
$s1 =~ tr[\176\000-\037\060-\071\101-\132\141-\172\040-\057\072-\100\133-\140\173-\175][\000-\176];
$s2 =~ tr[\176\000-\037\060-\071\101-\132\141-\172\040-\057\072-\100\133-\140\173-\175][\000-\176];
return $s1 cmp $s2;
}
sub verscmp {
my ($s1, $s2) = @_;
my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e1 = 0 unless defined $e1;
my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$e2 = 0 unless defined $e2;
if ($e1 ne $e2) {
my $r = verscmp_part($e1, $e2);
return $r if $r;
}
my $r = verscmp_part($v1, $v2);
return $r if $r;
$r1 = '' unless defined $r1;
$r2 = '' unless defined $r2;
return verscmp_part($r1, $r2);
}
sub queryinstalled {
my ($root, %opts) = @_;
$root = '' if !defined($root) || $root eq '/';
my @pkgs;
local *F;
if (open(F, '<', "$root/var/lib/dpkg/status")) {
my $ctrl = '';
while() {
if ($_ eq "\n") {
my %res = control2res($ctrl);
if (defined($res{'PACKAGE'})) {
my $data = {'name' => $res{'PACKAGE'}};
$res{'VERSION'} =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
$data->{'epoch'} = $1 if defined $1;
$data->{'version'} = $2;
$data->{'release'} = $3 if defined $3;
$data->{'arch'} = $res{'ARCHITECTURE'};
push @pkgs, $data;
}
$ctrl = '';
next;
}
$ctrl .= $_;
}
close F;
}
return \@pkgs;
}
1;
obs-build-20170201/Build/Snapcraft.pm 0000644 0001750 0001750 00000005037 13044631422 015550 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Snapcraft;
use strict;
use Build::Deb;
eval { require YAML::XS; };
*YAML::XS::LoadFile = sub {die("YAML::XS is not available\n")} unless defined &YAML::XS::LoadFile;
sub parse {
my ($cf, $fn) = @_;
my ($yaml) = YAML::XS::LoadFile($fn);
return {'error' => "Failed to parse yaml file"} unless $yaml;
my $ret = {};
$ret->{'name'} = $yaml->{'name'};
$ret->{'version'} = $yaml->{'version'};
$ret->{'epoch'} = $yaml->{'epoch'} if $yaml->{'epoch'};
# how should we report the built apps?
my @packdeps;
for my $p (@{$yaml->{'stage-packages'} || []}) {
push @packdeps, $p;
}
for my $p (@{$yaml->{'build-packages'} || []}) {
push @packdeps, $p;
}
for my $p (@{$yaml->{'after'} || []}) {
push @packdeps, "snapcraft-part:$p";
}
for my $key (sort keys(%{$yaml->{'parts'} || {}})) {
my $part = $yaml->{'parts'}->{$key};
push @packdeps, "snapcraft-plugin:$part->{plugin}" if defined $part->{plugin};
for my $p (@{$part->{'stage-packages'} || []}) {
push @packdeps, $p;
}
for my $p (@{$part->{'build-packages'} || []}) {
push @packdeps, $p;
}
for my $p (@{$part->{'after'} || []}) {
next if $yaml->{'parts'}->{$p};
push @packdeps, "build-snapcraft-part-$p";
}
}
my %exclarchs;
for my $arch (@{$yaml->{architectures} || []}) {
my @obsarchs = Build::Deb::obsarch($arch);
push @obsarchs, $arch unless @obsarchs;
$exclarchs{$_} = 1 for @obsarchs;
}
$ret->{'exclarch'} = [ sort keys %exclarchs ] if %exclarchs;
# $ret->{'badarch'} = $badarch if defined $badarch;
$ret->{'deps'} = \@packdeps;
# $ret->{'prereqs'} = \@prereqs if @prereqs;
# $ret->{'configdependent'} = 1 if $ifdeps;
return $ret;
}
1;
obs-build-20170201/Build/Susetags.pm 0000644 0001750 0001750 00000010265 13044631422 015424 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Susetags;
use strict;
# compatibility to old OBS code
sub parse_obs_compat {
my ($file, undef, undef, @arches) = @_;
$file = "$file.gz" if ! -e $file && -e "$file.gz";
my $pkgs = {};
parse($file, sub {
my ($data) = @_;
my $medium = delete($data->{'medium'});
my $loc = delete($data->{'location'});
if (defined($medium) && defined($loc)) {
$loc =~ s/^\Q$data->{'arch'}\E\///;
$data->{'path'} = "$medium $loc";
}
return unless !@arches || grep { /$data->{'arch'}/ } @arches;
$pkgs->{"$data->{'name'}-$data->{'version'}-$data->{'release'}-$data->{'arch'}"} = $data;
}, 'addselfprovides' => 1);
return $pkgs;
}
my %tmap = (
'Pkg' => '',
'Loc' => 'location',
'Src' => 'source',
'Prv' => 'provides',
'Req' => 'requires',
'Con' => 'conflicts',
'Obs' => 'obsoletes',
'Rec' => 'recommends',
'Sug' => 'suggests',
'Sup' => 'supplements',
'Enh' => 'enhances',
'Tim' => 'buildtime',
'Cks' => 'checksum',
);
sub addpkg {
my ($res, $data, $options) = @_;
# fixup location and source
if (exists($data->{'location'})) {
my ($medium, $dir, $loc) = split(' ', $data->{'location'}, 3);
$data->{'medium'} = $medium;
$data->{'location'} = defined($loc) ? "$dir/$loc" : "$data->{'arch'}/$dir";
}
$data->{'source'} =~ s/\s.*// if exists $data->{'source'};
if ($options->{'addselfprovides'} && defined($data->{'name'}) && defined($data->{'version'})) {
if (($data->{'arch'} || '') ne 'src' && ($data->{'arch'} || '') ne 'nosrc') {
my $evr = $data->{'version'};
$evr = "$data->{'epoch'}:$evr" if $data->{'epoch'};
$evr = "$evr-$data->{'release'}" if defined $data->{'release'};
my $s = "$data->{'name'} = $evr";
push @{$data->{'provides'}}, $s unless grep {$_ eq $s} @{$data->{'provides'} || []};
}
}
if ($options->{'withchecksum'} && $data->{'checksum'}) {
my ($ctype, $csum) = split(' ', delete($data->{'checksum'}));
$ctype = lc($ctype || '');
$data->{'checksum'} = "$ctype:$csum" if $csum && ($ctype eq 'md5' || $ctype eq 'sha1' || $ctype eq 'sha256' || $ctype eq 'sha512');
}
if (ref($res) eq 'CODE') {
$res->($data);
} else {
push @$res, $data;
}
}
sub parse {
return parse_obs_compat(@_) if @_ > 2 && !defined $_[2];
my ($in, $res, %options) = @_;
$res ||= [];
my $fd;
if (ref($in)) {
$fd = $in;
} else {
if ($in =~ /\.gz$/) {
open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
} else {
open($fd, '<', $in) || die("$in: $!\n");
}
}
my $cur;
my @tmap = sort keys %tmap;
@tmap = grep {$_ ne 'Cks'} @tmap unless $options{'withchecksum'};
my $r = join('|', @tmap);
$r = qr/^([\+=])($r):\s*(.*)/;
while (<$fd>) {
chomp;
next unless /$r/;
my ($multi, $tag, $data) = ($1, $2, $3);
if ($multi eq '+') {
while (<$fd>) {
chomp;
last if /^-\Q$tag\E/;
next if $tag eq 'Req' && /^rpmlib\(/;
push @{$cur->{$tmap{$tag}}}, $_;
}
} elsif ($tag eq 'Pkg') {
addpkg($res, $cur, \%options) if $cur;
$cur = {};
($cur->{'name'}, $cur->{'version'}, $cur->{'release'}, $cur->{'arch'}) = split(' ', $data);
$cur->{'epoch'} = $1 if $cur->{'version'} =~ s/^(\d+)://;
} else {
$cur->{$tmap{$tag}} = $data;
}
}
addpkg($res, $cur, \%options) if $cur;
if (!ref($in)) {
close($fd) || die("close $in: $!\n");
}
return $res;
}
1;
obs-build-20170201/Build/Debrepo.pm 0000644 0001750 0001750 00000007275 13044631422 015215 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Debrepo;
use strict;
sub addpkg {
my ($res, $data, $options) = @_;
return unless defined $data->{'version'};
my $selfprovides;
$selfprovides = "= $data->{'version'}" if $options->{'addselfprovides'};
# split version into evr
$data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s;
$data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s;
for my $d (qw{provides requires conflicts recommends suggests enhances breaks prerequires}) {
next unless $data->{$d};
if ($options->{'normalizedeps'}) {
$data->{$d} =~ s/\(([^\)]*)\)/$1/g;
$data->{$d} =~ s/<{$d} =~ s/>>/>/g;
}
$data->{$d} = [ split(/\s*,\s*/, $data->{$d}) ];
}
push @{$data->{'requires'}}, @{$data->{'prerequires'}} if $data->{'prerequires'};
delete $data->{'prerequires'};
push @{$data->{'conflicts'}}, @{$data->{'breaks'}} if $data->{'breaks'};
delete $data->{'breaks'};
if (defined($selfprovides)) {
$selfprovides = "($selfprovides)" unless $options->{'normalizedeps'};
$selfprovides = "$data->{'name'} $selfprovides";
push @{$data->{'provides'}}, $selfprovides unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides;
}
if ($options->{'withchecksum'}) {
for (qw {md5 sha1 sha256}) {
my $c = delete($data->{"checksum_$_"});
$data->{'checksum'} = "$_:$c" if $c;
}
}
if (ref($res) eq 'CODE') {
$res->($data);
} else {
push @$res, $data;
}
}
my %tmap = (
'package' => 'name',
'version' => 'version',
'architecture' => 'arch',
'provides' => 'provides',
'depends' => 'requires',
'pre-depends' => 'prerequires',
'conflicts' => 'conflicts',
'breaks' => 'breaks',
'recommends' => 'recommends',
'suggests' => 'suggests',
'enhances' => 'enhances',
'filename' => 'location',
'source' => 'source',
);
my %tmap_checksums = (
'md5sum' => 'checksum_md5',
'sha1' => 'checksum_sha1',
'sha256' => 'checksum_sha256',
);
sub parse {
my ($in, $res, %options) = @_;
$res ||= [];
my $fd;
if (ref($in)) {
$fd = $in;
} else {
if ($in =~ /\.gz$/) {
open($fd, '-|', "gzip", "-dc", $in) || die("$in: $!\n");
} else {
open($fd, '<', $in) || die("$in: $!\n");
}
}
my $pkg = {};
my $tag;
my %ltmap = %tmap;
%ltmap = (%ltmap, %tmap_checksums) if $options{'withchecksum'};
while (<$fd>) {
chomp;
if ($_ eq '') {
addpkg($res, $pkg, \%options) if %$pkg;
$pkg = {};
next;
}
if (/^\s/) {
next unless $tag;
$pkg->{$tag} .= "\n".substr($_, 1);
next;
}
my $data;
($tag, $data) = split(':', $_, 2);
next unless defined $data;
$tag = $tmap{lc($tag)};
next unless $tag;
$data =~ s/^\s*//;
$pkg->{$tag} = $data;
}
addpkg($res, $pkg, \%options) if %$pkg;
if (!ref($in)) {
close($fd) || die("close $in: $!\n");
}
return $res;
}
1;
obs-build-20170201/Build/Arch.pm 0000644 0001750 0001750 00000022435 13044631422 014505 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Arch;
use strict;
use Digest::MD5;
eval { require Archive::Tar; };
*Archive::Tar::new = sub {die("Archive::Tar is not available\n")} unless defined &Archive::Tar::new;
# Archlinux support, based on the GSoC work of Nikolay Rysev
# parse a PKGBUILD file
sub quote {
my ($str, $q, $vars) = @_;
if ($q ne "'" && $str =~ /\$/) {
$str =~ s/\$([a-zA-Z0-9_]+|\{([^\}]+)\})/join(' ', @{$vars->{$2 || $1} || []})/ge;
}
$str =~ s/([ \t\"\'\$])/sprintf("%%%02X", ord($1))/ge;
return $str;
}
sub unquotesplit {
my ($str, $vars) = @_;
$str =~ s/%/%25/g;
$str =~ s/^[ \t]+//;
while ($str =~ /([\"\'])/) {
my $q = $1;
last unless $str =~ s/$q(.*?)$q/quote($1, $q, $vars)/e;
}
if ($str =~ /\$/) {
$str =~ s/\$([a-zA-Z0-9_]+|\{([^\}]+)\})/join(' ', @{$vars->{$2 || $1} || []})/ge;
}
my @args = split(/[ \t]+/, $str);
for (@args) {
s/%([a-fA-F0-9]{2})/chr(hex($1))/ge
}
return @args;
}
sub parse {
my ($config, $pkgbuild) = @_;
my $ret;
local *PKG;
if (!open(PKG, '<', $pkgbuild)) {
$ret->{'error'} = "$pkgbuild: $!";
return $ret;
}
my %vars;
my @ifs;
while () {
chomp;
next if /^\s*$/;
next if /^\s*#/;
s/^\s+//;
if (/^(el)?if\s+(?:(?:test|\[)\s+(-n|-z)\s+)?(.*?)\s*\]?\s*;\s*then\s*$/) {
if ($1) {
$ifs[-1] += 1;
next if $ifs[-1] != 1;
pop @ifs;
}
my $flag = $2 || '-n';
my $t = join('', unquotesplit($3, \%vars));
$t = $t eq '' ? 'true' : '' if $flag eq '-z';
push @ifs, $t ne '' ? 1 : 0;
next;
}
if (@ifs) {
if (/^fi\s*$/) {
pop @ifs;
next;
} elsif (/^else\s*$/) {
$ifs[-1] += 1;
next;
}
next if grep {$_ != 1} @ifs;
}
last unless /^([a-zA-Z0-9_]*)(\+?)=(\(?)(.*?)$/;
my $var = $1;
my $app = $2;
my $val = $4;
if ($3) {
while ($val !~ s/\)\s*(?:#.*)?$//s) {
my $nextline = ;
last unless defined $nextline;
chomp $nextline;
$val .= ' ' . $nextline;
}
}
if ($app) {
push @{$vars{$var}}, unquotesplit($val, \%vars);
} else {
$vars{$var} = [ unquotesplit($val, \%vars) ];
}
}
close PKG;
$ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
$ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'};
$ret->{'deps'} = [];
push @{$ret->{'deps'}}, @{$vars{$_} || []} for qw{makedepends checkdepends depends};
# get arch from macros
my $arch;
for (@{$config->{'macros'} || []}) {
$arch = $1 if /^%define _target_cpu (\S+)/;
}
# map to arch linux name and add arch dependent
$arch = 'i686' if $arch =~ /^i[345]86$/;
push @{$ret->{'deps'}}, @{$vars{"${_}_$arch"} || []} for qw{makedepends checkdepends depends};
# Maintain architecture-specific sources for officially supported architectures
for my $asuf ('', '_i686', '_x86_64') {
$ret->{"source$asuf"} = $vars{"source$asuf"} if $vars{"source$asuf"};
}
return $ret;
}
sub islzma {
my ($fn) = @_;
local *F;
return 0 unless open(F, '<', $fn);
my $h;
return 0 unless read(F, $h, 5) == 5;
close F;
return $h eq "\3757zXZ";
}
sub lzmadec {
my ($fn) = @_;
my $nh;
my $pid = open($nh, '-|');
return undef unless defined $pid;
if (!$pid) {
$SIG{'PIPE'} = 'DEFAULT';
exec('xzdec', '-dc', $fn);
die("xzdec: $!\n");
}
return $nh;
}
sub queryvars {
my ($handle) = @_;
if (ref($handle)) {
die("arch pkg query not implemented for file handles\n");
}
if ($handle =~ /\.xz$/ || islzma($handle)) {
$handle = lzmadec($handle);
}
my $tar = Archive::Tar->new;
my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
die("$handle: not an arch package file\n") unless @read == 1;
my $pkginfo = $read[0]->get_content;
die("$handle: not an arch package file\n") unless $pkginfo;
my %vars;
$vars{'_pkginfo'} = $pkginfo;
for my $l (split('\n', $pkginfo)) {
next unless $l =~ /^(.*?) = (.*)$/;
push @{$vars{$1}}, $2;
}
return \%vars;
}
sub queryfiles {
my ($handle) = @_;
if (ref($handle)) {
die("arch pkg query not implemented for file handles\n");
}
if ($handle =~ /\.xz$/ || islzma($handle)) {
$handle = lzmadec($handle);
}
my @files;
my $tar = Archive::Tar->new;
# we use filter_cb here so that Archive::Tar skips the file contents
$tar->read($handle, 1, {'filter_cb' => sub {
my ($entry) = @_;
push @files, $entry->name unless $entry->is_longlink || (@files && $files[-1] eq $entry->name);
return 0;
}});
shift @files if @files && $files[0] eq '.PKGINFO';
return \@files;
}
sub query {
my ($handle, %opts) = @_;
my $vars = queryvars($handle);
my $ret = {};
$ret->{'name'} = $vars->{'pkgname'}->[0] if $vars->{'pkgname'};
$ret->{'hdrmd5'} = Digest::MD5::md5_hex($vars->{'_pkginfo'});
$ret->{'provides'} = $vars->{'provides'} || [];
$ret->{'requires'} = $vars->{'depend'} || [];
if ($vars->{'pkgname'} && $opts{'addselfprovides'}) {
my $selfprovides = $vars->{'pkgname'}->[0];
$selfprovides .= "=$vars->{'pkgver'}->[0]" if $vars->{'pkgver'};
push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides;
}
if ($opts{'evra'}) {
if ($vars->{'pkgver'}) {
my $evr = $vars->{'pkgver'}->[0];
if ($evr =~ /^([0-9]+):(.*)$/) {
$ret->{'epoch'} = $1;
$evr = $2;
}
$ret->{'version'} = $evr;
if ($evr =~ /^(.*)-(.*?)$/) {
$ret->{'version'} = $1;
$ret->{'release'} = $2;
}
}
$ret->{'arch'} = $vars->{'arch'}->[0] if $vars->{'arch'};
}
if ($opts{'description'}) {
$ret->{'description'} = $vars->{'pkgdesc'}->[0] if $vars->{'pkgdesc'};
}
if ($opts{'conflicts'}) {
$ret->{'conflicts'} = $vars->{'conflict'} if $vars->{'conflict'};
$ret->{'obsoletes'} = $vars->{'replaces'} if $vars->{'replaces'};
}
if ($opts{'weakdeps'}) {
my @suggests = @{$vars->{'optdepend'} || []};
s/:.*// for @suggests;
$ret->{'suggests'} = \@suggests if @suggests;
}
# arch packages don't seem to have a source :(
# fake it so that the package isn't confused with a src package
$ret->{'source'} = $ret->{'name'} if defined $ret->{'name'};
$ret->{'buildtime'} = $vars->{'builddate'}->[0] if $opts{'buildtime'} && $vars->{'builddate'};
return $ret;
}
sub queryhdrmd5 {
my ($handle) = @_;
if (ref($handle)) {
die("arch pkg query not implemented for file handles\n");
}
if ($handle =~ /\.xz$/ || islzma($handle)) {
$handle = lzmadec($handle);
}
my $tar = Archive::Tar->new;
my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
die("$handle: not an arch package file\n") unless @read == 1;
my $pkginfo = $read[0]->get_content;
die("$handle: not an arch package file\n") unless $pkginfo;
return Digest::MD5::md5_hex($pkginfo);
}
sub parserepodata {
my ($d, $data) = @_;
$d ||= {};
$data =~ s/^\n+//s;
my @parts = split(/\n\n+/s, $data);
for my $part (@parts) {
my @p = split("\n", $part);
my $p = shift @p;
if ($p eq '%NAME%') {
$d->{'name'} = $p[0];
} elsif ($p eq '%VERSION%') {
$d->{'version'} = $p[0];
} elsif ($p eq '%ARCH%') {
$d->{'arch'} = $p[0];
} elsif ($p eq '%BUILDDATE%') {
$d->{'buildtime'} = $p[0];
} elsif ($p eq '%FILENAME%') {
$d->{'filename'} = $p[0];
} elsif ($p eq '%PROVIDES%') {
push @{$d->{'provides'}}, @p;
} elsif ($p eq '%DEPENDS%') {
push @{$d->{'requires'}}, @p;
} elsif ($p eq '%CONFLICTS%') {
push @{$d->{'conflicts'}}, @p;
} elsif ($p eq '%REPLACES%') {
push @{$d->{'obsoletes'}}, @p;
} elsif ($p eq '%MD5SUM%') {
$d->{'checksum_md5'} = $p[0];
} elsif ($p eq '%SHA256SUM%') {
$d->{'checksum_sha256'} = $p[0];
}
}
return $d;
}
sub queryinstalled {
my ($root, %opts) = @_;
$root = '' if !defined($root) || $root eq '/';
local *D;
local *F;
opendir(D, "$root/var/lib/pacman/local") || return [];
my @pn = sort(grep {!/^\./} readdir(D));
closedir(D);
my @pkgs;
for my $pn (@pn) {
next unless open(F, '<', "$root/var/lib/pacman/local/$pn/desc");
my $data = '';
1 while sysread(F, $data, 8192, length($data));
close F;
my $d = parserepodata(undef, $data);
next unless defined $d->{'name'};
my $q = {};
for (qw{name arch buildtime version}) {
$q->{$_} = $d->{$_} if defined $d->{$_};
}
$q->{'epoch'} = $1 if $q->{'version'} =~ s/^(\d+)://s;
$q->{'release'} = $1 if $q->{'version'} =~ s/-([^-]*)$//s;
push @pkgs, $q;
}
return \@pkgs;
}
1;
obs-build-20170201/Build/Archrepo.pm 0000644 0001750 0001750 00000006202 13044631422 015365 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Archrepo;
use strict;
use Build::Arch;
eval { require Archive::Tar; };
if (!defined &Archive::Tar::iter) {
*Archive::Tar::iter = sub {
my ($class, $filename) = @_;
die("Archive::Tar is not available\n") unless defined &Archive::Tar::new;
Archive::Tar->new();
my $handle = $class->_get_handle($filename, 1, 'rb') or return undef;
my @data;
return sub {
return shift(@data) if !$handle || @data;
my $files = $class->_read_tar($handle, { limit => 1 });
@data = @$files if (ref($files) || '') eq 'ARRAY';
undef $handle unless @data;
return shift @data;
};
};
}
sub addpkg {
my ($res, $data, $options) = @_;
return unless defined $data->{'version'};
if ($options->{'addselfprovides'}) {
my $selfprovides = $data->{'name'};
$selfprovides .= "=$data->{'version'}" if defined $data->{'version'};
push @{$data->{'provides'}}, $selfprovides unless @{$data->{'provides'} || []} && $data->{'provides'}->[-1] eq $selfprovides;
}
if (defined($data->{'version'})) {
# split version into evr
$data->{'epoch'} = $1 if $data->{'version'} =~ s/^(\d+)://s;
$data->{'release'} = $1 if $data->{'version'} =~ s/-([^-]*)$//s;
}
$data->{'location'} = delete($data->{'filename'}) if exists $data->{'filename'};
if ($options->{'withchecksum'}) {
for (qw {md5 sha1 sha256}) {
my $c = delete($data->{"checksum_$_"});
$data->{'checksum'} = "$_:$c" if $c;
}
} else {
delete $data->{"checksum_$_"} for qw {md5 sha1 sha256};
}
if (ref($res) eq 'CODE') {
$res->($data);
} else {
push @$res, $data;
}
}
sub parse {
my ($in, $res, %options) = @_;
$res ||= [];
die("Build::Archrepo::parse needs a filename\n") if ref($in);
die("$in: $!\n") unless -e $in;
my $repodb = Archive::Tar->iter($in, 1);
die("$in is not a tar archive\n") unless $repodb;
my $e;
my $lastfn = '';
my $d;
while ($e = $repodb->()) {
next unless $e->type() == Archive::Tar::Constant::FILE();
my $fn = $e->name();
next unless $fn =~ s/\/(?:depends|desc|files)$//s;
if ($lastfn ne $fn) {
addpkg($res, $d, \%options) if $d->{'name'};
$d = {};
$lastfn = $fn;
}
Build::Arch::parserepodata($d, $e->get_content());
}
addpkg($res, $d, \%options) if $d->{'name'};
return $res;
}
1;
obs-build-20170201/Build/Repo.pm 0000644 0001750 0001750 00000003732 13044631422 014534 0 ustar alee alee ################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
package Build::Repo;
use strict;
our $do_rpmmd;
our $do_deb;
our $do_arch;
our $do_susetags;
our $do_mdk;
sub import {
for (@_) {
$do_rpmmd = 1 if $_ eq ':rpmmd';
$do_deb = 1 if $_ eq ':deb';
$do_arch = 1 if $_ eq ':arch';
$do_susetags = 1 if $_ eq ':susetags';
$do_mdk = 1 if $_ eq ':mdk';
}
$do_rpmmd = $do_deb = $do_arch = $do_susetags = $do_mdk = 1 unless $do_rpmmd || $do_deb || $do_arch || $do_susetags || $do_mdk;
if ($do_rpmmd) {
require Build::Rpmmd;
}
if ($do_susetags) {
require Build::Susetags;
}
if ($do_deb) {
require Build::Debrepo;
}
if ($do_arch) {
require Build::Archrepo;
}
if ($do_mdk) {
require Build::Mdkrepo;
}
}
sub parse {
my ($type, @args) = @_;
return Build::Rpmmd::parse(@args) if $do_rpmmd && $type eq 'rpmmd';
return Build::Susetags::parse(@args) if $do_susetags && $type eq 'susetags';
return Build::Debrepo::parse(@args) if $do_deb && $type eq 'deb';
return Build::Archrepo::parse(@args) if $do_arch && $type eq 'arch';
return Build::Mdkrepo::parse(@args) if $do_arch && $type eq 'mdk';
die("parse repo: unknown type '$type'\n");
}
1;
obs-build-20170201/substitutedeps 0000755 0001750 0001750 00000021047 13044631422 015246 0 ustar alee alee #!/usr/bin/perl -w
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use strict;
use Build;
sub expand {
my ($config, $str) = @_;
my @xspec;
my %cf = %$config;
$cf{'save_expanded'} = 1;
Build::Rpm::parse(\%cf, [ "$str" ], \@xspec);
return @xspec && ref($xspec[0]) ? $xspec[0]->[1] : '';
}
my ($dist, $buildroot, $rpmdeps, $archs, $configdir, $release, $changelog);
$configdir = ($::ENV{'BUILD_DIR'} || '/usr/lib/build') . '/configs';
while (@ARGV) {
if ($ARGV[0] eq '--root') {
shift @ARGV;
$buildroot = shift @ARGV;
next;
}
if ($ARGV[0] eq '--dist') {
shift @ARGV;
$dist = shift @ARGV;
next;
}
if ($ARGV[0] eq '--archpath') {
shift @ARGV;
$archs = shift @ARGV;
next;
}
if ($ARGV[0] eq '--configdir') {
shift @ARGV;
$configdir = shift @ARGV;
next;
}
if ($ARGV[0] eq '--release') {
shift @ARGV;
$release = shift @ARGV;
next;
}
if ($ARGV[0] eq '--changelog') {
shift @ARGV;
$changelog = shift @ARGV;
next;
}
last;
}
die("Usage: substitutedeps --dist --archpath [--configdir ] \n") unless @ARGV == 2;
my $spec = $ARGV[0];
my $specdir = $spec;
$specdir =~ s/[^\/]*$//;
$specdir = "./" if $specdir eq '';
my $newspec = $ARGV[1];
my $cf = Build::read_config_dist($dist, $archs, $configdir);
$cf->{'warnings'} = 1;
#######################################################################
my $xspec = [];
my $d = Build::parse($cf, $spec, $xspec) || {};
my @sdeps = @{$d->{'deps'} || []};
my @neg = map {substr($_, 1)} grep {/^-/} @{$d->{'deps'} || []};
my %neg = map {$_ => 1} @neg;
@sdeps = grep {!$neg{$_}} @sdeps;
@sdeps = Build::do_subst($cf, @sdeps);
@sdeps = grep {!$neg{$_}} @sdeps;
my %sdeps = map {$_ => 1} @sdeps;
open(F, '>', $newspec) || die("$newspec: $!\n");
my $used;
my $inchangelog = 0;
my $mainpkg = '';
my $pkg;
for my $line (@$xspec) {
$used = 1;
if (ref($line)) {
if (!defined($line->[1])) {
$used = 0;
$line = $line->[0];
} else {
$line = $line->[1];
}
}
if ($inchangelog) {
$inchangelog = 0 if $line =~ /^\s*%[^%]/;
next if $inchangelog;
}
if ($changelog && ($line =~ /\s*\%changelog\b/)) {
$inchangelog = 1;
next;
}
if ($line =~ /^Name\s*:\s*(\S+)/i) {
$pkg = $mainpkg = $1 unless $mainpkg;
}
if ($line =~ /^\s*%package\s+(-n\s+)?(\S+)/) {
if ($1) {
$pkg = $2;
} else {
$pkg = "$mainpkg-$2";
}
}
if ($line =~ /^Release\s*:\s*(.*?)\s*$/i) {
my $spec_rel = $1; # User-provided value
my $oldl = $line;
if (defined $release) {
if (!($line =~ s//$release/g)) {
if ($line =~ /<(?:CI_CNT|B_CNT)>/) {
# XXX: should pass ci_cnt/b_cnt instead
if ($release =~ /(\d+)\.(\d+)$/) {
my ($ci, $b) = ($1, $2);
$line =~ s//$ci/;
$line =~ s//$b/;
} elsif ($release =~ /(\d+)$/) {
my $b = $1;
$b = '0' if $line =~ s//$b/;
$line =~ s//$b/;
}
} else {
# no special replacement rules in the line, simply replace
$line =~ s/^(Release\s*:\s*).*/$1$release/i;
$line =~ s//$spec_rel/g;
}
}
$line =~ s///g; # no recursion please
} else {
# remove macros, as rpm doesn't like them
$line =~ s//0/;
$line =~ s//0/;
$line =~ s//0/;
}
if ($cf->{'releasesuffix'}) {
my $suffix = $cf->{'releasesuffix'};
if ($suffix =~ /^file:(.+)$/) {
my $file = $1;
if ($file =~ /\//s || $file =~ /^\./) {
$suffix = "error:illegal release suffix";
} else {
if (open(RP, '<', "$specdir$file")) {
$suffix = "error:no suffix in $file";
for (