[pacman-dev] [PATCH] bacman - regenerate package from system
Original work by Carlo "carlocci" Bersani with additions by Xavier Chantry and Allan McRae This script rebuilds an already installed package using metadata stored into the pacman database and system files. Replaces the outdated re-pacman script Signed-off-by: Allan McRae <mcrae_allan@hotmail.com> --- contrib/README | 2 +- contrib/bacman | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++ contrib/re-pacman | 77 ---------------- 3 files changed, 250 insertions(+), 78 deletions(-) create mode 100755 contrib/bacman delete mode 100755 contrib/re-pacman diff --git a/contrib/README b/contrib/README index 73dbade..5ce7ca4 100644 --- a/contrib/README +++ b/contrib/README @@ -20,7 +20,7 @@ pacsearch - a colorized search combining both -Ss and -Qs output. Installed packages are easily identified with a *** and local-only packages are also listed. -re-pacman - regenerate a pacman package based on installed files and the pacman +bacman - regenerate a pacman package based on installed files and the pacman database entries. Useful for reuse, or possible config file extension. vimprojects - a project file for the vim project plugin. diff --git a/contrib/bacman b/contrib/bacman new file mode 100755 index 0000000..ba124ed --- /dev/null +++ b/contrib/bacman @@ -0,0 +1,249 @@ +#!/bin/bash +# +# bacman: recreate a package from a running system +# This script rebuilds an already installed package using metadata +# stored into the pacman database and system files +# +# (c) 2008 - locci <carlocci_at_gmail_dot_com> +# +# 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 of the License, 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +readonly progname="bacman" +readonly progver="0.1.2" + +# +# User Friendliness +# +function usage(){ + echo "This program recreates a package using pacman's db and system files" + echo "Usage: $progname <installed package name>" + echo "Example: $progname kernel26" +} + +if [ $# -ne 1 ] ; then + usage + exit 1 +fi + +if [ "$1" = "--help" -o "$1" = "-h" ] ; then + usage + exit 0 +fi + +if [ "$1" = "--version" -o "$1" = "-v" ]; then + echo "$progname version $version" + echo "Copyright (C) 2008 locci" + exit 0 +fi + +# +# Setting environmental variables +# +if [ ! -r /etc/pacman.conf ]; then + echo Error: unable to read /etc/pacman.conf + exit 1 +fi + +eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf) +pac_db="${DBPath:-/var/lib/pacman/}/local" + +if [ ! -r /etc/makepkg.conf ]; then + echo Error: unable to read /etc/makepkg.conf + exit 1 +fi + +source "/etc/makepkg.conf" +if [ -r ~/.makepkg.conf ]; then + source ~/.makepkg.conf +fi + +pkg_arch=${CARCH:-'unknown'} +pkg_dest="${PKGDEST:-$PWD}" +pkg_pkger=${PACKAGER:-'Unknown Packager'} + +pkg_name="$1" +pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" +pkg_namver="${pkg_dir##*/}" + +# +# Checks everything is in place +# +if [ ! -d "$pac_db" ] ; then + echo Error: pacman database directory ${pac_db} not found + exit 1 +fi + +if [ ! -d "$pkg_dir" ] ; then + echo Error: package ${pkg_name} not found in pacman database + exit 1 +fi + +# +# Begin +# +echo Package: ${pkg_namver} +work_dir=$(mktemp -d -p /tmp) +cd $work_dir || exit 1 + +# +# File copying +# +echo Copying package files... + +cat "$pkg_dir"/files | +while read i; do + if [ -z "$i" ] ; then + continue + fi + + if [[ "$i" =~ %[A-Z]*% ]] ; then + current=$i + continue + fi + + case $current in + %FILES%) + ret=0 + if [ -d "/$i" ]; then + mkdir "$i" || ret=$? + elif [ -f "/$i" ]; then + cp -dp "/$i" "$i" || ret=$? + else + echo "/$i" is missing: this might result in a broken package + fi + + if [ $ret -ne 0 ]; then + echo Error: unable to create /$i + exit 1 + fi + ;; + esac +done + +ret=$? +if [ $ret -ne 0 ]; then + rm -rf $work_dir + exit 1 +fi + +pkg_size=$(du -sk | awk '{print $1 * 1024}') + +if [ -f "$pkg_dir/install" ] ; then + cp "$pkg_dir/install" "$work_dir/.INSTALL" +fi +if [ -f $pkg_dir/changelog ] ; then + cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" +fi + +# +# .PKGINFO stuff +# +echo Generating .PKGINFO metadata... +echo "# Generated by $progname $progver" > .PKGINFO +echo "# $(LC_ALL=C date)" >> .PKGINFO +echo "#" >> .PKGINFO + +cat "$pkg_dir"/{desc,files,depends} | +while read i; do + if [[ -z "$i" ]]; then + continue; + fi + + if [[ "$i" =~ %[A-Z]*% ]] ; then + current=$i + continue + fi + + case "$current" in + # desc + %NAME%) + echo "pkgname = $i" >> .PKGINFO + ;; + %VERSION%) + echo "pkgver = $i" >> .PKGINFO + ;; + %DESC%) + echo "pkgdesc = $i" >> .PKGINFO + ;; + %URL%) + echo "url = $i" >> .PKGINFO + ;; + %LICENSE%) + echo "license = $i" >> .PKGINFO + ;; + %ARCH%) + echo "arch = $i" >> .PKGINFO + ;; + %BUILDDATE%) + echo "builddate = $(date -u "+%s")" >> .PKGINFO + ;; + %PACKAGER%) + echo "packager = $pkg_pkger" >> .PKGINFO + ;; + %SIZE%) + echo "size = $pkg_size" >> .PKGINFO + ;; + %GROUPS%) + echo "group = $i" >> .PKGINFO + ;; + %REPLACES%) + echo "replaces = $i" >> .PKGINFO + ;; + %FORCE%) + echo "force = true" >> .PKGINFO + ;; + + # files + %BACKUP%) + # strip the md5sum after the tab + echo "backup = ${i%% *}" >> .PKGINFO + ;; + + # depends + %DEPENDS%) + echo "depend = $i" >> .PKGINFO + ;; + %OPTDEPENDS%) + echo "optdepend = $i" >> .PKGINFO + ;; + %CONFLICTS%) + echo "conflict = $i" >> .PKGINFO + ;; + %PROVIDES%) + echo "provides = $i" >> .PKGINFO + ;; + esac +done + +# +# Generate the package +# +echo Generating the package... + +ret=0 +bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? +if [ $ret -ne 0 ]; then + echo Error: unable to write package to $pkg_dest + echo Maybe the disk is full or you do not have write access + exit 1 +fi + +rm -rf $work_dir + +echo Done + +exit 0 + +# vim: set ts=2 sw=2 noet: \ No newline at end of file diff --git a/contrib/re-pacman b/contrib/re-pacman deleted file mode 100755 index fff1c87..0000000 --- a/contrib/re-pacman +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh -# -# re-pacman: regenerate a pacman package based on installed files and the -# pacman database entries. Useful for reuse, or possible config file -# extension -# -# Copyright (c) 2006 Aaron Griffin <aaron@archlinux.org> -# -# 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 of the License, 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. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -#TODO -# * Check for md5 changes in backup lines and change pkgrel - -pacinfo () { - [ $# -ne 2 ] && return 1 - #use echo to strip spaces - echo $(pacman -Qi ${1} | grep "${2}" | cut -d: -f2-) -} - -make_pkginfo () { - echo "# Generated by re-pacman 1.0.0" - echo "# On $(date)" - echo "pkgname =$(pacinfo ${1} Name)" - echo "pkgver =$(pacinfo ${1} Version)" - echo "pkgdesc =$(pacinfo ${1} Description)" - echo "url =$(pacinfo ${1} URL)" - echo "builddate =$(pacinfo ${1} 'Build Date')" - echo "packager =$(pacinfo ${1} Packager)" - echo "size =$(pacinfo ${1} Size)" - echo "arch =$(pacinfo ${1} Architecture)" - deps=$(pacinfo ${1} 'Depends On') - for d in ${deps}; do - echo "depend = ${d}" - done -} - -LANG="POSIX" - -if [ $# -ne 1 ]; then - echo "usage: re-pacman <installed package name>" - exit 1 -fi - -ver=$(pacinfo ${1} Version) -if [ "x${ver}" = "x" ]; then - echo "Package '${1}' not found, aborting." - exit 1 -fi - -echo ":: Cleaning up old files" -rm -f .PKGINFO "${1}-${ver}.pkg.tar.gz" - -echo ":: Building PKGINFO" -make_pkginfo ${1} > .PKGINFO - -flist=".PKGINFO" -flist="${flist} $(pacman -Ql ${1} | sed 's|\w* \(.*\)|/\1|g' | grep -v '/$')" - -echo ":: Building final package tarball" -echo ${flist} | tr ' ' '\n' | tar czf "${1}-${ver}.pkg.tar.gz" -T - 2>/dev/null - -rm -f .PKGINFO -echo ":: Package '${1}-${ver}.pkg.tar.gz' is now ready for installation" - -# vim: set ts=2 sw=2 noet: -- 1.5.5.3
Il Saturday 31 May 2008 15:23:54 Allan McRae ha scritto:
Original work by Carlo "carlocci" Bersani with additions by Xavier Chantry and Allan McRae
This script rebuilds an already installed package using metadata stored into the pacman database and system files. Replaces the outdated re-pacman script
Signed-off-by: Allan McRae <mcrae_allan@hotmail.com>
Hello, I finally had a while to fix the permissions issue and to include fakeroot support. This is the patch to the commit Allan made -------------------------------------BEGIN------------------------------------- --- gitbacman 2008-06-03 19:02:14.000000000 +0200 +++ bacman 2008-06-03 19:16:04.000000000 +0200 @@ -5,7 +5,7 @@ # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> -# +# # 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 of the License, or @@ -15,7 +15,7 @@ # 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. If not, see <http://www.gnu.org/licenses/>. # @@ -24,6 +24,15 @@ readonly progver="0.1.2" # +# Fakeroot +# +if [ -f /usr/bin/fakeroot -a $EUID -gt 0 ] ; then + echo "Entering fakeroot environment" + /usr/bin/fakeroot -u -- $progname $1 + exit $? +fi + +# # User Friendliness # function usage(){ @@ -116,10 +125,9 @@ case $current in %FILES%) ret=0 - if [ -d "/$i" ]; then - mkdir "$i" || ret=$? - elif [ -f "/$i" ]; then - cp -dp "/$i" "$i" || ret=$? + if [ -e "/$i" ]; then + bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - + ret=${PIPESTATUS[0]} else echo "/$i" is missing: this might result in a broken package fi @@ -208,7 +216,7 @@ # files %BACKUP%) # strip the md5sum after the tab - echo "backup = ${i%% *}" >> .PKGINFO + echo "backup = ${i%%$'\t'*}" >> .PKGINFO ;; # depends @@ -228,6 +236,12 @@ done # +# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL +# +chown root:root $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null +chmod 644 $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null + +# # Generate the package # echo Generating the package... @@ -247,3 +261,4 @@ exit 0 # vim: set ts=2 sw=2 noet: + -------------------------------------END------------------------------------- And of course the complete script: -------------------------------------BEGIN------------------------------------- #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # 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 of the License, 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. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # Fakeroot # if [ -f /usr/bin/fakeroot -a $EUID -gt 0 ] ; then echo "Entering fakeroot environment" /usr/bin/fakeroot -u -- $progname $1 exit $? fi # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $version" echo "Copyright (C) 2008 locci" exit 0 fi # # Setting environmental variables # if [ ! -r /etc/pacman.conf ]; then echo Error: unable to read /etc/pacman.conf exit 1 fi eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" if [ ! -r /etc/makepkg.conf ]; then echo Error: unable to read /etc/makepkg.conf exit 1 fi source "/etc/makepkg.conf" if [ -r ~/.makepkg.conf ]; then source ~/.makepkg.conf fi pkg_arch=${CARCH:-'unknown'} pkg_dest="${PKGDEST:-$PWD}" pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) ret=0 if [ -e "/$i" ]; then bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - ret=${PIPESTATUS[0]} else echo "/$i" is missing: this might result in a broken package fi if [ $ret -ne 0 ]; then echo Error: unable to create /$i exit 1 fi ;; esac done ret=$? if [ $ret -ne 0 ]; then rm -rf $work_dir exit 1 fi pkg_size=$(du -sk | awk '{print $1 * 1024}') if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%%$'\t'*}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; esac done # # Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL # chown root:root $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null chmod 644 $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null # # Generate the package # echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access exit 1 fi rm -rf $work_dir echo Done exit 0 # vim: set ts=2 sw=2 noet: -------------------------------------END-------------------------------------
Carlo Bersani wrote:
Hello, I finally had a while to fix the permissions issue and to include fakeroot support.
Great, tested this with mlocate and the permissions get setup nicely. I did notice one regression though.
# +# Fakeroot +# +if [ -f /usr/bin/fakeroot -a $EUID -gt 0 ] ; then + echo "Entering fakeroot environment" + /usr/bin/fakeroot -u -- $progname $1 + exit $? +fi
We should add a warning here if fakeroot is missing so the user knows the permissions might be messy. The positioning of this block also needs to be considered, e.g.:
./bacman Entering fakeroot environment This program recreates a package using pacman's db and system files Usage: bacman <installed package name> Example: bacman kernel26
@@ -116,10 +125,9 @@ case $current in %FILES%) ret=0 - if [ -d "/$i" ]; then - mkdir "$i" || ret=$? - elif [ -f "/$i" ]; then - cp -dp "/$i" "$i" || ret=$? + if [ -e "/$i" ]; then + bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - + ret=${PIPESTATUS[0]} else echo "/$i" is missing: this might result in a broken package fi
The ret catch from bsdtar is not working correctly. E.g. making the sudo package where the user does not have permission to read /etc/sudoers no longer has that error caught. Instead of checking $PIPESTATUS, how about checking the actual file is present: if [ ! -e $work_dir/$i ]; then ret=1 fi Allan
Il Wednesday 04 June 2008 05:55:55 Allan McRae ha scritto:
Carlo Bersani wrote:
Hello, I finally had a while to fix the permissions issue and to include fakeroot support.
Great, tested this with mlocate and the permissions get setup nicely. I did notice one regression though.
We should add a warning here if fakeroot is missing so the user knows the permissions might be messy.
The positioning of this block also needs to be considered, e.g.:
./bacman
Entering fakeroot environment This program recreates a package using pacman's db and system files Usage: bacman <installed package name> Example: bacman kernel26
Wops, that was stupid : ) I fixed that
+ if [ -e "/$i" ]; then + bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - + ret=${PIPESTATUS[0]} else echo "/$i" is missing: this might result in a broken package fi
The ret catch from bsdtar is not working correctly. E.g. making the sudo package where the user does not have permission to read /etc/sudoers no longer has that error caught.
And I even checked $PIPESTATUS behaviour before. This looks like a problem with bsdtar which returns 0 even if the file is missing: carlocci ~/.abs/tmp $ bsdtar -cf foo.tar /etc/shadow && echo I\'m dumb! bsdtar: Removing leading '/' from member names bsdtar: /etc/shadow: could not open file: Permission denied I'm dumb!
Instead of checking $PIPESTATUS, how about checking the actual file is present:
if [ ! -e $work_dir/$i ]; then ret=1 fi
This is a nice workaround, as long as we can't trust bsdtar. Here's the patch to the commit Allan made: --- gitbacman 2008-06-03 19:02:14.000000000 +0200 +++ bacman 2008-06-04 18:43:19.000000000 +0200 @@ -43,12 +43,33 @@ fi if [ "$1" = "--version" -o "$1" = "-v" ]; then - echo "$progname version $version" + echo "$progname version $progver" echo "Copyright (C) 2008 locci" exit 0 fi # +# Fakeroot support +# +if [ $EUID -gt 0 ]; then + if [ -f /usr/bin/fakeroot ]; then + echo "Entering fakeroot environment" + export INFAKEROOT="1" + /usr/bin/fakeroot -u -- $0 $1 + exit $? + else + echo "You should install fakeroot or run $progname as root" + echo "Otherwise $progname won't be able to preserve the owner:group of the files" + exit 1 + fi +elif [ $EUID -eq 0 ] && [ -z $INFAKEROOT ]; then + echo + echo "CAUTION: you might be packaging security sensitive data!" + echo +fi + +# # Setting environmental variables # if [ ! -r /etc/pacman.conf ]; then @@ -116,16 +137,21 @@ case $current in %FILES%) ret=0 - if [ -d "/$i" ]; then - mkdir "$i" || ret=$? - elif [ -f "/$i" ]; then - cp -dp "/$i" "$i" || ret=$? + if [ -e "/$i" ]; then + bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - else echo "/$i" is missing: this might result in a broken package fi - if [ $ret -ne 0 ]; then - echo Error: unable to create /$i + # Workaround to bsdtar not reporting a missing file as an error + if [ ! -e "$work_dir"/"$i" ]; then + echo + echo "Error: unable to add /$i to the package" + echo "Check the file permissions, probably the file contains important data" + echo "If you can't read it as a user, you probably should not make a package" + echo "with it inside: it might result in a security hazard" + echo "Run $progname as root, if you know what you are doing" + echo exit 1 fi ;; @@ -152,6 +178,9 @@ # echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO +if [ -n $INFAKEROOT ]; then + echo "# Using $(fakeroot -v)" >> .PKGINFO +fi echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO @@ -208,7 +237,7 @@ # files %BACKUP%) # strip the md5sum after the tab - echo "backup = ${i%% *}" >> .PKGINFO + echo "backup = ${i%%$'\t'*}" >> .PKGINFO ;; # depends @@ -228,6 +257,12 @@ done # +# Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL +# +chown root:root $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null +chmod 644 $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null + +# # Generate the package # echo Generating the package... @@ -237,6 +272,7 @@ if [ $ret -ne 0 ]; then echo Error: unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access + rm -rf $work_dir exit 1 fi @@ -247,3 +283,4 @@ exit 0 # vim: set ts=2 sw=2 noet: + Here's the whole script: #!/bin/bash # # bacman: recreate a package from a running system # This script rebuilds an already installed package using metadata # stored into the pacman database and system files # # (c) 2008 - locci <carlocci_at_gmail_dot_com> # # 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 of the License, 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. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # readonly progname="bacman" readonly progver="0.1.2" # # User Friendliness # function usage(){ echo "This program recreates a package using pacman's db and system files" echo "Usage: $progname <installed package name>" echo "Example: $progname kernel26" } if [ $# -ne 1 ] ; then usage exit 1 fi if [ "$1" = "--help" -o "$1" = "-h" ] ; then usage exit 0 fi if [ "$1" = "--version" -o "$1" = "-v" ]; then echo "$progname version $progver" echo "Copyright (C) 2008 locci" exit 0 fi # # Fakeroot support # if [ $EUID -gt 0 ]; then if [ -f /usr/bin/fakeroot ]; then echo "Entering fakeroot environment" export INFAKEROOT="1" /usr/bin/fakeroot -u -- $0 $1 exit $? else echo "You should install fakeroot or run $progname as root" echo "Otherwise $progname won't be able to preserve the owner:group of the files" exit 1 fi elif [ $EUID -eq 0 ] && [ -z $INFAKEROOT ]; then echo echo "CAUTION: you might be packaging security sensitive data!" echo fi # # Setting environmental variables # if [ ! -r /etc/pacman.conf ]; then echo Error: unable to read /etc/pacman.conf exit 1 fi eval $(awk '/DBPath/ {print $1$2$3}' /etc/pacman.conf) pac_db="${DBPath:-/var/lib/pacman/}/local" if [ ! -r /etc/makepkg.conf ]; then echo Error: unable to read /etc/makepkg.conf exit 1 fi source "/etc/makepkg.conf" if [ -r ~/.makepkg.conf ]; then source ~/.makepkg.conf fi pkg_arch=${CARCH:-'unknown'} pkg_dest="${PKGDEST:-$PWD}" pkg_pkger=${PACKAGER:-'Unknown Packager'} pkg_name="$1" pkg_dir="$(echo $pac_db/$pkg_name-[0-9]*)" pkg_namver="${pkg_dir##*/}" # # Checks everything is in place # if [ ! -d "$pac_db" ] ; then echo Error: pacman database directory ${pac_db} not found exit 1 fi if [ ! -d "$pkg_dir" ] ; then echo Error: package ${pkg_name} not found in pacman database exit 1 fi # # Begin # echo Package: ${pkg_namver} work_dir=$(mktemp -d -p /tmp) cd $work_dir || exit 1 # # File copying # echo Copying package files... cat "$pkg_dir"/files | while read i; do if [ -z "$i" ] ; then continue fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case $current in %FILES%) ret=0 if [ -e "/$i" ]; then bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - else echo "/$i" is missing: this might result in a broken package fi # Workaround to bsdtar not reporting a missing file as an error if [ ! -e "$work_dir"/"$i" ]; then echo echo "Error: unable to add /$i to the package" echo "Check the file permissions, probably the file contains important data" echo "If you can't read it as a user, you probably should not make a package" echo "with it inside: it might result in a security hazard" echo "Run $progname as root, if you know what you are doing" echo exit 1 fi ;; esac done ret=$? if [ $ret -ne 0 ]; then rm -rf $work_dir exit 1 fi pkg_size=$(du -sk | awk '{print $1 * 1024}') if [ -f "$pkg_dir/install" ] ; then cp "$pkg_dir/install" "$work_dir/.INSTALL" fi if [ -f $pkg_dir/changelog ] ; then cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" fi # # .PKGINFO stuff # echo Generating .PKGINFO metadata... echo "# Generated by $progname $progver" > .PKGINFO if [ -n $INFAKEROOT ]; then echo "# Using $(fakeroot -v)" >> .PKGINFO fi echo "# $(LC_ALL=C date)" >> .PKGINFO echo "#" >> .PKGINFO cat "$pkg_dir"/{desc,files,depends} | while read i; do if [[ -z "$i" ]]; then continue; fi if [[ "$i" =~ %[A-Z]*% ]] ; then current=$i continue fi case "$current" in # desc %NAME%) echo "pkgname = $i" >> .PKGINFO ;; %VERSION%) echo "pkgver = $i" >> .PKGINFO ;; %DESC%) echo "pkgdesc = $i" >> .PKGINFO ;; %URL%) echo "url = $i" >> .PKGINFO ;; %LICENSE%) echo "license = $i" >> .PKGINFO ;; %ARCH%) echo "arch = $i" >> .PKGINFO ;; %BUILDDATE%) echo "builddate = $(date -u "+%s")" >> .PKGINFO ;; %PACKAGER%) echo "packager = $pkg_pkger" >> .PKGINFO ;; %SIZE%) echo "size = $pkg_size" >> .PKGINFO ;; %GROUPS%) echo "group = $i" >> .PKGINFO ;; %REPLACES%) echo "replaces = $i" >> .PKGINFO ;; %FORCE%) echo "force = true" >> .PKGINFO ;; # files %BACKUP%) # strip the md5sum after the tab echo "backup = ${i%%$'\t'*}" >> .PKGINFO ;; # depends %DEPENDS%) echo "depend = $i" >> .PKGINFO ;; %OPTDEPENDS%) echo "optdepend = $i" >> .PKGINFO ;; %CONFLICTS%) echo "conflict = $i" >> .PKGINFO ;; %PROVIDES%) echo "provides = $i" >> .PKGINFO ;; esac done # # Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL # chown root:root $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null chmod 644 $work_dir/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null # # Generate the package # echo Generating the package... ret=0 bsdtar -czf "$pkg_dest/$pkg_namver-$pkg_arch.tar.gz" $(ls -A) || ret=$? if [ $ret -ne 0 ]; then echo Error: unable to write package to $pkg_dest echo Maybe the disk is full or you do not have write access rm -rf $work_dir exit 1 fi rm -rf $work_dir echo Done exit 0 # vim: set ts=2 sw=2 noet:
Carlo Bersani wrote:
Il Wednesday 04 June 2008 05:55:55 Allan McRae ha scritto:
Carlo Bersani wrote:
Hello, I finally had a while to fix the permissions issue and to include fakeroot support.
Great, tested this with mlocate and the permissions get setup nicely. I did notice one regression though.
Wops, that was stupid : ) I fixed that
Great, this does everything now! I think some of the error/warning messages are a bit excessive (e.g. you don't really need to warn the user about accessing potentially sensitive information if they are root. It just come with the territory...). I will make the minor adjustments to the comments that I feel are needed and resubmit the patch for the inclusion of this script over the weekend. Many thanks for your work. I have other ideas for script for the contrib section if you want to continue contributing :) Allan
Il Thursday 05 June 2008 17:20:55 Allan McRae ha scritto:
Carlo Bersani wrote:
Il Wednesday 04 June 2008 05:55:55 Allan McRae ha scritto:
Carlo Bersani wrote:
Hello, I finally had a while to fix the permissions issue and to include fakeroot support.
Great, tested this with mlocate and the permissions get setup nicely. I did notice one regression though.
Wops, that was stupid : ) I fixed that
Great, this does everything now! I think some of the error/warning messages are a bit excessive (e.g. you don't really need to warn the user about accessing potentially sensitive information if they are root. It just come with the territory...). I will make the minor adjustments to the comments that I feel are needed and resubmit the patch for the inclusion of this script over the weekend.
Many thanks for your work. I have other ideas for script for the contrib section if you want to continue contributing :)
Allan
_______________________________________________ pacman-dev mailing list pacman-dev@archlinux.org http://archlinux.org/mailman/listinfo/pacman-dev
Il Thursday 05 June 2008 17:20:55 Allan McRae ha scritto:
Great, this does everything now! I think some of the error/warning messages are a bit excessive (e.g. you don't really need to warn the user about accessing potentially sensitive information if they are root. It just come with the territory...). I will make the minor adjustments to the comments that I feel are needed and resubmit the patch for the inclusion of this script over the weekend.
Great
Many thanks for your work. I have other ideas for script for the contrib section if you want to continue contributing :)
Feel free to make your suggestions, I'd be glad to help as long as it's fun and especially as long as it's compatible with my limited scripting knowledge. ps: sorry for the empty message: the "reply" and "send message" buttons look awfully alike in kmail.
participants (2)
-
Allan McRae
-
Carlo Bersani