I need to document this so I can refer to it while debugging.
This follows the chain of scripts which processes a commit.
Periodic
FreshPorts, at present, checks for new commits every three minutes, via this entry in /etc/crontab:
*/3 * * * * root periodic everythreeminutes
That will invoke this script:
$ cat /usr/local/etc/periodic/everythreeminutes/215.fp_check_git_for_commits #!/bin/sh - # # FreshPorts periodic script # # Checks to see if there are any new commits waiting # # If there is a global system configuration file, suck it in. # if [ -r /etc/defaults/periodic.conf ] then . /etc/defaults/periodic.conf source_periodic_confs fi # assign default values fp_scripts_dir=${fp_scripts_dir:-/usr/local/libexec/freshports} case "$fp_check_for_git_commits_enable" in [Yy][Ee][Ss]) logger -p local3.notice -t FreshPorts "into $0" echo "" cd $fp_scripts_dir && ./helper_scripts/check_for_git_commits.sh || rc=3 ;; *) rc=0;; esac exit $rc
check_for_git_commits.sh
This is a cheat.
$ cat /usr/local/libexec/freshports/helper_scripts/check_for_git_commits.sh #!/bin/sh logger -t check_for_git_commits.sh -p local4.notice "touching ~ingress/signals/check_git ~ingress/signals/job_waiting" echo touch ~ingress/signals/check_git ~ingress/signals/job_waiting | sudo su -fm ingress logger -t check_for_git_commits.sh -p local4.notice "done touching, going away now"
It touches a file, which is a signal for the ingress daemon.
ingress.sh
$ cat /usr/local/libexec/freshports-service/ingress.sh #!/bin/sh # # $Id: fp-daemon.sh,v 1.17 2006-11-10 14:08:26 dan Exp $ # # Copyright (c) 2001-2003 DVL Software # # # include our local parameters . /usr/local/etc/freshports/ingress.sh CP='/bin/cp' # we do not use -i because that would fail when re re-run a commit MV='/bin/mv' RM='/bin/rm' PERL='/usr/local/bin/perl' # # sanity checking upon startup # check_for_jobs() { # # This flag file is only set by a job run by this script. # A race condition should never arise. # FLAG="${INGRESS_FLAGDIR}/job_waiting" if [ -f ${FLAG} ] then cd ${SCRIPTDIR} echo "yes, there is a job waiting" echo "running ${PERL} ./job-waiting.pl" echo "from directory ${SCRIPTDIR}" ls -l ./job-waiting.pl ${PERL} ./job-waiting.pl if [ $? -eq 0 ] then echo "job-waiting.pl finishes normally" else echo "FATAL job-waiting.pl finished with an error: $?" fi rm ${FLAG} fi } echo "starting up!" if [ ! -d ${SCRIPTDIR} ] then echo "Required directory does not exist: ${SCRIPTDIR}" exit fi if [ ! -d ${INGRESS_MSGDIR}/incoming ] then echo "Required directory does not exist: ${INGRESS_MSGDIR}/incoming" exit fi echo incoming: ${INGRESS_MSGDIR}/incoming echo ready while : do cd ${SCRIPTDIR} INCOMING=${INGRESS_MSGDIR}/incoming if [ -e 'OFFLINE' ] then echo "system is OFFLINE: ${SCRIPTDIR}/OFFLINE exists" break else check_for_jobs fi sleep 3 done
That script checks for files in the incoming queue. More on that, perhaps later.
Then, if not OFFLINE, it checks for waiting jobs.
job-waiting.pl
$ cat /usr/local/libexec/freshports/job-waiting.pl #!/usr/local/bin/perl -w # # $Id: job-waiting.pl,v 1.3 2007-01-29 00:17:35 dan Exp $ # # Copyright (c) 1999-2007 DVL Software # # This script is invoked by the fp-freshports.sh script # usually located in /var/services/freshports # use strict; use DBI; use FreshPorts::database; use FreshPorts::cache; use FreshPorts::commit_log_ports_ignore; use FreshPorts::system_status; use FreshPorts::utilities; # added in for testing require Sys::Syslog; FreshPorts::Utilities::InitSyslog(); #die('we are done here - stopped'); Sys::Syslog::syslog('warning', "running job-waiting.pl"); my %Jobs_ingress = ( $FreshPorts::Config::CheckGit => 'check_git.sh', ); my %Jobs_freshports = ( $FreshPorts::Config::MovedFileFlag => 'process_moved.sh', $FreshPorts::Config::NewReposReadyForImport => 'import_packagesite.py', $FreshPorts::Config::NewRepoImported => 'UpdatePackagesFromRawPackages.py', $FreshPorts::Config::UpdatingFileFlag => 'process_updating.sh', $FreshPorts::Config::VuXMLFileFlag => 'process_vuxml.sh', $FreshPorts::Config::WWWENPortsCategoriesFlag => 'process_www_en_ports_categories.sh', ); FreshPorts::Utilities::Report('notice', "starting $0"); # # This script is invoked by either the freshports or the ingress user # they have separate lists of jobs to look for. Rather than maintain two # scripts, there is one. # my $username = getpwuid($<); my %Jobs; FreshPorts::Utilities::Report('notice', "running $0 as user = '$username'"); if ($username eq 'freshports') { %Jobs = %Jobs_freshports; } elsif ($username eq 'ingress') { %Jobs = %Jobs_ingress; } else { FreshPorts::Utilities::Report('notice', "WHO IS THAT USER? I don't know them. Stopping."); die($0 . ' must be run only as the ingress or freshports users'); exit; } FreshPorts::Utilities::Report('notice', "checking jobs for $username"); my $JobFound; do { $JobFound = 0; # one job might create another, so we keeping looping until they are all cleared. while (my ($flag, $script) = each %Jobs) { if (-f $flag) { $JobFound =1; FreshPorts::Utilities::Report('notice', "$flag exists. About to run $script"); `$FreshPorts::Config::scriptpath/$script`; FreshPorts::Utilities::Report('notice', "Finished running $script"); } else { FreshPorts::Utilities::Report('notice', "flag '$flag' not set. no work for $script"); } } } until (!$JobFound);
In there, we find that check_git.sh is invoked.
check_git.sh
$ cat /usr/local/libexec/freshports/check_git.sh #!/bin/sh # This script exists mainly to redirect the output of git-delta.sh to a logfile. # if [ ! -f /usr/local/etc/freshports/config.sh ] then echo "/usr/local/etc/freshports/config.sh not found by $0" exit 1 fi . /usr/local/etc/freshports/config.sh LOGGERTAG=check_git.sh ${LOGGER} -t ${LOGGERTAG} $0 has started # redirect everything into the file ${SCRIPTDIR}/git-delta.sh "doc ports ports-quarterly src" >> ${GITLOG} 2>&1 /bin/rm ${CHECKGITFILE} ${LOGGER} -t ${LOGGERTAG} $0 has finished
git-delta.sh
$ cat /usr/local/libexec/freshports/git-delta.sh #!/bin/sh # process the new commits # based upon https://github.com/FreshPorts/git_proc_commit/issues/3 # An idea from https://github.com/sarcasticadmin if [ ! -f /usr/local/etc/freshports/config.sh ] then echo "/usr/local/etc/freshports/config.sh.sh not found by $0" exit 1 fi # this can be a space separated list of repositories to check # e.g. "doc ports src" repos=$1 . /usr/local/etc/freshports/config.sh LOGGERTAG='git-delta.sh' logfile "has started. Will check these repos: '${repos}'" # what remote are we using on this repo? REMOTE='origin' # where we do dump the XML files which we create? XML="${INGRESS_MSGDIR}/incoming" logfile "XML dir is $XML" for repo in ${repos} do logfile "Now processing repo: ${repo}" # convert the repo label to a physical directory on disk dir=`convert_repo_label_to_directory ${repo}` # empty means error if [ "${dir}" == "" ]; then logfile "FATAL error, repo='${repo}' is unknown: cannot translate it to a directory name" continue fi # where is the repo directory? # This is the directory which contains the repos. REPODIR="${INGRESS_PORTS_DIR_BASE}/${dir}" LATEST_FILE="${INGRESS_PORTS_DIR_BASE}/latest.${dir}" if [ -d ${REPODIR} ]; then logfile "REPODIR='${REPODIR}' exists" else logfile "FATAL error, REPODIR='${REPODIR}' is not a directory" continue fi if [ -f ${LATEST_FILE} ]; then logfile "LATEST_FILE='${LATEST_FILE}' exists" else logfile "FATAL error, LATEST_FILE='${LATEST_FILE}' does not exist. We need a starting point." continue fi logfile "Repodir is $REPODIR" # on with the work cd ${REPODIR} # Update local copies of remote branches # logfile "Running: ${GIT} fetch $REMOTE:" # ${GIT} fetch $REMOTE # logfile "Done." # logfile "Running: ${GIT} checkout master:" # ${GIT} checkout master # logfile "Done." logfile "Running: ${GIT} pull:" ${GIT} pull logfile "Done." # let's try having the latest commt in this this. STARTPOINT=`cat ${LATEST_FILE}` if [ "${STARTPOINT}x" = 'x' ] then logfile "STARTPOINT is empty; there must not be any new commits to process" logfile "Not proceeding with this repo: '${repo}'" continue else logfile "STARTPOINT = ${STARTPOINT}" fi # Bring local branch up-to-date with the local remote # logfile "Running; ${GIT} rebase $REMOTE/master:" # ${GIT} rebase $REMOTE/master # logfile "Running; ${GIT} fetch:" # ${GIT} fetch # logfile "Done." # get list of commits, if only to document them here logfile "Running: ${GIT} rev-list ${STARTPOINT}..HEAD" commits=`${GIT} rev-list ${STARTPOINT}..HEAD` logfile "Done." if [ -z "commits" ] then logfile "No commits were found" else logfile "The commits found are:" for commit in $commits do logfile "$commit" done fi logfile "${SCRIPTDIR}/git-to-freshports-xml.py --repo ${repo} --path ${REPODIR} --commit ${STARTPOINT} --spooling ${INGRESS_SPOOLINGDIR} --output ${XML}" ${SCRIPTDIR}/git-to-freshports-xml.py --repo ${repo} --path ${REPODIR} --commit ${STARTPOINT} --spooling ${INGRESS_SPOOLINGDIR} --output ${XML} new_latest=`${GIT} rev-parse HEAD` echo $new_latest > ${LATEST_FILE} done logfile "Ending"
git-to-freshports-xml.py creates the XML files which are placed into the incoming queue (at ~ingress/message-queues/incoming).
The files are noticed by the freshports daemon (running as /usr/local/libexec/freshports-service/freshports.sh).