Skip to content

Commit

Permalink
Let standard domain (/var)/run/cups/cups.sock be used if available
Browse files Browse the repository at this point in the history
Now, if there is not already a CUPS running (for example from .deb
packages), the Snap's CUPS uses the standard domain socket
(/var)/run/cups/cups.sock and the standard port 631. If domain socket
or port are already occupied the alternatives
/var/snap/printing-stack-snap/common/run/cups.sock and port 10631 are
used.

To make this Snap's tools always use this Snap's CUPS, the actually
selected domain socket is set as ServerName in the Snap's client.conf,
/var/snap/printing-stack-snap/common/etc/cups/client.conf and libcups
is built to use this client.conf by default.

This Snap's cups-browsed is started with the CUPS_SERVER environment
variable set to the selected domain socket. So it always attaches to
the CUPS of this Snap.

Further changes and fixes to make this working and to make this Snap
also correctly working with the extra check of administrative tasks of
the previous commit:

- All apps which do admin tasks via cupsd (cups-browsed, lpadmin,
  cupsenable, cupsdisable, cupsaccept, cupsreject, cancel, cupsctl)
  are now plugging cups-control.

- A new interface "cups-domain-socket" based on the "system-files"
  interface allows the Snap's apps to read/write access the standard
  CUPS domain socket (/var)/run/cups/cups.sock.

- The CUPS build system is patched to use
  /var/snap/printing-stack-snap/common/etc/cups instead of /etc/cups
  as standard CUPS_SERVERROOT, especially to make libcups use the
  Snap's client.conf.

- run-cupsd checks whether the standard CUPS domain socket is free
  using the "lsof" utility. Then it drops the selected domain socket
  as ServerName in client.conf, so that the utilities use it.

- run-cups-browsed reads the domain socket from client.conf and sets
  the CUPS_SERVER environment variable before starting cups-browsed.
  run-cups-browsed waits for cupsd coming up, by checking the presence
  of the PID file and whether there is actually a process with this
  PID.  Only then it reads client.conf, to be sure it contains the
  currently selected domain socket.

- run-cupsd and run-cups-browsed delete their PID files in the end, as
  when they end, their corresponding daemon has terminated.

- Fixed the PID file paths in stop-cupsd and stop-cups-browsed.

- Changed the location for CUPS config files to
  /var/snap/printing-stack-snap/common/etc/cups
  • Loading branch information
tillkamppeter committed May 6, 2020
1 parent 2e5817f commit 2da5047
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 68 deletions.
35 changes: 31 additions & 4 deletions scripts/run-cups-browsed
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ set -e -x
mkdir -p $SNAP_DATA/var/log
mkdir -p $SNAP_DATA/var/cache
mkdir -p $SNAP_DATA/var/run
mkdir -p $SNAP_COMMON/etc
mkdir -p $SNAP_COMMON/etc/cups

CONF=$SNAP_COMMON/etc/cups-browsed.conf
CONF=$SNAP_COMMON/etc/cups/cups-browsed.conf
CLIENTCONF=$SNAP_COMMON/etc/cups/client.conf
DAEMON=cups-browsed
DOMAINSOCKET=$SNAP_DATA/var/run/cups.sock

# Set UTF-8
export LC_ALL=C.UTF-8
Expand All @@ -35,9 +35,33 @@ mkdir -p $TMPDIR
#export CUPS_FONTPATH=$SNAP_DATA/share/cups/fonts
#export CUPS_REQUESTROOT=$SNAP_DATA/var/spool
#export CUPS_SERVERBIN=$SNAP_DATA/lib/cups
#export CUPS_SERVERROOT=$SNAP_COMMON/etc
#export CUPS_SERVERROOT=$SNAP_COMMON/etc/cups
#export CUPS_STATEDIR=$SNAP_DATA/var/run

# Wait for this Snap's CUPS coming up before preparing
# cups-browsed.conf and starting cups-browsed, to assure
# that it attaches to the correct CUPS
CUPSSTARTED=0
for i in $(seq 60); do
if [ -r ${SNAP_DATA}/var/run/cupsd.pid ]; then
PID=$(cat "${SNAP_DATA}/var/run/cupsd.pid" || true)
if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
CUPSSTARTED=1
break;
fi
fi
sleep 1
done
if [ "${CUPSSTARTED}" = "0" ]; then
echo "ERROR: CUPS startup timed out"
exit 1
fi

# Read domain socket from CUPS' client.conf
DOMAINSOCKET=`grep -i ServerName $CLIENTCONF | cut -d ' ' -f 2`

export CUPS_SERVER=$DOMAINSOCKET

# Create cups-browsed.conf if not already present
if [ ! -f $CONF ]; then
# Get upstream default config file
Expand All @@ -64,3 +88,6 @@ echo $PID > $SNAP_DATA/var/run/cups-browsed.pid

# Keep this script running until cups-browsed terminates
wait $PID

# Remove PID file as process is done
rm -f $SNAP_DATA/var/run/cups-browsed.pid
84 changes: 54 additions & 30 deletions scripts/run-cupsd
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ mkdir -p $SNAP_DATA/var/spool/tmp
mkdir -p $SNAP_DATA/var/run/certs
mkdir -p $SNAP_DATA/var/log
mkdir -p $SNAP_DATA/var/cache/fontconfig
mkdir -p $SNAP_COMMON/etc/ppd
mkdir -p $SNAP_COMMON/etc/ssl
mkdir -p $SNAP_COMMON/etc/cups/ppd
mkdir -p $SNAP_COMMON/etc/cups/ssl
mkdir -p $SNAP_COMMON/etc/fonts
mkdir -p $SNAP_COMMON/run

# Set UTF-8
export LC_ALL=C.UTF-8
Expand All @@ -28,10 +29,10 @@ mkdir -p $TMPDIR
export FONTCONFIG_FILE=$SNAP_COMMON/etc/fonts/fonts.conf

# Create cups-files.conf if not already present
if [ ! -f $SNAP_COMMON/etc/cups-files.conf ]; then
if [ ! -f $SNAP_COMMON/etc/cups/cups-files.conf ]; then
# Get default cups-files.conf
CUPSFILESCONF=$SNAP/etc/cups/cups-files.conf
cp $CUPSFILESCONF $SNAP_COMMON/etc/cups-files.conf
cp $CUPSFILESCONF $SNAP_COMMON/etc/cups/cups-files.conf
fi

# Set paths for the snap
Expand All @@ -49,30 +50,30 @@ perl -p -i \
-e 's:^(\s*\#)?\s*Printcap\s+.*$:Printcap '"$SNAP_COMMON"'/etc/printcap:;' \
-e 's:^(\s*\#)?\s*RequestRoot\s+.*$:RequestRoot '"$SNAP_DATA"'/var/spool:;' \
-e 's:^(\s*\#)?\s*ServerBin\s+.*$:ServerBin '"$SNAP"'/lib/cups:;' \
-e 's:^(\s*\#)?\s*ServerRoot\s+.*$:ServerRoot '"$SNAP_COMMON"'/etc:;' \
-e 's:^(\s*\#)?\s*ServerRoot\s+.*$:ServerRoot '"$SNAP_COMMON"'/etc/cups:;' \
-e 's:^(\s*\#)?\s*StateDir\s+.*$:StateDir '"$SNAP_DATA"'/var/run:;' \
-e 's:^(\s*\#)?\s*TempDir\s+.*$:TempDir '"$SNAP_DATA"'/var/spool/tmp:;' \
$SNAP_COMMON/etc/cups-files.conf
grep -q 'PassEnv FONTCONFIG_FILE' $SNAP_COMMON/etc/cups-files.conf ||
echo PassEnv FONTCONFIG_FILE >> $SNAP_COMMON/etc/cups-files.conf
# chmod 0640 $SNAP_COMMON/etc/cups-files.conf
$SNAP_COMMON/etc/cups/cups-files.conf
grep -q 'PassEnv FONTCONFIG_FILE' $SNAP_COMMON/etc/cups/cups-files.conf ||
echo PassEnv FONTCONFIG_FILE >> $SNAP_COMMON/etc/cups/cups-files.conf
# chmod 0640 $SNAP_COMMON/etc/cups/cups-files.conf

# Create cupsd.conf if not already present
if [ ! -f $SNAP_COMMON/etc/cupsd.conf ]; then
if [ ! -f $SNAP_COMMON/etc/cups/cupsd.conf ]; then
# Get default cupsd.conf
CUPSDCONF=$SNAP/etc/cups/cupsd.conf
cat $CUPSDCONF | \
grep -v 'Listen' | \
perl -p -e 's:^(\s*<Location\s*/>\s*)$:$1 Allow \@LOCAL\n:' \
> $SNAP_COMMON/etc/cupsd.conf
> $SNAP_COMMON/etc/cups/cupsd.conf

# No restrictions on size of log file
echo MaxLogSize 9999999 >> $SNAP_COMMON/etc/cupsd.conf
echo MaxLogSize 9999999 >> $SNAP_COMMON/etc/cups/cupsd.conf

# Debug logging
perl -p -i -e 's:^(\s*)\#?(\s*LogLevel\s+)\S+:\1\2debug:g' $SNAP_COMMON/etc/cupsd.conf
perl -p -i -e 's:^(\s*)\#?(\s*LogLevel\s+)\S+:\1\2debug:g' $SNAP_COMMON/etc/cups/cupsd.conf

# chmod 0640 $SNAP_COMMON/etc/cupsd.conf
# chmod 0640 $SNAP_COMMON/etc/cups/cupsd.conf
fi

# Create fonts.conf if not already present
Expand All @@ -89,48 +90,71 @@ perl -p -i \
$SNAP_COMMON/etc/fonts/fonts.conf

# Create snmp.conf if not already present
if [ ! -f $SNAP_COMMON/etc/snmp.conf ]; then
if [ ! -f $SNAP_COMMON/etc/cups/snmp.conf ]; then
# Get default snmp.conf
cp $SNAP/etc/cups/snmp.conf $SNAP_COMMON/etc/
cp $SNAP/etc/cups/snmp.conf $SNAP_COMMON/etc/cups/
fi

# Get further default files but do not overwrite existing ones
yes n | cp -ri $SNAP/etc/cups/ppd $SNAP_COMMON/etc/
yes n | cp -ri $SNAP/etc/cups/ssl $SNAP_COMMON/etc/
yes n | cp -ri $SNAP/etc/cups/ppd $SNAP_COMMON/etc/cups/
yes n | cp -ri $SNAP/etc/cups/ssl $SNAP_COMMON/etc/cups/

#chmod 711 $SNAP_DATA/var/run/certs/
#chown root.root $SNAP_DATA/var/run/certs/

# Make sure that port and domain socket of this snap are always used
# Make sure that port and domain socket of this Snap are always used
# Use standard port and domain socket if this is the first CUPS started
# on this system (assumed to be the system's default CUPS)
PORT=631
ALTPORT=10631
DOMAINSOCKET=$SNAP_DATA/var/run/cups.sock
DOMAINSOCKET=/run/cups/cups.sock
if [ ! -d /run/cups ]; then
DOMAINSOCKET=/var/run/cups/cups.sock
fi
ALTDOMAINSOCKET=$SNAP_COMMON/run/cups.sock

# If the standard port 631 is occupied (by a system CUPS installed via
# DEB/RPM/source for example) use alternative port
if $SNAP/scripts/port-occupied $PORT; then
# CUPS already running (Debian packages), try alternative port
# CUPS already running, try alternative port
PORT=$ALTPORT
fi

# If the standard domain socket is in use (by a system CUPS installed via
# DEB/RPM/source for example) use alternative domain socket
if lsof $DOMAINSOCKET > /dev/null 2>&1; then
# CUPS already running, try alternative port
DOMAINSOCKET=$ALTDOMAINSOCKET
fi

# Set the port in cupsd.conf
cat $SNAP_COMMON/etc/cupsd.conf | grep -v Listen | grep -v Port > $SNAP_COMMON/etc/cupsd.conf.new && \
echo Port $PORT > $SNAP_COMMON/etc/cupsd.conf && \
cat $SNAP_COMMON/etc/cupsd.conf.new >> $SNAP_COMMON/etc/cupsd.conf && \
rm $SNAP_COMMON/etc/cupsd.conf.new
( cat $SNAP_COMMON/etc/cups/cupsd.conf | grep -v Listen | grep -v Port > $SNAP_COMMON/etc/cups/cupsd.conf.new || true ) && \
echo Port $PORT > $SNAP_COMMON/etc/cups/cupsd.conf && \
cat $SNAP_COMMON/etc/cups/cupsd.conf.new >> $SNAP_COMMON/etc/cups/cupsd.conf && \
rm -f $SNAP_COMMON/etc/cups/cupsd.conf.new

# Set the domain socket in cupsd.conf
cat $SNAP_COMMON/etc/cupsd.conf | grep -v Listen > $SNAP_COMMON/etc/cupsd.conf.new && \
echo Listen $DOMAINSOCKET > $SNAP_COMMON/etc/cupsd.conf && \
cat $SNAP_COMMON/etc/cupsd.conf.new >> $SNAP_COMMON/etc/cupsd.conf && \
rm $SNAP_COMMON/etc/cupsd.conf.new
( cat $SNAP_COMMON/etc/cups/cupsd.conf | grep -v Listen > $SNAP_COMMON/etc/cups/cupsd.conf.new || true ) && \
echo Listen $DOMAINSOCKET > $SNAP_COMMON/etc/cups/cupsd.conf && \
cat $SNAP_COMMON/etc/cups/cupsd.conf.new >> $SNAP_COMMON/etc/cups/cupsd.conf && \
rm -f $SNAP_COMMON/etc/cups/cupsd.conf.new

# Set the domain socket in client.conf
touch $SNAP_COMMON/etc/cups/client.conf
( cat $SNAP_COMMON/etc/cups/client.conf | grep -v ServerName > $SNAP_COMMON/etc/cups/client.conf.new || true ) && \
echo ServerName $DOMAINSOCKET > $SNAP_COMMON/etc/cups/client.conf && \
cat $SNAP_COMMON/etc/cups/client.conf.new >> $SNAP_COMMON/etc/cups/client.conf && \
rm -f $SNAP_COMMON/etc/cups/client.conf.new

SCHEDULER=cupsd

# Spawn cupsd in a way that we can grab its PID
exec $SCHEDULER -f -s $SNAP_COMMON/etc/cups-files.conf -c $SNAP_COMMON/etc/cupsd.conf &
exec $SCHEDULER -f -s $SNAP_COMMON/etc/cups/cups-files.conf -c $SNAP_COMMON/etc/cups/cupsd.conf &
PID=$!
echo $PID > $SNAP_DATA/var/run/cupsd.pid

# Keep this script running until cupsd terminates
wait $PID

# Remove PID file as process is done
rm -f $SNAP_DATA/var/run/cupsd.pid
10 changes: 5 additions & 5 deletions scripts/stop-cups-browsed
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
set -e -x

# Exit if we are already shutting down cups-browsed
if [ -f "${SNAP_COMMON}/pid/stop-cups-browsed.lock" ]; then
if [ -f "${SNAP_DATA}/var/run/stop-cups-browsed.lock" ]; then
echo "==> We are already shutting down cups-browsed"
exit 0
fi
touch "${SNAP_COMMON}/pid/stop-cups-browsed.lock"
touch "${SNAP_DATA}/var/run/stop-cups-browsed.lock"

# Shut down cups-browsed
echo "==> Shutting down cups-browsed"
PID=$(cat "${SNAP_COMMON}/pid/cups-browsed.pid" || true)
PID=$(cat "${SNAP_DATA}/var/run/cups-browsed.pid" || true)
if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
kill -TERM "${PID}"

Expand All @@ -31,5 +31,5 @@ if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
fi

# Removing PID file
rm -f "${SNAP_COMMON}/pid/cups-browsed.pid"
rm -f "${SNAP_COMMON}/pid/stop-cups-browsed.lock"
rm -f "${SNAP_DATA}/var/run/cups-browsed.pid"
rm -f "${SNAP_DATA}/var/run/stop-cups-browsed.lock"
10 changes: 5 additions & 5 deletions scripts/stop-cupsd
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
set -e -x

# Exit if we are already shutting down cupsd
if [ -f "${SNAP_COMMON}/pid/stop-cupsd.lock" ]; then
if [ -f "${SNAP_DATA}/var/run/stop-cupsd.lock" ]; then
echo "==> We are already shutting down cupsd"
exit 0
fi
touch "${SNAP_COMMON}/pid/stop-cupsd.lock"
touch "${SNAP_DATA}/var/run/stop-cupsd.lock"

# Shut down cups-browsed first, so that it can remove its temporary queues
# before CUPS shuts down
Expand All @@ -16,7 +16,7 @@ $SNAP/stop-cups-browsed

# Shut down CUPS
echo "==> Shutting down CUPS"
PID=$(cat "${SNAP_COMMON}/pid/cupsd.pid" || true)
PID=$(cat "${SNAP_DATA}/var/run/cupsd.pid" || true)
if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
kill -TERM "${PID}"

Expand All @@ -36,5 +36,5 @@ if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
fi

# Removing PID file
rm -f "${SNAP_COMMON}/pid/cupsd.pid"
rm -f "${SNAP_COMMON}/pid/stop-cupsd.lock"
rm -f "${SNAP_DATA}/var/run/cupsd.pid"
rm -f "${SNAP_DATA}/var/run/stop-cupsd.lock"
Loading

0 comments on commit 2da5047

Please sign in to comment.