This is a proposed wiki how-to. I thought I'd roll it out here first to elicit comments. Anyone please chime in here. If I receive positive feedback, I'll author a wiki page on this topic.
Goal:
Using minimal download bandwidth and a minimal on-disc footprint, allow one to run any branch of squeezeboxserver / logitechmediaserver from 7.0 to 7.8 as a service and to easily allow switching between installed branches.
This is potentially useful to plugin writers who often need to test compatibility with various sbs/lms versions.
Assumptions:
- Running on Ubuntu or some debian based distro.
- Service will run under the user account 'lms'.
- Local git repository will reside at /usr/share/lms/server.
- We'll create separate data and log directories for any branch we're going to run.
- Those data and log dirs will be at /var/lib/lms_data/${BRANCHNAME} and /var/log/lms_log/${BRANCHNAME}
- Those data and log dirs will be linked to /var/lib/lms and /var/log/lms
- We'll create a generic 'lms' service for running the code.
- We'll make updating the repo a service control option.
- We'll have a script for easily switching between branches.
So, for example, say we're running the lms 7.8.x git code. Switching to SqueezeCenter 7.3.x would be as easy as:
Also, for example, updating the currently running branch to the latest code and discarding any local changes would be as easy as:Code:# /usr/local/sbin/lms-switch-branch.sh 7.3
Preparation:Code:# service lms force-update
Become root
Create the lms user account:Code:sudo su
Download the latest version of the repo:Code:useradd --gid nogroup --no-create-home --no-user-group --system --shell /bin/false "lms"
Note: by downloading only the latest revisions for every branch, we keep the downloaded object file to about 250M. Remove the "--depth 1" from that command to make previous revisions available.Code:git clone -n --depth 1 https://github.com/Logitech/slimserver.git /usr/share/lms/server
Checkout branch 7.8
Code:cd /usr/share/lms/server git checkout 7.8
Create data and log dirs for the 7.8 branch
Create links to the data and log dirs..Code:mkdir -p /var/lib/lms_data/7.8 chown -R lms:nogroup /var/lib/lms_data mkdir -p /var/log/lms_log/7.8 chown -R lms:nogroup /var/log/lms_log
Create a defaults file for the service..Code:ln -s /var/lib/lms_data/7.8 /var/lib/lms ln -s /var/log/lms_log/7.8 /var/log/lms
/etc/default/lms:
Create a service control script..Code:SLIMDESC='LMS branch 7.8 git code' SLIMUSER='lms' SLIMOPTIONS=''
/etc/init.d/lms:
Create a service safe script..Code:#!/bin/sh ### BEGIN INIT INFO # Provides: lms # Required-Start: $all # Required-Stop: $all # Should-Start: $all # Should-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Startup script for the LMS Media Server git code # Description: LMS Media Server git code powers the Squeezebox, Transporter and SLIMP3 network music # players and is the best software to stream your music to any software MP3 # player. It supports MP3, AAC, WMA, FLAC, Ogg Vorbis, WAV and more! # As of version 7.7 it also supports UPnP clients, serving pictures and movies too! ### END INIT INFO # # $Id$ # # lms initscript for slimserver.pl # This file should be placed in /etc/init.d. # # Original Author: Mattias Holmlund # Updated By: Dan Sully, Michael Herger # # Rewrite 20120515 by Gordon Harris to make conforming with: # http://refspecs.linuxbase.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html # and based on http://www.thegeekstuff.com/2012/03/lsbinit-script/ # # Using the lsb functions to perform the operations. . /lib/lsb/init-functions SLIMSRVC='lms' SLIMUSER='lms' SLIMGROUP=$(id -ng $SLIMUSER) SLIMDESC='LMS Media Server git code' REPO=/usr/share/$SLIMSRVC/server DAEMON=/usr/share/$SLIMSRVC/server/slimserver.pl DAEMON_SAFE=/usr/sbin/${SLIMSRVC}_safe PIDFILE=/var/run/${SLIMSRVC}.pid SCRIPTNAME=$(basename /etc/init.d/${SLIMSRVC}) PREFSDIR=/var/lib/${SLIMSRVC}/prefs LOGDIR=/var/log/${SLIMSRVC}/ CACHEDIR=/var/lib/${SLIMSRVC}/cache CHARSET=utf8 SLIMOPTIONS= # Read config file if it is present. if [ -r /etc/default/${SLIMSRVC} ]; then . /etc/default/${SLIMSRVC} fi d_check_running() { if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE $DAEMON "$SLIMDESC" > /dev/null 2>&1 && status=0 || status=$? if [ $status -eq 0 ]; then log_daemon_msg "$SLIMDESC is already running" log_end_msg 0 exit 0 fi fi } d_start() { d_check_running log_daemon_msg "Starting" "$SLIMDESC" # Use lms_safe to restart the daemon when # it dies. This must be done to handle mysql restarts. if start-stop-daemon --start --quiet \ --chuid $SLIMUSER \ --pidfile $PIDFILE \ --exec $DAEMON_SAFE \ --background \ --make-pidfile \ -- \ $DAEMON \ --prefsdir $PREFSDIR \ --logdir $LOGDIR \ --cachedir $CACHEDIR \ --charset=$CHARSET \ $SLIMOPTIONS ; then log_end_msg 0 else log_end_msg 1 fi } # This starts lms without the safe script.. d_start_direct() { d_check_running log_daemon_msg "Starting" "$SLIMDESC" # Make the pid file writeable by lms touch $PIDFILE chown "${SLIMUSER}:${SLIMGROUP}" $PIDFILE if start-stop-daemon --start --quiet \ --chuid $SLIMUSER \ --pidfile $PIDFILE \ --exec $DAEMON \ --background \ --make-pidfile \ -- \ --pidfile $PIDFILE \ --prefsdir $PREFSDIR \ --logdir $LOGDIR \ --cachedir $CACHEDIR \ --charset=$CHARSET \ $SLIMOPTIONS ; then log_end_msg 0 else log_end_msg 1 fi } d_stop() { if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE $DAEMON "$SLIMDESC" > /dev/null 2>&1 && status=0 || status=$? if [ $status -eq 0 ]; then log_begin_msg "Stoppping $SLIMDESC" start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE --retry=TERM/30/KILL/5 /bin/rm -rf $PIDFILE log_end_msg 0 fi else # status 3: program is not running status=3 fi if [ $status -gt 0 ]; then # status 1: program is dead and /var/run pid file exists log_daemon_msg "$SLIMDESC is not running" fi } # # Function that sends a SIGHUP to the daemon/service. # d_reload() { start-stop-daemon --stop --quiet --pidfile $PIDFILE --signal 1 } d_status() { if [ -e $PIDFILE ]; then status_of_proc -p $PIDFILE $DAEMON "$SLIMDESC" && exit 0 || exit $? else log_daemon_msg "${SLIMDESC} is not running" cd "$REPO" && in_repo log_daemon_msg "Getting ${SLIMDESC} repository status.." git remote show origin git status log_end_msg 3 fi } in_repo(){ if [ $(pwd) != "$REPO" ]; then log_daemon_msg "Error: ${REPO} not found." log_end_msg 3 exit 128 fi } d_update() { log_daemon_msg "Updating $SLIMDESC" cd "$REPO" && in_repo git pull && status=0 || status=$? if [ $status -eq 0 ]; then log_daemon_msg "${SLIMDESC} has ben updated." else log_daemon_msg "Error updating ${SLIMDESC}." fi } d_force_update() { log_daemon_msg "Force-Updating $SLIMDESC" cd "$REPO" && in_repo git reset --hard git clean -fd git pull && status=0 || status=$? if [ $status -eq 0 ]; then log_daemon_msg "${SLIMDESC} has ben updated." else log_daemon_msg "Error updating ${SLIMDESC}." fi } if [ ! -x "$DAEMON" ]; then log_daemon_msg "${DAEMON} not found." log_end_msg 5 exit 5 fi if [ ! -x "$DAEMON_SAFE" ]; then log_daemon_msg "${DAEMON_SAFE} not found." log_end_msg 5 exit 5 fi case "$1" in start) d_start ;; start-direct) d_start_direct ;; stop) d_stop ;; # reload) # d_reload # ;; restart|force-reload) d_stop sleep 3 d_start ;; update) d_stop sleep 3 d_update sleep 3 d_start ;; force-update) d_stop sleep 3 d_force_update sleep 3 d_start ;; status) d_status ;; *) log_action_msg "Usage: $(which service) $(basename $0) {start|stop|restart|force-reload|update|force-update|status}" exit 2 ;; esac exit $?
/usr/sbin/lms_safe:
..to be continued..Code:#!/bin/bash # $Id$ if [ $# = 0 ] then echo "To stop Logitech Media Server git code, kill this script instead of the" echo "actual lms process." echo echo "Usage: $0 lms-binary lms-arguments" exit 1 fi function clean_up { # Kill the daemon if it is running kill $SLIMPID echo $(date "+%F %H:%M:%S") $(basename $0) "stopped." >> /var/log/lms/server.log exit } trap clean_up SIGINT SIGHUP SIGTERM echo $(date "+%F %H:%M:%S") $(basename $0) "started." >> /var/log/lms/server.log while true do # From the Bash Reference Manual: # When Bash receives a signal for which a trap has been set # while waiting for a command to complete, the trap will not # be executed until the command completes. When Bash is waiting # for an asynchronous command via the wait builtin, the reception # of a signal for which a trap has been set will cause the wait # builtin to return immediately with an exit status greater than # 128, immediately after which the trap is executed. "$@" --norestart > /dev/null 2>&1 & SLIMPID=$! # wait for the server to get started before wait() sleep 5 wait $SLIMPID echo $(date "+%F %H:%M:%S") "Logitech Media Server git code died. Restarting." >> /var/log/lms/server.log # Normally, when the server realizes that the mysql-connection is gone, # the mysql server has already been started again. So no need to sleep # here. done
Results 1 to 3 of 3
-
2012-05-14, 19:06 #1
How to manage running multiple branchs of LMS git code
Last edited by gharris999; 2012-05-17 at 12:08.
-
2012-05-15, 20:27 #2
..continued.
Create a log rotate script..
/etc/logrotate.d/lms:
Create service control links:Code:/var/log/lms/server.log { weekly rotate 5 size 200k compress missingok postrotate # send USR1 to squeezebox PID to reset logging /bin/kill -USR1 `pgrep -f 'perl.*slimserver.pl' -n 2>/dev/null` 2>/dev/null || : endscript } /var/log/lms/scanner.log { weekly rotate 5 size 200k compress missingok }
Create a branch switching script:Code:update-rc.d -f lms remove >/dev/null 2>&1 update-rc.d -f lms defaults
/usr/local/sbin/lms-switch-branch.sh
Script for running the git code from the console in debug mode:Code:#!/bin/sh NEWBRANCH='7.8' ISGOODBRANCH=0 #Discard local changes... DISCARD=0 #Update repo UPDATE=0 if [ ! -z "$1" ]; then NEWBRANCH="$1" fi # Change to the repo dir.. cd /usr/share/lms/server # Get a list of the available branches.. BRANCHES=`git branch -r | sed -n -e 's#^.*origin/\(.*\)$#\1#p'` for BRANCH in $BRANCHES do if [ "$NEWBRANCH" = "$BRANCH" ]; then ISGOODBRANCH=1 fi done if [ $ISGOODBRANCH -lt 1 ]; then echo "Error: ${NEWBRANCH} is not a branch of github.com/Logitech/slimserver.git" echo "Available branches:" echo $BRANCHES exit 1 fi # Stop the service.. service lms stop # Do a hard reset of the repo to discard any local changes.. if [ $DISCARD -gt 0 ]; then git reset --hard git clean -fd fi # Switch to the new branch git checkout "$NEWBRANCH" if [ $? -gt 0 ]; then echo "Error checking out branch ${NEWBRANCH}." exit 1 fi # Update the default file with the name of the new branch RE="s/^SLIMDESC=.*$/SLIMDESC='LMS branch ${NEWBRANCH} git code'" sed -i -e "$RE" /etc/default/lms # Update the repo if [ $UPDATE -gt 0 ]; then git pull fi # Create new data & log dirs.. LIBDIR="/var/lib/lms_data/${NEWBRANCH}" LOGDIR="/var/log/lms_log/${NEWBRANCH}" if [ ! -d "$LIBDIR" ]; then mkdir -p "$LIBDIR" fi if [ ! -d "$LOGDIR" ]; then mkdir -p "$LOGDIR" fi # Fix permissions chown -r lms:nogroup "$LIBDIR" chown -r lms:nogroup "$LOGDIR" # Create new data & log links LIBDIRLINK='/var/lib/lms' LOGDIRLINK='/var/log/lms' if [ -L "$LIBDIRLINK" ]; then rm "$LIBDIRLINK" fi if [ ! -d "$LIBDIRLINK" ]; then ln -s "$LIBDIR" "$LIBDIRLINK" fi if [ -L "$LOGDIRLINK" ]; then rm "$LOGDIRLINK" fi if [ ! -d "$LOGDIRLINK" ]; then ln -s "$LOGDIR" "$LOGDIRLINK" fi # Restart the service.. service lms start exit $?
lms-git-debug.sh
That's it for now. Mostly, I'm looking for comments here on the advisability of this approach.Code:#!/bin/bash # Script to debug running of lms git code.. #RUNASROOT=1 RUNASROOT=0 INSTNAME='lms' INSTUSER='lms' PIDFILE=/var/lib/${INSTNAME}/${INSTNAME}.pid PREFSDIR=/var/lib/${INSTNAME}/prefs LOGDIR=/var/log/${INSTNAME} CACHEDIR=/var/lib/${INSTNAME}/cache PUSER=${INSTUSER} PGROUP=`id -ng $PUSER` OUTFILE=./${INSTNAME}-git-debug.txt if [ -e ${PIDFILE} ]; then rm ${PIDFILE} fi echo "Attempting to start ${INSTNAME}.." echo " Console output redirected to ${OUTFILE}.." echo " Hit CTRL+C to terminate.." if [[ $RUNASROOT -eq 1 ]]; then /usr/bin/perl /usr/share/${INSTNAME}/server/slimserver.pl --pidfile=${PIDFILE} --user=${PUSER} --group=${PGROUP} --cachedir=${CACHEDIR} --prefsdir=${PREFSDIR} --logdir=${LOGDIR} --charset=utf8 --diag --d_startup >${OUTFILE} 2>&1 else sudo -u ${INSTUSER} /usr/bin/perl /usr/share/${INSTNAME}/server/slimserver.pl --pidfile=${PIDFILE} --cachedir=${CACHEDIR} --prefsdir=${PREFSDIR} --logdir=${LOGDIR} --charset=utf8 --diag --d_startup >${OUTFILE} 2>&1 fi rm ${PIDFILE} echo "Done! Examine ${OUTFILE} for details.."
-
2012-06-05, 20:38 #3
Ok, I've put together an install script that automates all the above steps, installing a 'lms' service which runs the logitechmediaserver git code. I've tested this script with Ubuntu 12.04 and Fedora 16. On Ubuntu (and other debian systems) the script installs a regular sysv-style init script. On Fedora and other distros using systemd, the script installs unit files.

Reply With Quote
