Bug#690210: debootstrap : debian-ports support
Le mercredi 18 avril à 14h 40mn 35s (+0900), Hideki Yamane a écrit :
> control: tags -1 +pending
>
> On Sat, 27 May 2017 11:27:06 +0200 jhcha54008 <jhcha54008@free.fr> wrote:
> > I am testing the updated ([1],[2]) version attached of a
> > debootstrap script to accomodate the peculiarities of non
> > released port architectures from www.debian-ports.org :
> (snip)
> > I would be thankful for feedback if someone has the opportunity
> > to test it.
>
> Adjust it to current git code, could you check it, please?
>
Hi again,
Here is a new version of the patch with a better separation of the main
code from the one to support debian-ports.
I hope it will help !
Regards,
JH Chatenet
diff -Naur debootstrap-1.0.97.orig/debian/rules debootstrap-1.0.97/debian/rules
--- debootstrap-1.0.97.orig/debian/rules 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/debian/rules 2018-04-28 11:55:40.107863387 +0200
@@ -37,6 +37,7 @@
debian/debootstrap-udeb/usr/share/debootstrap/scripts/stable \
debian/debootstrap-udeb/usr/share/debootstrap/scripts/testing \
debian/debootstrap-udeb/usr/share/debootstrap/scripts/unstable
+ -rm -f debian/debootstrap-udeb/usr/share/debootstrap/sort_pkgs_perl
override_dh_gencontrol:
dh_gencontrol -- -Vkeyring=$(KEYRING)
diff -Naur debootstrap-1.0.97.orig/debootstrap debootstrap-1.0.97/debootstrap
--- debootstrap-1.0.97.orig/debootstrap 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/debootstrap 2018-04-28 11:55:40.211863902 +0200
@@ -46,6 +46,7 @@
CHECKCERTIF=""
PRIVATEKEY=""
CACHE_DIR=""
+PORT=""
DEF_MIRROR="http://deb.debian.org/debian"
DEF_HTTPS_MIRROR="https://deb.debian.org/debian"
@@ -124,6 +125,7 @@
--private-key=file read the private key from file
--certificate=file use the client certificate stored in file (PEM)
--no-check-certificate do not check certificate against certificate authorities
+ --debian-ports set up defaults for a port architecture (see www.ports.debian.org)
EOF
}
@@ -384,6 +386,10 @@
CHECKCERTIF="--no-check-certificate"
shift
;;
+ --debian-ports)
+ PORT=yes
+ shift
+ ;;
-*)
error 1 BADARG "unrecognized or invalid option %s" "$1"
;;
@@ -428,6 +434,9 @@
TARGET=$CHROOTDIR
fi
SCRIPT=$DEBOOTSTRAP_DIR/suite-script
+ if [ -e "$DEBOOTSTRAP_DIR/functions_for_debian_ports" ]; then
+ PORT=yes
+ fi
else
if [ -z "$1" ] || [ -z "$2" ]; then
usage_err 1 NEEDSUITETARGET "You must specify a suite and a target."
@@ -613,6 +622,10 @@
###########################################################################
+if [ -n "$PORT" ]; then
+ . "$DEBOOTSTRAP_DIR/functions_for_debian_ports"
+fi
+
. "$SCRIPT"
if [ "$SECOND_STAGE_ONLY" = "true" ]; then
@@ -716,6 +729,8 @@
echo "$base" >"$TARGET/debootstrap/base"
chmod 755 "$TARGET/debootstrap/debootstrap"
+ [ "" = "$PORT" ] || \
+ cp "$DEBOOTSTRAP_DIR/functions_for_debian_ports" "$TARGET/debootstrap/"
fi
fi
diff -Naur debootstrap-1.0.97.orig/debootstrap.8 debootstrap-1.0.97/debootstrap.8
--- debootstrap-1.0.97.orig/debootstrap.8 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/debootstrap.8 2018-04-28 11:55:40.243864061 +0200
@@ -165,6 +165,10 @@
.IP
.IP "\fB\-\-private\-key=FILE\fP"
Read the private key from file
+.IP
+.IP "\fB\-\-debian\-ports=FILE\fP"
+Tweaking for port architectures (see www.ports.debian.org) when downloading
+from a ftp.ports.debian.org mirror.
.SH EXAMPLES
.
diff -Naur debootstrap-1.0.97.orig/functions debootstrap-1.0.97/functions
--- debootstrap-1.0.97.orig/functions 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/functions 2018-04-28 11:55:40.479865231 +0200
@@ -1801,3 +1801,8 @@
fakechroot" >> "$TARGET/var/lib/dpkg/diversions"
}
+
+############################################################## debian-ports support
+packages_merge_in_work_out_debs () {
+:
+}
diff -Naur debootstrap-1.0.97.orig/functions_for_debian_ports debootstrap-1.0.97/functions_for_debian_ports
--- debootstrap-1.0.97.orig/functions_for_debian_ports 1970-01-01 01:00:00.000000000 +0100
+++ debootstrap-1.0.97/functions_for_debian_ports 2018-04-28 12:05:10.262690632 +0200
@@ -0,0 +1,113 @@
+download_indices () {
+ mk_download_dirs
+ "$DOWNLOAD_INDICES" "$(echo "$@" | tr ' ' '\n' | sort)"
+ # debian-ports also needs "unreleased" architecture
+ local mem_SUITE
+ mem_SUITE="$SUITE"
+ SUITE="unreleased" "$DOWNLOAD_INDICES" $(echo "$@" | tr ' ' '\n' | sort)
+ SUITE="$mem_SUITE"
+}
+
+merge_packages_files () {
+ local TEMP_COMPONENTS m c c1 path pkgdest path1 pkgdest1
+
+ COMPONENTS_WITHOUT_UNRELEASED=$(echo $COMPONENTS|tr ' ' '\n'|sort|uniq|tr '\n' ' ')
+ TEMP_COMPONENTS="$COMPONENTS_WITHOUT_UNRELEASED"
+
+ for m in $MIRRORS; do
+ for c in $COMPONENTS_WITHOUT_UNRELEASED; do
+ path="dists/unreleased/$c/binary-$ARCH/Packages"
+ pkgdest="$TARGET/$($DLDEST pkg "unreleased" "$c" "$ARCH" "$m" "$path")"
+ path1="dists/$SUITE/$c/binary-$ARCH/Packages"
+ pkgdest1="$TARGET/$($DLDEST pkg "$SUITE" "$c" "$ARCH" "$m" "$path1")"
+
+ cat "$pkgdest1" "$pkgdest" > "${pkgdest1}.concatenate"
+ "$SORT_PKGS" "${pkgdest1}.concatenate" > "${pkgdest1}.merged"
+ if [ -s "${pkgdest1}.merged" ] ; then
+ if [ -n "$DEBOOTSTRAP_MERGE_KEEP_ORIGINAL" ] ; then
+ mv "$pkgdest1" "${pkgdest1}.original"
+ fi
+ mv "${pkgdest1}.merged" "$pkgdest1"; rm -f "${pkgdest1}.concatenate"
+ fi
+ done
+ done
+
+ TEMP_COMPONENTS="$(echo $TEMP_COMPONENTS|tr ' ' '\n'|sort|uniq|tr '\n' ' ')"
+ if [ "$TEMP_COMPONENTS" != "$COMPONENTS_WITHOUT_UNRELEASED" ] ; then
+ COMPONENTS="$TEMP_COMPONENTS"
+ fi
+}
+
+setup_apt_sources () {
+ mkdir -p "$TARGET/etc/apt"
+ for m in "$@"; do
+ local cs cs1 c path path1 pkgdest pkgdest1
+ for c in ${COMPONENTS_WITHOUT_UNRELEASED:-$USE_COMPONENTS}; do
+ path="dists/$SUITE/$c/binary-$ARCH/Packages"
+ pkgdest="$TARGET/$($DLDEST pkg "$SUITE" "$c" "$ARCH" "$m" "$path")"
+ if [ -e "$pkgdest" ]; then cs="$cs $c"; fi
+ # for "unreleased" archive (debian-ports)
+ path1="dists/unreleased/$c/binary-$ARCH/Packages"
+ pkgdest1="$TARGET/$($DLDEST pkg unreleased "$c" "$ARCH" "$m" "$path1")"
+ if [ -e "$pkgdest1" ]; then cs1="$cs1 $c"; fi
+ done
+ if [ "$cs" != "" ]; then echo "deb $m $SUITE$cs"; fi
+ if [ "$cs1" != "" ]; then echo "deb $m unreleased${cs1}"; fi
+ done > "$TARGET/etc/apt/sources.list"
+}
+
+packages_merge_in_work_out_debs () {
+ if [ -z "$SORT_PKGS" ]; then
+ error 1 NO_SORTCMD "No sort_pkgs is available; either install perl, or build sort_pkgs.c from source"
+ fi
+ merge_packages_files
+}
+
+################################################################# sort_pkgs
+
+# unstable and unreleased are merged and sorted by SORT_PKGS. An alternative
+# sort program can be given in the environment variable DEBOOTSTRAP_SORT_PKGS
+# If no perl interpreter is available, a minimal C implementation of sort_pkgs
+# should be provided.
+
+if [ -n "$DEBOOTSTRAP_SORT_PKGS" ] ; then
+ if command -v "$DEBOOTSTRAP_SORT_PKGS" >/dev/null 2>&1; then
+ SORT_PKGS="$DEBOOTSTRAP_SORT_PKGS"
+ else
+ error 1 SORTCMDUNVL "%s is not available on the system" "$DEBOOTSTRAP_SORT_PKGS"
+ fi
+elif in_path perl && [ -e "$DEBOOTSTRAP_DIR/sort_pkgs_perl" ]; then
+ . "$DEBOOTSTRAP_DIR/sort_pkgs_perl"
+elif [ -e /usr/lib/debootstrap/di_sort_pkgs ]; then
+ # There is no perl available in debian-installer.
+ # A binary implementation of sort_pkgs should be provided by
+ # another udeb package under /usr/lib/debootstrap/di_sort_pkgs
+ SORT_PKGS=/usr/lib/debootstrap/di_sort_pkgs
+elif [ -e "$DEBOOTSTRAP_DIR/sort_pkgs" ]; then
+ SORT_PKGS="$DEBOOTSTRAP_DIR/sort_pkgs"
+else
+ SORT_PKGS=""
+fi
+
+############################################################### debian-ports specific
+
+# debian-ports is only for unstable(sid) suite
+if [ ! "$SUITE" = unstable ] && [ ! "$SUITE" = sid ]; then
+ error 1 ONLYUNSTABLE "debian-ports only provides unstable suite. Aborting..."
+fi
+
+# use the debian-ports keyring if debian-ports-archive-keyring installed
+keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg
+# or the one installed
+keyring /etc/apt/trusted.gpg
+
+# Install debian-ports-archive-keyring (priority: optional) along with
+# the important packages on the target if you try to install debian-ports
+if [ -z "$ADDITIONAL" ]; then
+ ADDITIONAL="debian-ports-archive-keyring"
+elif $(echo "$ADDITIONAL" | grep -qvF 'debian-ports-archive-keyring'); then
+ ADDITIONAL="${ADDITIONAL} debian-ports-archive-keyring"
+fi
+
+default_mirror http://deb.debian.org/debian-ports
+
diff -Naur debootstrap-1.0.97.orig/Makefile debootstrap-1.0.97/Makefile
--- debootstrap-1.0.97.orig/Makefile 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/Makefile 2018-04-28 11:55:40.487865271 +0200
@@ -12,6 +12,8 @@
cp -a scripts/* $(DSDIR)/scripts/
install -o root -g root -m 0644 functions $(DSDIR)/
+ install -o root -g root -m 0644 sort_pkgs_perl $(DSDIR)/
+ install -o root -g root -m 0644 functions_for_debian_ports $(DSDIR)/
sed 's/@VERSION@/$(VERSION)/g' debootstrap >$(DESTDIR)/usr/sbin/debootstrap
chown root:root $(DESTDIR)/usr/sbin/debootstrap
diff -Naur debootstrap-1.0.97.orig/scripts/debian-common debootstrap-1.0.97/scripts/debian-common
--- debootstrap-1.0.97.orig/scripts/debian-common 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/scripts/debian-common 2018-04-28 11:55:40.495865311 +0200
@@ -10,12 +10,18 @@
esac
work_out_debs () {
- required="$(get_debs Priority: required)"
+
+ # merge Packages files from unstable and unreleased if needed
+ packages_merge_in_work_out_debs
+
+ # Duplicate package names (possibly from different versions) are causing errors.
+ required="$(get_debs Priority: required|tr ' ' '\n'|sort|uniq|tr '\n' ' ')"
if doing_variant - || doing_variant fakechroot; then
#required="$required $(get_debs Priority: important)"
# ^^ should be getting debconf here somehow maybe
- base="$(get_debs Priority: important)"
+ # Duplicate package names (possibly from different versions) are causing errors.
+ base="$(get_debs Priority: important|tr ' ' '\n'|sort|uniq|tr '\n' ' ')"
elif doing_variant buildd; then
base="apt build-essential"
elif doing_variant minbase; then
@@ -32,6 +38,11 @@
base="$base apt-transport-https ca-certificates"
;;
esac
+
+ # Duplicate package names (in required and in base) are causing errors.
+ if [ "$RESOLVE_DEPS" != true ]; then
+ base=$(without "$base" "$required")
+ fi
}
first_stage_install () {
diff -Naur debootstrap-1.0.97.orig/scripts/sid debootstrap-1.0.97/scripts/sid
--- debootstrap-1.0.97.orig/scripts/sid 2018-04-17 04:06:32.000000000 +0200
+++ debootstrap-1.0.97/scripts/sid 2018-04-28 12:05:57.950927105 +0200
@@ -4,6 +4,34 @@
variants - buildd fakechroot minbase
keyring /usr/share/keyrings/debian-archive-keyring.gpg
+# Check for debian-ports and print a warning if needed
+if [ -z "$PORT" ] && [ ! "$SECOND_STAGE_ONLY" = true ]; then
+ # If PORT is set, the user took the responsability ...
+ if [ -z "$USER_MIRROR" ] || [ ! "$USER_MIRROR" = "${USER_MIRROR#http://}" ] || \
+ [ ! "$USER_MIRROR" = "${USER_MIRROR#https://}" ]; then
+ # The option '--debian-ports' is useful if we download from a debian-ports mirror
+ # it shouldn't be set if we install from a CD, or from a regular debian mirror
+ if [ -n "$PORTS_ARCH" ]; then
+ PORTS_ARCH_LIST="$PORTS_ARCH"
+ else
+ # As of 2018/04/18
+ PORTS_ARCH_LIST="alpha hppa hurd-i386 m68k powerpcspe ppc64 riscv64 sh4 sparc64 x32"
+ fi
+
+ for port_name in $PORTS_ARCH_LIST
+ do
+ if [ "$port_name" = "$ARCH" ]; then
+ if [ -z "$PORTS_ARCH" ]; then
+ info ISPORTARCH1 "As of 2018/04/18 :"
+ fi
+ info ISPORTARCH2 "the selected architecture '%s' is hosted at ftp.ports.debian.org. You may find the option --debian-ports useful" "$ARCH"
+ break
+ fi
+ done
+ fi
+fi
+
+
# include common settings
if [ -d /usr/share/debootstrap/scripts ]; then
. /usr/share/debootstrap/scripts/debian-common
diff -Naur debootstrap-1.0.97.orig/sort_pkgs_perl debootstrap-1.0.97/sort_pkgs_perl
--- debootstrap-1.0.97.orig/sort_pkgs_perl 1970-01-01 01:00:00.000000000 +0100
+++ debootstrap-1.0.97/sort_pkgs_perl 2018-04-28 11:55:40.511865390 +0200
@@ -0,0 +1,186 @@
+#
+# Here is a debootstrap helper to sort Packages files by ascending version number.
+#
+# This file re-use functions 'pkg_name_is_illegal', 'version_check', 'version_order',
+# 'version_compare_string', 'version_split_digits' and 'version_compare_part' from
+# debian package 'libdpkg-perl' (see the copyright file therein for attribution).
+#
+
+ SORT_PKGS=sort_pkgs_perl
+
+ sort_pkgs_perl () {
+ perl -e '
+defined($ARGV[0]) or die("no file argument");
+
+open PACKAGES,$ARGV[0]
+ or die("open : $!");
+
+# adapted from Dpkg::Package and Dpkg::Version
+sub pkg_name_is_illegal($) {
+ my $name = shift || "";
+
+ $name eq "" &&
+ return "may not be empty string";
+ $name =~ m/[^-+.0-9a-z]/o &&
+ return sprintf("character %s not allowed", $&);
+ $name =~ m/^[0-9a-z]/o ||
+ return "must start with an alphanumeric character";
+ return;
+}
+
+sub version_split($) {
+ my $ver = shift;
+ my ($epoch,$version,$revision);
+
+ if ($ver =~ /^([^:]*):(.+)$/) {
+ $epoch = $1;
+ $ver = $2;
+ } else {
+ $epoch = 0;
+ }
+
+ if ($ver =~ /(.*)-(.*)$/) {
+ $version = $1;
+ $revision = $2;
+ } else {
+ $version = $ver;
+ $revision = 0;
+ }
+
+ return ($epoch, $version, $revision);
+}
+
+sub version_check($$$$) {
+ my ($str, $epoch, $version, $revision) = @_;
+
+# version number cannot be empty
+ if (not defined($str) or not length($str)) {
+ return 0;
+ }
+# version number does not start with digit
+ if ($version =~ m/^[^\d]/) {
+ return 0;
+ }
+# version number contains illegal character
+ if ($str =~ m/([^-+:.0-9a-zA-Z~])/o) {
+ return 0;
+ }
+# epoch part of the version number is not a number
+ if ($epoch !~ /^\d*$/) {
+ return 0;
+ }
+
+# version number is valid
+ return 1;
+}
+
+sub _version_order {
+ my ($x) = @_;
+
+ if ($x eq "~") {
+ return -1;
+ } elsif ($x =~ /^\d$/) {
+ return $x * 1 + 1;
+ } elsif ($x =~ /^[A-Za-z]$/) {
+ return ord($x);
+ } else {
+ return ord($x) + 256;
+ }
+}
+
+sub version_compare_string($$) {
+ my @a = map { _version_order($_) } split(//, shift);
+ my @b = map { _version_order($_) } split(//, shift);
+ while (1) {
+ my ($a, $b) = (shift @a, shift @b);
+ return 0 if not defined($a) and not defined($b);
+ $a ||= 0; # Default order for "no character"
+ $b ||= 0;
+ return 1 if $a > $b;
+ return -1 if $a < $b;
+ }
+}
+
+sub version_split_digits($) {
+ return split(/(?<=\d)(?=\D)|(?<=\D)(?=\d)/, $_[0]);
+}
+
+sub version_compare_part($$) {
+ my @a = version_split_digits(shift);
+ my @b = version_split_digits(shift);
+ while (1) {
+ my ($a, $b) = (shift @a, shift @b);
+ return 0 if not defined($a) and not defined($b);
+ $a ||= 0; # Default value for lack of version
+ $b ||= 0;
+ if ($a =~ /^\d+$/ and $b =~ /^\d+$/) {
+ # Numerical comparison
+ my $cmp = $a <=> $b;
+ return $cmp if $cmp;
+ } else {
+ # String comparison
+ my $cmp = version_compare_string($a, $b );
+ return $cmp if $cmp;
+ }
+ }
+}
+
+# order package names as apt-sortpkgs would
+
+sub compare_pkgname($$) {
+ my ( $a,$b ) = @_;
+
+ if ((length($a) < length($b)) &&
+ substr($b,0,length($a)) eq $a) {
+ return +1;
+ } elsif ((length($a) > length($b)) &&
+ substr($a,0,length($b)) eq $b) {
+ return -1;
+ } else {
+ return $a cmp $b;
+ }
+}
+
+my $stanza_begin = 0;
+my @pkg_list = ();
+my ($f, $v, $pkg, $ver, $stanza_end);
+my ($version_is_valid, $ver_epoch, $ver_ver, $ver_rev);
+while(<PACKAGES>) {
+ chomp;
+ next if (/^ /);
+ if (/^([^:]*:)\s*(.*)$/) {
+ $f = lc($1); $v = $2;
+ $pkg = $v if ($f eq "package:");
+ $ver = $v if ($f eq "version:");
+ } elsif (/^$/) {
+ $stanza_end = tell();
+ ($ver_epoch, $ver_ver, $ver_rev) = version_split($ver);
+ $version_is_valid
+ = version_check($ver,$ver_epoch,$ver_ver,$ver_rev);
+ if ($version_is_valid && (! pkg_name_is_illegal($pkg))) {
+ push @pkg_list,[$pkg,$stanza_begin,$stanza_end,
+ $ver_epoch,$ver_ver,$ver_rev];
+ }
+ $stanza_begin = $stanza_end;
+ }
+}
+
+@pkg_list = sort({compare_pkgname($a->[0],$b->[0]) or
+ $a->[3] <=> $b->[3] or
+ version_compare_part($a->[4],$b->[4]) or
+ version_compare_part($a->[5],$b->[5]) or
+ $a->[1] <=> $b->[1]} @pkg_list);
+
+my $pkg_elt;
+foreach $pkg_elt (@pkg_list) {
+ seek(PACKAGES,$pkg_elt->[1],0);
+ while(<PACKAGES>) {
+ print $_;
+ last if tell() >= $pkg_elt->[2];
+ }
+}
+close(PACKAGES);
+' "$@"
+}
+
+
Reply to: