Thu, 24 Dec 2009

CFT: Sudo Update

If you use Sudo on FreeBSD and want to test out an update for it please apply the patch from here and rebuild/reinstall the port. I'm especially interested in environments using ldap, kerberos and newer releases of FreeBSD (specifically 8.0). I'll take reports of success or failure for anything though. Since this is such a heavily used port I want to make sure I get it correct and cause as little headache for myself and others as possible.

posted at: 14:02 | tags: , , | path: /entries/freebsd | permanent link to this entry

Tue, 16 Jun 2009

Package List (plist) Details

For the most part plists (in FreeBSD ports) are simply a listing of files installed by the port relative to ${PREFIX}. The contents of the plist get put into the +CONTENTS file in the package. Failure to get the plist correct in the port causes the package and the port to not properly clean up after itself, which leads to stray files on your machine. Not only is it a tidy problem it can potentially cause problems later on down the road. It's not hard to imagine a scenario where a binary is left laying around with a vulnerability in it. It is important to get plists correct to ensure a happy user experience.

Probably the most common thing you will see done in plists besides listing files is handling configuration files during (de)installation. This is well documented in the handbook (and don't forget to put the corresponding part in the Makefile as the plist is not processed when using the port). You can actually do a lot more with the plist if you need to, though it is not often the case.

I've had a few people ask me recently how plists work so I thought I would document what I consider to be a good resource regarding plists. When in doubt I always take a look at pkg_create(1) - specifically the PACKING LIST DETAILS section. If you're working on a port and get yourself confused when dealing with the plist I would look through that and it will most likely clear up any issue you have.

posted at: 17:10 | tags: , | path: /entries/freebsd | permanent link to this entry

Tue, 20 Jan 2009

Mono Framework 2.0 on FreeBSD

I've taken the good work done by the BSD# folks and have prepared it for integration into the FreeBSD ports tree. I'm awaiting final approval from them to put it through an -exp run on the cluster. If all goes well with the -exp run I'll be able to commit it into the tree shortly after. I don't know when it will happen yet but it's becoming closer with each passing day.

The effort consists of one huge patch and 3 new ports. The patch is at mono.diff along with webkit-sharp.shar, gnome-desktop-sharp20.shar and gmime2-sharp20.shar. Feel free to send me a mail if you notice anything wrong with them.

posted at: 15:52 | tags: , | path: /entries/freebsd | permanent link to this entry

Tue, 02 Sep 2008

Bug Found and Fixed in fastest_sites.

There was a bug in fastest_sites which I just committed a fix for. The idea for the fix came from Ryan Steinmetz, though the patch has a couple smaller additions by me to make it slightly more friendly.

The bug is because there are things like this in Mk/bsd.sites.mk:

.if !defined(IGNORE_MASTER_SITE_DEBIAN_POOL)
MASTER_SITE_DEBIAN_POOL+=       \
	${MASTER_SITE_DEBIAN:C|(/%SUBDIR%/)|/pool/main/${PORTNAME:C/^(.).*$/\1/}/${PORTNAME}/|}
.endif

...

.if !defined(IGNORE_MASTER_SITE_GOOGLE_CODE)
.if defined(PROJECTHOST)
MASTER_SITE_GOOGLE_CODE+= \
	http://${PROJECTHOST}.googlecode.com/files/
.else
MASTER_SITE_GOOGLE_CODE+= \
	http://${PORTNAME}.googlecode.com/files/
.endif
.endif

The way fastest_sites works is by doing 'make -V MASTER_SITE_FOO -f $PORTSDIR/Mk/bsd.sites.mk' for every MASTER_SITE definition in the file. It then splits the result and makes the connections to everything (not technically true, it only does the first 10 which respond) in the list in order to get the RTT estimate for a TCP handshake. The problem is that ${PORTNAME} is not defined resulting in:

wxs@ack ~ % make -V MASTER_SITE_GOOGLE_CODE -V MASTER_SITE_DEBIAN_POOL -f /usr/ports/Mk/bsd.sites.mk
http://.googlecode.com/files/
http://www.gtlib.cc.gatech.edu/pub/debian/pool/main/// ftp://ftp.us.debian.org/debian/pool/main/// ftp://ftp.au.debian.org/debian/pool/main/// ftp://ftp.bg.debian.org/debian/pool/main/// ftp://ftp.cl.debian.org/debian/pool/main/// ftp://ftp.cz.debian.org/debian/pool/main/// ftp://ftp.de.debian.org/debian/pool/main/// ftp://ftp.ee.debian.org/debian/pool/main/// ftp://ftp.es.debian.org/debian/pool/main/// ftp://ftp.fi.debian.org/debian/pool/main/// ftp://ftp.fr.debian.org/debian/pool/main/// ftp://ftp.hk.debian.org/debian/pool/main/// ftp://ftp.hr.debian.org/debian/pool/main/// ftp://ftp.hu.debian.org/debian/pool/main/// ftp://ftp.ie.debian.org/debian/pool/main/// ftp://ftp.is.debian.org/debian/pool/main/// ftp://ftp.it.debian.org/debian/pool/main/// ftp://ftp.jp.debian.org/debian/pool/main/// http://ring.nict.go.jp/archives/linux/debian/debian/pool/main/// http://ring.sakura.ad.jp/archives/linux/debian/debian/pool/main/// http://ring.riken.jp/archives/linux/debian/debian/pool/main/// ftp://ftp.nl.debian.org/debian/pool/main/// ftp://ftp.no.debian.org/debian/pool/main/// ftp://ftp.pl.debian.org/debian/pool/main/// ftp://ftp.ru.debian.org/debian/pool/main/// ftp://ftp.se.debian.org/debian/pool/main/// ftp://ftp.si.debian.org/debian/pool/main/// ftp://ftp.sk.debian.org/debian/pool/main/// ftp://ftp.uk.debian.org/debian/pool/main/// ftp://ftp.wa.au.debian.org/debian/pool/main/// ftp://ftp2.de.debian.org/debian/pool/main///
wxs@ack ~ % 

The results are obviously bad: http://.googlecode.com is not legal, and while the seecond result is a legal URL it is not correct in the context of ports - it's missing the piece about the PORTNAME.

The patch looks for results that contain '//.', '[a-zA-Z]//' or '..' as those are the common cases. Technically the '..' case doesn't exist yet but it's not a far stretch to see a MASTER_SITE_FOO definition that uses http://www.${PORTNAME}.mirror-network.com in the future. We might as well catch that case now.

I committed the patch tonight, thanks again Ryan, and notified Jordan (he's the author of fastest_sites) about some other minor issues with it. I'd fix them myself but my python-fu is very weak and I just don't have the time since I'm moving in a week. Hopefully Jordan will get around to it once he's back from his honeymoon.

posted at: 22:46 | tags: , , | path: /entries/freebsd | permanent link to this entry

Thu, 07 Aug 2008

Stupid make.conf Tricks.

No, I'm not dead. I was on vacation last week for my honeymoon and a friends wedding in Hawaii. I'm back now and trying to get my life back on track, but I'm not sure how well that will work since I'm moving to North Carolina in a month or so. I figured I would get back into the swing of things by posting a question I was recently asked and then give you my solution to it. It's a simple one to start things off again.

I was asked how you would go about removing a specific CFLAGS setting for a specific port. This is slightly different from the more common case: setting specific CFLAGS. The more common case is solved with:

.if ${.CURDIR:M*/foo/bar}
CFLAGS=baz
.endif

That is only one way to do it. There are others including things like portconf. The answer to the question I was asked is:

wxs@ack /usr/ports/devel/git % cat /etc/make.conf
x="foo bar baz"
.if ${.CURDIR:M*/devel/git}
x:=${x:C/bar //}
.endif
wxs@ack /usr/ports/devel/git % make -V x
"foo baz"
wxs@ack /usr/ports/devel/git %

I also have another answer, which I think is a cleaner solution (it's not the same as the one above but it illustrates the point):

wxs@ack ~ % cat Makefile
a=foo bar baz

all:
	@echo ${a:Nbar}
wxs@ack ~ % make
foo baz
wxs@ack ~ %

posted at: 21:02 | tags: , | path: /entries/geek | permanent link to this entry

Fri, 13 Jun 2008

Flying Solo

garga       2008-06-13 17:57:54 UTC

  FreeBSD ports repository

  Modified files:
    .                    access
  Log:
  Forced commit to note wxs@ is free from mentorship, hs is ready to fly solo.

  Revision  Changes    Path
  1.833     +0 -0      CVSROOT/access

posted at: 18:45 | tags: , | path: /entries/freebsd | permanent link to this entry

Mon, 28 Apr 2008

Extending the OPTIONS Framework - Part 3.

I'll save the boring details but I've cleaned up the first patch in this series (the one that extends the OPTIONS to a 4th field and requires OPTIONS_DESC). This new method means that there is always the '?' or F1 keys available, since if OPTIONS_DESC is not set it uses a default message (like in the second patch). If you want to see the current versions they will be available here at least until something happens with the PR (committed or stalled long enough for the patches to become stale).

I submitted both in a PR tonight. Now it's up to the powers that be to determine which solution they like best, and for me to adjust the patches as necessary to suit their concerns (if there are any).

Oh, I also finally got around to submitting my show-all-pkg-messages patch that I've been sitting on for a few months now. I had some initial reports from some friends that it worked on more ports than I tested with.

posted at: 22:57 | tags: , | path: /entries/freebsd | permanent link to this entry

Fri, 25 Apr 2008

Extending the OPTIONS Framework - Part 2.

This is part 2 (part 1) of my venture into extending the OPTIONS framework to be a little more user friendly. For background read part 1, otherwise this won't make much sense.

With this approach the maintainer must declare DESC_FOO for every option. Failure to do so results in a default message being put in place. The upside of this approach is that the help screen becomes the default on every port, regardless of if they have long descriptions or not. The downside of this approach is that I must call make(1) for every OPTION, which is not very efficient - I've tried to figure out a way around it but couldn't. I tend to think my first approach is cleaner on the maintainer, at the expense of more complication in bsd.port.mk. Also, with the first approach there is a higher chance of the longer descriptions being the default (ie: not having them results in a failure to parse them).

Here's the patch - I'll probably send-pr it tonight or tomorrow:

Index: bsd.port.mk
===================================================================
RCS file: /home/ncvs/ports/Mk/bsd.port.mk,v
retrieving revision 1.592
diff -u -u -r1.592 bsd.port.mk
--- bsd.port.mk 14 Apr 2008 16:46:41 -0000  1.592
+++ bsd.port.mk 25 Apr 2008 23:01:35 -0000
@@ -1234,6 +1234,7 @@
 .else
 UNIQUENAME?=   ${PKGNAMEPREFIX}${PORTNAME}
 .endif
+OPTIONSDESCFILE?=  ${PORT_DBDIR}/${UNIQUENAME}/options.descr
 OPTIONSFILE?=  ${PORT_DBDIR}/${UNIQUENAME}/options
 _OPTIONSFILE!= ${ECHO_CMD} "${OPTIONSFILE}"
 .if defined(OPTIONS)
@@ -5783,6 +5784,7 @@
        . ${_OPTIONSFILE}; \
    fi; \
    set -- ${OPTIONS} XXX; \
+   TMPOPTIONSDESCFILE=$$(mktemp -t portoptionsdescr); \
    while [ $$# -gt 3 ]; do \
        OPTIONSLIST="$${OPTIONSLIST} $$1"; \
        defaultval=$$3; \
@@ -5798,14 +5800,21 @@
            val=$$3; \
        fi; \
        DEFOPTIONS="$${DEFOPTIONS} $$1 \"$$2\" $${val}"; \
+       LONGDESC=$$(cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} -V DESC_$$1); \
+       if [ "x$${LONGDESC}" = "x" ]; then \
+           ${ECHO_CMD} "$$1: No long description specified.  Contact the maintainer to fix this." | fmt >> $${TMPOPTIONSDESCFILE}; \
+       else \
+           ${ECHO_CMD} $$1: $${LONGDESC} | fmt >> $${TMPOPTIONSDESCFILE}; \
+       fi; \
        shift 3; \
    done; \
    TMPOPTIONSFILE=$$(mktemp -t portoptions); \
    trap "${RM} -f $${TMPOPTIONSFILE}; exit 1" 1 2 3 5 10 13 15; \
-   ${SH} -c "${DIALOG} --checklist \"Options for ${PKGNAME:C/-([^-]+)$/ \1/}\" 21 70 15 $${DEFOPTIONS} 2> $${TMPOPTIONSFILE}"; \
+   ${SH} -c "${DIALOG} --hfile $${TMPOPTIONSDESCFILE} --hline \"Press ? for a detailed description\" --checklist \"Options for ${PKGNAME:C/-([^-]+)$/ \1/}\" 21 70 15 $${DEFOPTIONS} 2> $${TMPOPTIONSFILE}"; \
    status=$$?; \
    if [ $${status} -ne 0 ] ; then \
        ${RM} -f $${TMPOPTIONSFILE}; \
+       ${RM} -f $${TMPOPTIONSDESCFILE}; \
        ${ECHO_MSG} "===> Options unchanged"; \
        exit 0; \
    fi; \
@@ -5832,11 +5841,14 @@
    if [ `${ID} -u` != 0 -a "x${INSTALL_AS_USER}" = "x" ]; then \
        ${ECHO_MSG} "===>  Switching to root credentials to write ${_OPTIONSFILE}"; \
        ${SU_CMD} "${CAT} $${TMPOPTIONSFILE} > ${_OPTIONSFILE}"; \
+       ${SU_CMD} "${CAT} $${TMPOPTIONSDESCFILE} > ${OPTIONSDESCFILE}"; \
        ${ECHO_MSG} "===>  Returning to user credentials"; \
    else \
        ${CAT} $${TMPOPTIONSFILE} > ${_OPTIONSFILE}; \
+       ${CAT} $${TMPOPTIONSDESCFILE} > ${OPTIONSDESCFILE}; \
    fi; \
-   ${RM} -f $${TMPOPTIONSFILE}
+   ${RM} -f $${TMPOPTIONSFILE}; \
+   ${RM} -f $${TMPOPTIONSDESCFILE}
 .endif
 .endif

@@ -5916,11 +5928,12 @@
    optionsdir=${_OPTIONSFILE}; optionsdir=$${optionsdir%/*}; \
    if [ `${ID} -u` != 0 -a "x${INSTALL_AS_USER}" = "x" ]; then \
        ${ECHO_MSG} "===> Switching to root credentials to remove ${_OPTIONSFILE} and $${optionsdir}"; \
-       ${SU_CMD} "${RM} -f ${_OPTIONSFILE} ; \
+       ${SU_CMD} "${RM} -f ${_OPTIONSFILE} ${OPTIONSDESCFILE}; \
            ${RMDIR} $${optionsdir}"; \
        ${ECHO_MSG} "===> Returning to user credentials"; \
    else \
        ${RM} -f ${_OPTIONSFILE}; \
+       ${RM} -f ${OPTIONSDESCFILE}; \
        ${RMDIR} $${optionsdir}; \
    fi
 .else

posted at: 19:05 | tags: , | path: /entries/freebsd | permanent link to this entry

Wed, 02 Apr 2008

Extending the OPTIONS Framework - Part 1.

This will be at least a two part post, possibly more depending upon where this takes me. I spent some time at night late last week working on extending the OPTIONS framework in ports. It started with this thread on ports@ and continued into April (same thread). The idea is to extend the OPTIONS framework used in ports from the 3 field way it is currently to an optional 4th field which would contain a much more detailed description of what the option means - possibly including listing dependencies it will pull in. Ports that choose to use this 4th field will automatically allow the user to hit '?' or F1 on the dialog(1) screen used to select the OPTIONS, which will bring up the detailed descriptions in a separate window.

My initial thoughts last week were to use a variable called DESC_foo to store the long description (where "foo" is the name of the OPTION). The upside of this is that I just have to look for DESC_foo and display it somehow. The downside is that it's not intuitive, given how the OPTIONS framework works currently. It just seems like a nicer solution to inline the long descriptions, rather than declare them separately. I thought about it some more and decided that Pav's approach - putting the descriptions inline - is nicer, though probably a bit more complicated to implement. So I whipped up an initial draft late Wednesday or Thursday night and decided to let it rest while I took a mini-vacation to North Carolina to speak at a conference (more on that later).

While at the conference I thought some more about it and came up with a fairly clean solution and implemented it when I returned. I like it and it seems to work for the one or two ports I've tested it on. I'm still waiting from a more formal review from people, but I think it will hold up. The one thing I dislike about the patch is that I had to implement another knob (OPTIONS_DESC) which maintainers must turn on when they implement the long description field. The reason for this is that without it I can't determine the difference between a port which has 3 OPTIONS with a long description (12 fields) or a port which has 4 OPTIONS without a long description (12 fields). Ideally, over time people will adopt this extension and eventually the knob can be removed and can be the default case. Of course, this is highly optimistic thinking... :)

I just spoke to some people tonight and they are concerned that it may break existing applications which parse OPTIONS. This lends credence to my initial thoughts on how to do it. I'll probably whip up that approach one of these nights and also try and get a formal review of it from the right people.

For now, here's the patch I described:

Index: bsd.port.mk
===================================================================
RCS file: /home/ncvs/ports/Mk/bsd.port.mk,v
retrieving revision 1.591
diff -u -u -r1.591 bsd.port.mk
--- bsd.port.mk 11 Mar 2008 23:45:04 -0000  1.591
+++ bsd.port.mk 1 Apr 2008 17:04:57 -0000
@@ -1229,6 +1229,7 @@
 .else
 UNIQUENAME?=   ${PKGNAMEPREFIX}${PORTNAME}
 .endif
+OPTIONSDESCFILE?=  ${PORT_DBDIR}/${UNIQUENAME}/options.descr
 OPTIONSFILE?=  ${PORT_DBDIR}/${UNIQUENAME}/options
 _OPTIONSFILE!= ${ECHO_CMD} "${OPTIONSFILE}"
 .if defined(OPTIONS)
@@ -5781,6 +5782,7 @@
        . ${_OPTIONSFILE}; \
    fi; \
    set -- ${OPTIONS} XXX; \
+   TMPOPTIONSDESCFILE=$$(mktemp -t portoptionsdescr); \
    while [ $$# -gt 3 ]; do \
        OPTIONSLIST="$${OPTIONSLIST} $$1"; \
        defaultval=$$3; \
@@ -5796,14 +5798,24 @@
            val=$$3; \
        fi; \
        DEFOPTIONS="$${DEFOPTIONS} $$1 \"$$2\" $${val}"; \
-       shift 3; \
+       if [ -n "${OPTIONS_DESC}" ]; then \
+           ${ECHO_CMD} "$$1: $$4" | fmt >> $${TMPOPTIONSDESCFILE}; \
+           shift 4; \
+       else \
+           shift 3; \
+       fi; \
    done; \
    TMPOPTIONSFILE=$$(mktemp -t portoptions); \
-   trap "${RM} -f $${TMPOPTIONSFILE}; exit 1" 1 2 3 5 10 13 15; \
-   ${SH} -c "${DIALOG} --checklist \"Options for ${PKGNAME:C/-([^-]+)$/ \1/}\" 21 70 15 $${DEFOPTIONS} 2> $${TMPOPTIONSFILE}"; \
+   trap "${RM} -f $${TMPOPTIONSFILE}; ${RM} -f $${TMPOPTIONSDESCFILE}; exit 1" 1 2 3 5 10 13 15; \
+   if [ -n "${OPTIONS_DESC}" ]; then \
+       ${SH} -c "${DIALOG} --hfile $${TMPOPTIONSDESCFILE} --hline \"Press ? for a detailed description\" --checklist \"Options for ${PKGNAME:C/-([^-]+)$/ \1/}\" 21 70 15 $${DEFOPTIONS} 2> $${TMPOPTIONSFILE}"; \
+   else \
+       ${SH} -c "${DIALOG} --checklist \"Options for ${PKGNAME:C/-([^-]+)$/ \1/}\" 21 70 15 $${DEFOPTIONS} 2> $${TMPOPTIONSFILE}"; \
+   fi; \
    status=$$?; \
    if [ $${status} -ne 0 ] ; then \
        ${RM} -f $${TMPOPTIONSFILE}; \
+       ${RM} -f $${TMPOPTIONSDESCFILE}; \
        ${ECHO_MSG} "===> Options unchanged"; \
        exit 0; \
    fi; \
@@ -5830,11 +5842,18 @@
    if [ `${ID} -u` != 0 -a "x${INSTALL_AS_USER}" = "x" ]; then \
        ${ECHO_MSG} "===>  Switching to root credentials to write ${_OPTIONSFILE}"; \
        ${SU_CMD} "${CAT} $${TMPOPTIONSFILE} > ${_OPTIONSFILE}"; \
+       if [ -n "${OPTIONS_DESC}" ]; then \
+           ${SU_CMD} "${CAT} $${TMPOPTIONSDESCFILE} > ${OPTIONSDESCFILE}"; \
+       fi; \
        ${ECHO_MSG} "===>  Returning to user credentials"; \
    else \
        ${CAT} $${TMPOPTIONSFILE} > ${_OPTIONSFILE}; \
+       if [ -n "${OPTIONS_DESC}" ]; then \
+           ${CAT} $${TMPOPTIONSDESCFILE} > ${OPTIONSDESCFILE}; \
+       fi; \
    fi; \
-   ${RM} -f $${TMPOPTIONSFILE}
+   ${RM} -f $${TMPOPTIONSFILE}; \
+   ${RM} -f $${TMPOPTIONSDESCFILE}
 .endif
 .endif

@@ -5868,7 +5887,11 @@
        if [ "$${val}" = "missing" ]; then \
            OPTIONS_INVALID=yes; \
        fi; \
-       shift 3; \
+       if [ -n "${OPTIONS_DESC}" ]; then \
+           shift 4; \
+       else \
+           shift 3; \
+       fi; \
    done; \
    if [ "$${OPTIONS_INVALID}" = "yes" ]; then \
        cd ${.CURDIR} && ${MAKE} config; \
@@ -5900,8 +5923,13 @@
        else \
            val="$$3 (default)"; \
        fi; \
-       ${ECHO_MSG} "     $$1=$${val} \"$$2\""; \
-       shift 3; \
+       if [ -n "${OPTIONS_DESC}" ]; then \
+           ${ECHO_CMD} "     $$1=$${val} \"$$2\" ($$4)" | fmt; \
+           shift 4; \
+       else \
+           ${ECHO_MSG} "     $$1=$${val} \"$$2\""; \
+           shift 3; \
+       fi; \
    done
    @${ECHO_MSG} "===> Use 'make config' to modify these settings"
 .endif
@@ -5909,16 +5937,17 @@

 .if !target(rmconfig)
 rmconfig:
-.if defined(OPTIONS) && exists(${_OPTIONSFILE})
+.if defined(OPTIONS) && (exists(${_OPTIONSFILE}) || exists(${OPTIONSDESCFILE}))
    -@${ECHO_MSG} "===> Removing user-configured options for ${PKGNAME}"; \
    optionsdir=${_OPTIONSFILE}; optionsdir=$${optionsdir%/*}; \
    if [ `${ID} -u` != 0 -a "x${INSTALL_AS_USER}" = "x" ]; then \
        ${ECHO_MSG} "===> Switching to root credentials to remove ${_OPTIONSFILE} and $${optionsdir}"; \
-       ${SU_CMD} "${RM} -f ${_OPTIONSFILE} ; \
+       ${SU_CMD} "${RM} -f ${_OPTIONSFILE} ${OPTIONSDESCFILE}; \
            ${RMDIR} $${optionsdir}"; \
        ${ECHO_MSG} "===> Returning to user credentials"; \
    else \
        ${RM} -f ${_OPTIONSFILE}; \
+       ${RM} -f ${OPTIONSDESCFILE}; \
        ${RMDIR} $${optionsdir}; \
    fi
 .else

posted at: 19:59 | tags: , | path: /entries/freebsd | permanent link to this entry

Mon, 24 Mar 2008

Fastest Sites is Committed.

Coming to a portsnap (or c[v]sup) mirror near you is something I just committed tonight. It's actually really small but quite useful and written by Jordan Sissel called fastest_sites.py. Basically, for every MASTER_SITE_foo in bsd.sites.mk it will run through the list and sort it based upon RTT for a TCP handshake (which is the best guess for least effort). The sorted list is output'ed in such a fashion that it can be included into your make.conf (.include "/path/to/output" is best).

It's quite useful for people who want to control the MASTER_SITE_foo closely. It's available at ports-mgmt/fastest_sites.

posted at: 21:42 | tags: , , | path: /entries/freebsd | permanent link to this entry