[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: