Bug 20601

Summary: DESTDIR and /etc/shells
Product: Ports & Packages Reporter: lwa <lwa>
Component: Individual Port(s)Assignee: Ade Lovett <ade>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   

Description lwa 2000-08-14 16:50:02 UTC
	In ports shells installation, 'make install' edits 
        /etc/shells directly instead of ${DESTDIR}/etc/shells.

Fix: 

just change any occurence to /etc/shells
	by ${DESTDIR}/etc/shells in following ports :

		44bsd-csh, bash2, esh, flash, ksh93,
		pdksh, perlsh, sash, tcsh, zsh-devel
		and zsh
How-To-Repeat: 
	cd /usr/ports/shells/zsh-devel
	make install DESTDIR=/foo
Comment 1 markp freebsd_committer freebsd_triage 2001-06-07 15:47:11 UTC
State Changed
From-To: open->closed

/etc/shells is special, changing ${PREFIX}/etc/shells is invalid.
Comment 2 Peter Pentchev 2001-06-07 17:51:36 UTC
On Thu, Jun 07, 2001 at 06:32:14PM +0200, Laurent Wacrenier wrote:
> markp@FreeBSD.org wrote:
> > Synopsis: DESTDIR and /etc/shells
> > 
> > State-Changed-From-To: open->closed
> > State-Changed-By: markp
> > State-Changed-When: Thu Jun 7 07:47:11 PDT 2001
> > State-Changed-Why: 
> > /etc/shells is special, changing ${PREFIX}/etc/shells is invalid.
> > 
> > http://www.FreeBSD.org/cgi/query-pr.cgi?pr=20601
> 
> I does not understand how special it is to allow wrong informations in
> its contents.
> 
> I did not wrote about ${PREFIX} but ${DESTDIR} wich are different
> macros with different semantics. DESTDIR is, for example, a chroot
> jail or a NFS mounted system. Updating /etc/shell is an Bad Thing in
> all case when DESTDIR is defined and is not "/".
> 
> According /usr/share/mk/bsd.README :
> 
>  The variable DESTDIR works as before.  It's not set anywhere but will change
>  the tree where the file gets installed.
> 
> According /usr/src/etc/Makefile, /etc/shells is not special
> in the FreeBSD source tree :
> 
>  BIN1= ... shells ...
> 
>  distribution:
>        ...
>        ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 644 ${BIN1} ${DESTDIR}/etc;
>        ...

This is a valid complaint.  However, the problem lies much deeper -
it's not just /etc/shells.  Many things in the Ports collection
assume that ${DESTDIR} is not set, many things break if ${DESTDIR}
is set to something else.

For example, a lot of ports pass paths relative to ${PREFIX} as absolute
paths to their configure scripts and similar.  In case ${DESTDIR}
is defined, these paths would be incorrect inside a jail, because
they would contain ${DESTDIR} at the start.

A very simplistic fix for the case of shells is attached.  It's made
for the shells/bash2 port, but it could be applied (with a little tweaking)
to many other ports of shells.  This shall resolve this particular problem,
but leave the bigger one - of relative/absolute paths hardcoded in built
programs and config files and such - still open.

G'luck,
Peter

-- 
I am the meaning of this sentence.

Index: ports/shells/bash2/Makefile
===================================================================
RCS file: /home/ncvs/ports/shells/bash2/Makefile,v
retrieving revision 1.49
diff -u -r1.49 Makefile
--- ports/shells/bash2/Makefile	2001/04/10 10:47:48	1.49
+++ ports/shells/bash2/Makefile	2001/06/07 16:50:41
@@ -24,9 +24,11 @@
 MAN1=		bash.1 bashbug.1
 
 post-install:
-	${CP} /etc/shells /etc/shells.bak
-	(${GREP} -v ${PREFIX}/bin/bash /etc/shells.bak; ${ECHO} ${PREFIX}/bin/bash) >/etc/shells
-	${RM} /etc/shells.bak
+	${MKDIR} ${DESTDIR}/etc
+	${TOUCH} ${DESTDIR}/etc/shells
+	${CP} ${DESTDIR}/etc/shells ${DESTDIR}/etc/shells.bak
+	(${GREP} -v ${PREFIX:C,^${DESTDIR},,}/bin/bash ${DESTDIR}/etc/shells.bak; ${ECHO} ${PREFIX:C,^${DESTDIR},,}/bin/bash) >${DESTDIR}/etc/shells
+	${RM} ${DESTDIR}/etc/shells.bak
 .if !defined(NOPORTDOCS)
 	${MKDIR} ${PREFIX}/share/doc/bash
 	${INSTALL_MAN}  \
Comment 3 mark 2001-06-07 18:03:06 UTC
On Thu, Jun 07, 2001 at 07:51:36PM +0300, Peter Pentchev wrote:
> A very simplistic fix for the case of shells is attached.  It's made
> for the shells/bash2 port, but it could be applied (with a little tweaking)
> to many other ports of shells.  This shall resolve this particular problem,
> but leave the bigger one - of relative/absolute paths hardcoded in built
> programs and config files and such - still open.

The first problem should be documented in the Porters Handbook,
currently it doesn't mention any complications with DESTDIR. That
would help stop the problem in the future, but that still leaves a
large number of ports to check..

Perhaps introduce a "RUNTIME_PREFIX" variable which ports can use to
determine what the prefix will be at runtime?

Regards,
Mark
Comment 4 lwa 2001-06-07 18:32:18 UTC
Peter Pentchev wrote:
 
> This is a valid complaint.  However, the problem lies much deeper -
> it's not just /etc/shells.

I guess so, but I needed only this for the shells when I posted the
problem.

In most cases, the fix is simply to preprend ${DESTDIR} at the destination
of the "install", "rm", ... statements of {pre-|post-}install targets.
The main difficulty is to seek them all in the ports.

> A very simplistic fix for the case of shells is attached.  It's made
> for the shells/bash2 port, but it could be applied (with a little tweaking)

I don't fully agree with your patch :

 - ${PREFIX} does not contain ${DESTDIR}, If I install bash with DESTDIR=/mnt,
   ${PREFIX} still has its default value of /usr/local, so, you have not
   to trim /mnt from ${PREFIX} in ${DESTDIR}/etc/shells contents.

 - (minor) ${DESTDIR}/etc and ${DESTDIR}/etc/shells are expected to already
   exists if you made previously what it's explained in jail(8) manual page.
   You are expected to install ports in a functional hierarchy.
Comment 5 lwa 2001-06-07 19:00:50 UTC
Laurent Wacrenier wrote:
> 
>  - ${PREFIX} does not contain ${DESTDIR}, If I install bash with DESTDIR=/mnt,
>    ${PREFIX} still has its default value of /usr/local, so, you have not
>    to trim /mnt from ${PREFIX} in ${DESTDIR}/etc/shells contents.

Sorry, I re-checked my assertion, you'd right.
${DESTDIR} is praticaly not used in bsd.port.mk except
to be prepended to actual ${PREFIX}.

As you saifd, the problem is deeper, some ports hardcoding ${PREFIX}
in theyre binary may be wrong.
Comment 6 markp freebsd_committer freebsd_triage 2001-06-08 06:44:17 UTC
State Changed
From-To: closed->open

My mistake, this is a widespread problem
Comment 7 Peter Pentchev 2001-06-08 07:16:01 UTC
On Thu, Jun 07, 2001 at 08:00:50PM +0200, Laurent Wacrenier wrote:
> Laurent Wacrenier wrote:
> > 
> >  - ${PREFIX} does not contain ${DESTDIR}, If I install bash with DESTDIR=/mnt,
> >    ${PREFIX} still has its default value of /usr/local, so, you have not
> >    to trim /mnt from ${PREFIX} in ${DESTDIR}/etc/shells contents.
> 
> Sorry, I re-checked my assertion, you'd right.
> ${DESTDIR} is praticaly not used in bsd.port.mk except
> to be prepended to actual ${PREFIX}.
> 
> As you saifd, the problem is deeper, some ports hardcoding ${PREFIX}
> in theyre binary may be wrong.

PREFIX does not contain DESTDIR only if you build and install the port
with different environment settings, which is generally a Bad Thing (tm).

G'luck,
Peter

-- 
I've heard that this sentence is a rumor.
Comment 8 Peter Pentchev 2001-06-08 07:19:24 UTC
On Thu, Jun 07, 2001 at 07:32:18PM +0200, Laurent Wacrenier wrote:
> Peter Pentchev wrote:
>  
> > This is a valid complaint.  However, the problem lies much deeper -
> > it's not just /etc/shells.
> 
> I guess so, but I needed only this for the shells when I posted the
> problem.
> 
> In most cases, the fix is simply to preprend ${DESTDIR} at the destination
> of the "install", "rm", ... statements of {pre-|post-}install targets.
> The main difficulty is to seek them all in the ports.

Nope, not just that - ${DESTDIR} needs to also be removed from all
the argument passing where it is not needed, and this will be a hard one.
Some programs are just not built with chroot() and friends in mind,
and use the same path for both installation paths and hardwired configuration
paths :(

> > A very simplistic fix for the case of shells is attached.  It's made
> > for the shells/bash2 port, but it could be applied (with a little tweaking)
> 
> I don't fully agree with your patch :
> 
>  - ${PREFIX} does not contain ${DESTDIR}, If I install bash with DESTDIR=/mnt,
>    ${PREFIX} still has its default value of /usr/local, so, you have not
>    to trim /mnt from ${PREFIX} in ${DESTDIR}/etc/shells contents.
> 
>  - (minor) ${DESTDIR}/etc and ${DESTDIR}/etc/shells are expected to already
>    exists if you made previously what it's explained in jail(8) manual page.
>    You are expected to install ports in a functional hierarchy.

OK, I already answered the first one; and about this one, well, it never
hurts to be safe - the 'install' target in bsd.port.mk runs an mtree to
make sure that ${PREFIX} has all the needed directories, so.. :)

G'luck,
Peter

-- 
This sentence would be seven words long if it were six words shorter.
Comment 9 sada freebsd_committer freebsd_triage 2001-08-12 21:29:21 UTC
State Changed
From-To: open->analyzed

Discussed.
Comment 10 John E. Hein 2001-08-23 16:03:00 UTC
There is a proposed fix for this overall problem, but I haven't heard any
 public feedback, positive or negative, about it.  If you are interested,
 please test the patch and submit comments.

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=28155

It goes to fixing the underlying problem with the improper treatment
 of PREFIX and DESTDIR in bsd.port.mk.  A number of individual ports
 will have to be fixed as well since they depend on the broken behavior
 of bsd.port.mk.  But there are many ports already broken anyway (such
 as the ones mentioned in both this PR (20601) and the PR above (28155)).
Comment 11 Ade Lovett freebsd_committer freebsd_triage 2002-04-13 04:01:49 UTC
State Changed
From-To: analyzed->closed

This one is going nowhere fast. 


Comment 12 Ade Lovett freebsd_committer freebsd_triage 2002-04-13 04:01:49 UTC
Responsible Changed
From-To: freebsd-ports->ade

My fault[tm]