Subject: Re: Unprivileged builds
To: Hubert Feyrer <hubert@feyrer.de>
From: Julio M. Merino Vidal <jmmv84@gmail.com>
List: tech-pkg
Date: 05/28/2005 22:09:54
--=-XWcq2R1G4x2KEpkeHrWr
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Sat, 2005-05-28 at 19:57 +0200, Hubert Feyrer wrote:
> > On May 28, 2005, at 1:18 PM, Julio M. Merino Vidal wrote:
> >> what about adding a PKGSRC_UNPRIVED variable to make it easy for end
> >> users to use pkgsrc without root privileges?
> ...
> >> The attached patch implements it, setting multiple variables to use the
> >> current user/group pair and disables some features that may break
> >> builds.  It also changes bootstrap to benefit from it.
> 
> Maybe see page 10 of http://www.feyrer.de/Texts/Own/21c3-pkgsrc-paper.pdf 
> (== http://www.feyrer.de/OPS/pkgsrc_env_no-root) for a few more things 
> (chmod...).

Aha!  I knew I had previously seen this somewhere.

> Personally, I'd keep this in a seperate file, i.e. in bsd.pkg.mk:
> 
>  	.if defined(PKGSRC_UNPRIVED)
>  	.include .../bsd.pkg-unprivileged.mk
>  	.endif
> 
> and then move all the things you added into that file.
> Keeps things a bit seperated.

Yeah, that's neat.  I've created a mk/unprivileged.mk file and renamed
stuff a bit (file attached).  I'm doubtful about where the main guard
should be placed.  I.e., the conditional that checks for the
UNPRIVILEGED variable... should it be in bsd.pkg.mk, preventing the
inclusion of the file, or should it stay inside the new .mk file (as it
is now)?

I've also applied Min's suggestion of setting BINMODE and NONBINMODE, as
well as the CHOWN and CHMOD you said.

BTW, I've seized the opportunity to do some more changes to the
bootstrap script.  First of all, I've added a --varbase argument to let
the user specify where var is.  Then, I've made the script choose some
reasonable defaults if the user gave --ignore-user-check (and did not
explicitly provide values for the directories).  This way, one can
easily bootstrap as in:

	$ ./bootstrap --ignore-user-check

and everything will be configured and placed inside ~/pkg.

The patch for this is attached, although it may need to be discussed
in a separate thread.

Comments?

-- 
Julio M. Merino Vidal <jmmv84@gmail.com>
http://www.livejournal.com/users/jmmv/
The NetBSD Project - http://www.NetBSD.org/

--=-XWcq2R1G4x2KEpkeHrWr
Content-Disposition: attachment; filename=patch.diff
Content-Type: text/x-patch; name=patch.diff; charset=UTF-8
Content-Transfer-Encoding: 7bit

Index: bootstrap/bootstrap
===================================================================
RCS file: /cvsroot/pkgsrc/bootstrap/bootstrap,v
retrieving revision 1.37
diff -u -r1.37 bootstrap
--- bootstrap/bootstrap	14 May 2005 02:12:48 -0000	1.37
+++ bootstrap/bootstrap	28 May 2005 20:01:47 -0000
@@ -37,10 +37,12 @@
 
 BOOTSTRAP_VERSION=20050419
 
-# set defaults for system locations
-prefix=/usr/pkg
-pkgdbdir=/var/db/pkg
-sysconfdir=${prefix}/etc
+# ensure system locations are empty; we will set them later when we know
+# whether they will be system wide or user specific
+prefix=
+pkgdbdir=
+sysconfdir=
+varbase=
 
 ignorecasecheck=no
 ignoreusercheck=no
@@ -57,6 +59,7 @@
     [ --prefix <prefix> ]
     [ --pkgdbdir <pkgdbdir> ]
     [ --sysconfdir <sysconfdir> ]
+    [ --varbase <varbase> ]
     [ --ignore-case-check ]
     [ --ignore-user-check ]
     [ --preserve-path ]
@@ -241,6 +244,7 @@
 	--pkgdbdir)	pkgdbdir="$2"; shift ;;
 	--sysconfdir=*)	sysconfdir=`echo x"$1" | sed 's,^[^=]*=,,'` ;;
 	--sysconfdir)	sysconfdir="$2"; shift ;;
+	--varbase)	varbase="$2"; shift ;;
 	--ignore-case-check) ignorecasecheck=yes ;;
 	--ignore-user-check) ignoreusercheck=yes ;;
 	--preserve-path) preserve_path=yes ;;
@@ -251,6 +255,19 @@
 	shift
 done
 
+# set defaults for system locations if not already set by the user
+if [ "$ignoreusercheck" = "yes" ]; then
+	[ -z "$prefix" ] && prefix=${HOME}/pkg
+	[ -z "$pkgdbdir" ] && pkgdbdir=${prefix}/var/db/pkg
+	[ -z "$sysconfdir" ] && sysconfdir=${prefix}/etc
+	[ -z "$varbase" ] && varbase=${prefix}/var
+else
+	[ -z "$prefix" ] && prefix=/usr/pkg
+	[ -z "$pkgdbdir" ] && pkgdbdir=/var/db/pkg
+	[ -z "$sysconfdir" ] && sysconfdir=${prefix}/etc
+	[ -z "$varbase" ] && varbase=/var
+fi
+
 if [ "x$preserve_path" != "xyes" ]; then
 	PATH="$PATH:/sbin:/usr/sbin"
 fi
@@ -535,6 +552,7 @@
 fi
 PKG_DBDIR=$pkgdbdir; export PKG_DBDIR
 LOCALBASE=$prefix; export LOCALBASE
+VARBASE=$varbase; export VARBASE
 
 # build libnbcompat
 echo_msg "Building libnbcompat"
@@ -564,9 +582,15 @@
 fi
 			
 
+# enable unprivileged builds if not root
+if [ "$ignoreusercheck" = "yes" ]; then
+	echo "UNPRIVILEGED=yes" >> ${MKCONF_EXAMPLE}
+fi
+
 # save environment in example mk.conf
 echo "PKG_DBDIR=$pkgdbdir" >> ${MKCONF_EXAMPLE}
 echo "LOCALBASE=$prefix" >> ${MKCONF_EXAMPLE}
+echo "VARBASE=$varbase" >> ${MKCONF_EXAMPLE}
 if [ "${sysconfdir}" != "${prefix}/etc" ]; then
 	echo "PKG_SYSCONFBASE=$sysconfdir" >> ${MKCONF_EXAMPLE}
 fi

--=-XWcq2R1G4x2KEpkeHrWr
Content-Disposition: attachment; filename=unprivileged.mk
Content-Type: text/plain; name=unprivileged.mk; charset=UTF-8
Content-Transfer-Encoding: 7bit

# $NetBSD$
#
# Ease configuration of unprivileged (non-root) builds.
#
# UNPRIVILEGED		If set to 'yes', enable unprivileged builds.
#			Disabled by default.
#
# UNPRIVILEGED_GROUP	Specifies the group name (or gid) that will be used
#			to install files.  Guessed if empty.
#
# UNPRIVILEGED_USER	Specifies the user name (or uid) that will be used
#			to install files.  Guessed if empty.

.if defined(UNPRIVILEGED) && !empty(UNPRIVILEGED:M[Yy][Ee][Ss])

# Guess which user/group has to be used.
.  if !defined(UNPRIVILEGED_USER) || empty(UNPRIVILEGED_USER)
UNPRIVILEGED_USER!=	${ID} -n -u
.  endif
.  if !defined(UNPRIVILEGED_GROUP) || empty(UNPRIVILEGED_GROUP)
UNPRIVILEGED_GROUP!=	${ID} -n -g
.  endif

# Override super-user account.
ROOT_GROUP=		${UNPRIVILEGED_GROUP}
ROOT_USER=		${UNPRIVILEGED_USER}

# Override user/group pairs used to install files.
BINGRP=			${UNPRIVILEGED_GROUP}
BINOWN=			${UNPRIVILEGED_USER}
GAMEGRP=		${UNPRIVILEGED_GROUP}
GAMEOWN=		${UNPRIVILEGED_USER}
MANGRP=			${UNPRIVILEGED_GROUP}
MANOWN=			${UNPRIVILEGED_USER}
SHAREGRP=		${UNPRIVILEGED_GROUP}
SHAREOWN=		${UNPRIVILEGED_USER}

# Override installation modes.  As a regular user, we may have problems
# when overwriting files if they are not writable.
BINMODE=		755
NONBINMODE=		644

# mtree is useless as a regular user because it won't set directory
# ownerships correctly.
NO_MTREE=		# defined

# As a regular user, creation of other users and groups won't work, so
# disable this step by default.
PKG_CREATE_USERGROUP?=	NO

# Override commands that won't work as a regular user.
CHGRP=			${TRUE}
CHOWN=			${TRUE}
SU_CMD=			${SH} -c

.endif

--=-XWcq2R1G4x2KEpkeHrWr--