source: tags/confman-1.3.1/confmanlib.sh @ 111

Revision 111, 10.9 KB checked in by ccowart, 6 years ago (diff)

Rolling the next confman.

  • Property rc:mode set to 0444
  • Property svn:keywords set to Date Rev Author Id
Line 
1#! /bin/bash
2#
3# This file provides shell libraries to our configuration management system.
4# It will be sourced by the relevant Rescomp scripts.
5#
6# Author: Chris Cowart <ccowart@rescomp.berkeley.edu>
7# Date: 30 March 2006
8#
9# $Id$
10
11REPO_URI="${REPO_PROTOCOL}${REPO_HOSTNAME}${REPO_PATH}"
12
13# Checks out the conf tree if we don't already have it. Updates it if we do.
14function conf_checkout_tree {
15        if [ ! -d ${WORK_PATH} ] ; then
16                        local path=`echo ${WORK_PATH} | sed -E 's:/[^/]+$::'`
17                        mkdir -p ${WORK_PATH}
18
19                        # This makes sure nobody can enter your working copy. We relax the
20                        # permissions during the rollout, and restrict them again at
21                        # the end.
22                        chmod 700 ${WORK_PATH}
23
24                        svn checkout ${REPO_URI} ${WORK_PATH}
25                        rm -rf ${path}/.svn
26        else
27                        svn update ${WORK_PATH}
28        fi
29}
30
31# I update the working copy of a given module to the repository's copy.
32function conf_update_module {
33        local module="$1"
34        svn update ${WORK_PATH}/${module}
35}
36
37# Updates the whole source tree
38function conf_update_tree {
39        svn update ${WORK_PATH}
40}
41
42# Revert a working file
43function conf_revert {
44        svn revert $*
45}
46
47# Assumes that we already have core setup in our work path.
48function conf_create_module {
49        local module=$1
50        svn mkdir ${WORK_PATH}/$module
51        svn mkdir ${WORK_PATH}/${REPO_CHECKPTS}/$module
52        svn commit ${WORK_PATH}/${module} ${WORK_PATH}/${REPO_CHECKPTS}/$module -m \
53                        "Created directory structure for ${module} --`whoami`"
54}
55
56# Commits module $1 with message $2
57function conf_commit {
58        local module=$1
59        local msg="$2"
60        svn commit -F "$msg" ${WORK_PATH}/$module
61}
62
63# A way to utilize the svn status feature.
64function conf_status {
65        svn status $*
66}
67
68# Roll out the specified module, optionally at the specified checkpoint
69# eg:   conf_rollout MODULE [checkpoint]
70function conf_rollout {
71        local module="$1"
72        if [ -z $2 ] ; then
73                local moduledir="${WORK_PATH}/$module"
74        else
75                local moduledir="${WORK_PATH}/checkpoints/${module}/${2}"
76        fi
77        # This is a hack to work around NFS home dirs, for now:
78        chmod o+rx ${WORK_PATH}
79
80        for directory in `find $moduledir -type d | grep -v "\.svn"` ; do
81                local livedir=`echo $directory | sed "s:$moduledir::"`
82                livedir="${LIVE_ROOT}${livedir}"
83                if [ ! -d $livedir ] ; then
84                                local owner=`conf_get_prop ${directory} owner`
85                                local group=`conf_get_prop ${directory} group`
86                                local mode=`conf_get_prop ${directory} mode`
87                        local opts="-d -o $owner -g $group -m $mode"
88                        local cmd="sudo install $opts $livedir"
89                        echo $cmd
90                        $cmd
91                fi
92        done
93        for file in `find $moduledir -type f | grep -v "\.svn"` ; do
94                local livefile=`echo "$file" | sed "s:$moduledir::"`
95                local owner=`conf_get_prop ${file} owner`
96                local group=`conf_get_prop ${file} group`
97                local mode=`conf_get_prop ${file} mode`
98                local opts="-Sp -o $owner -g $group -m $mode"
99                local cmd="sudo install $opts $file ${LIVE_ROOT}$livefile"
100                echo $cmd
101                $cmd
102        done
103        # This is a hack to work around NFS home dirs, for now:
104        chmod o-rx ${WORK_PATH}
105}
106
107function conf_install {
108        local module="$1"
109        shift
110        local file=`abspath $1`
111        shift
112        local moduledir="${WORK_PATH}/$module"
113        local livefile=`echo "$file" | sed -E "s:${WORK_PATH}/[^/]+::"`
114        local pathmodule=`echo "$file" | sed -E "s:${WORK_PATH}/([^/]+).*:\1:"`
115        local suffix
116        livefile=`echo "$livefile" | sed -E "s:-${pathmodule}$::"`
117        if [[ $SINGULARITIES =~ $livefile ]] ; then
118                suffix="-${module}"
119        fi
120        livefile="${livefile}${suffix}"
121
122
123        # See if it even exists
124        file="${moduledir}${livefile}"
125        if [ ! -f "$file" ] && [ -z "$1" ] ; then
126                return 0
127        elif [ ! -f "$file" ] ; then
128                conf_install $module $*
129        fi
130
131        # If we got here, figure it out
132        local owner=`conf_get_prop ${file} owner`
133        local group=`conf_get_prop ${file} group`
134        local mode=`conf_get_prop ${file} mode`
135        local opts="-Sp -o $owner -g $group -m $mode"
136        local cmd="sudo install $opts $file ${LIVE_ROOT}$livefile"
137
138        chmod o+rx ${WORK_PATH}
139        echo $cmd
140        $cmd
141        chmod o-rx ${WORK_PATH}
142
143        if [ ! -z $1 ] ; then
144                conf_install $module $*
145        fi
146}
147
148
149function conf_list {
150        local file=$1
151        local module=`echo ${file#$WORK_PATH} | sed -E 's:/([^/]+)/.*:\1:'`
152        local livefile=`echo ${file#$WORK_PATH} | sed -E 's:/([^/]+)/:/:'`
153        local owner=`conf_get_prop ${file} owner`
154        local group=`conf_get_prop ${file} group`
155        local mode=`conf_get_prop ${file} mode`
156        local comment=`conf_get_prop ${file} comment`
157        echo -e "$mode\t$owner\t$group\t$comment\t\t$livefile"
158}
159       
160
161
162# This function assembles the singularities:
163function conf_assemble_sing {
164        local file=$1
165        local livefile="${LIVE_ROOT}${file}"
166        local tmpfile=`mktemp -t confman` || exit 1
167        local owner group mode flag livepart msg
168        for layer in $LAYERS ; do
169                livepart="${LIVE_ROOT}${file}-${layer}"
170                myfile="${WORK_PATH}/${layer}/${file}-${layer}"
171                if [ -f $myfile -a -f $livepart ] ; then
172                                owner=`conf_get_prop ${myfile} owner`
173                                group=`conf_get_prop ${myfile} group`
174                                mode=`conf_get_prop     ${myfile} mode`
175                        comment=`conf_get_prop  ${myfile} comment`
176                        cat $livepart >> $tmpfile
177                        sudo rm $livepart
178                        flag=1
179                fi
180        done
181        if [ ! -z $flag ] ; then
182                local opts="-Sp -o $owner -g $group -m $mode"
183        local cmd="sudo install $opts $tmpfile $livefile"
184                echo $cmd
185                $cmd
186        fi
187        rm -f $tmpfile
188}
189
190# This function generates a checkpoint called NAME for the given MODULE.
191# eg: conf_new_checkpoint MODULE NAME
192function conf_new_checkpoint {
193        local module=$1
194        local checkpoint=$2
195        local chkpath="${WORK_PATH}/${REPO_CHECKPTS}/${module}/${checkpoint}"
196        local revision=`svn info ${WORK_PATH} | awk '/Last Changed Rev:/ {print $4}'`
197        echo $revision > $chkpath
198        svn add $chkpath
199        local msg="Created a checkpoint, ${checkpoint} for ${module} --`whoami`"
200        svn commit ${WORK_PATH}/${REPO_CHECKPTS} -m "$msg"
201}
202
203# This function will remove the checkpoint NAME from MODULE.
204# eg: conf_rm_checkpoint MODULE NAME
205function conf_rm_checkpoint {
206        local module=$1
207        local checkpoint=$2
208        local chkpath="${WORK_PATH}/${REPO_CHECKPTS}/${module}/${checkpoint}"
209        svn rm ${chkpath}
210        local msg="Removed the checkpoint ${checkpoint} from ${module} --`whoami`"
211        svn commit ${WORK_PATH}/${REPO_CHECKPTS} -m "$msg"
212}
213
214# This function will restore the state of your module's working copy to the
215# named checkpoint. eg: conf_rollback MODULE NAME
216function conf_rollback {
217        local module=$1
218        local checkpoint=$2
219        local clock=$3
220        local modpath="${WORK_PATH}/${module}"
221        local chkpath="${WORK_PATH}/${REPO_CHECKPTS}/${module}/${checkpoint}"
222        local revision
223        local date=`echo $checkpoint | sed -E 's:(....)(..)(..):\1-\2-\3:'`
224
225        # Named checkpoint
226        if [ -f "${chkpath}" ] ; then
227        revision=`cat $chkpath`
228        elif [ -z $clock ] ; then               # Time checkpoint
229        revision="{${date}}"
230        else
231        clock=`echo $clock | sed -E 's#(..)(..)#\1:\2#'`
232        revision="{${date}T${clock}}"
233        fi
234
235        svn update --revision $revision $modpath
236}
237
238# This function will print the value of the specified property to STDOUT
239function conf_get_prop {
240        local file=$1
241        local prop=$2
242        svn propget "confman:${prop}" ${file}
243}
244
245# This function will set the value of the specified property.
246function conf_set_prop {
247        local file=$1
248        local prop=$2
249        local value=$3
250        svn propset "confman:${prop}" "${value}" ${file}
251}
252
253function conf_gen_file {
254        local module=$1
255        local file=$2
256        local owner=$3
257        local group=$4
258        local mode=$5
259        local comment="$6"
260        local usefile=$7
261        local myfile="${WORK_PATH}/${module}${file}"
262        local warning="${comment} ${CONF_WARNING}"
263        local morewarn="${comment} Managed under ${module} module."
264        local revision="${comment} \$Id\$"
265        echo $file
266
267        if [ -z $usefile ] ; then
268                                        echo -e "${warning}\n${morewarn}\n${revision}\n" > $myfile
269        elif head -n 1 ${usefile} | grep '^#!' >/dev/null ; then
270                                        awk "{if (NR==2)
271                                                        print \"\\n${warning}\\n${morewarn}\\n${revision}\\n\"\$0;
272                                                                else print \$0 }" ${usefile} > $myfile
273        else
274                                        echo -e "${warning}\n${morewarn}\n${revision}\n" > $myfile
275                                        cat ${usefile} >> $myfile
276        fi
277
278        svn add $myfile
279        svn ps svn:keywords "Id" $myfile
280        conf_set_prop $myfile owner $owner
281        conf_set_prop $myfile group $group
282        conf_set_prop $myfile mode      $mode
283        conf_set_prop $myfile comment "$comment"
284}
285
286function conf_rm_file {
287        svn rm $*
288}
289
290function conf_mkdir {
291        local directory=$1
292        local owner=$2
293        local group=$3
294        local mode=$4
295        local workdir="/"
296        local directories=`echo "$directory" | sed 's:/: :g'`
297        local dir
298
299        for dir in $directories ; do
300                workdir="${workdir}/${dir}"
301                if [ ! -d ${workdir} ] ; then
302                        echo svn mkdir ${workdir}
303                        svn mkdir ${workdir}
304                        conf_set_prop $workdir owner $owner
305                        conf_set_prop $workdir group $group
306                        conf_set_prop $workdir mode $mode
307                        conf_set_prop $workdir comment "dir"
308                fi
309        done
310}
311
312function conf_rmmod {
313        local module=$1
314        svn rm ${WORK_PATH}/${module}
315        svn rm ${WORK_PATH}/${REPO_CHECKPTS}/${module}
316}
317
318function conf_rename {
319        local oldmod=$1
320        local newmod=$2
321        local file
322
323        # First, we perform the easy operations
324        svn mv ${WORK_PATH}/${oldmod} ${WORK_PATH}/${newmod} || \
325                {       echo "There was a problem renaming the modules." >&4 ; \
326                        conf_clean_exit 1
327                }
328        svn mv ${WORK_PATH}/${REPO_CHECKPTS}/${oldmod} \
329                        ${WORK_PATH}/${REPO_CHECKPTS}/${newmod} || \
330                {       echo "There was a problem renaming the checkpts." >&4 ; \
331                        conf_clean_exit 1
332                }
333
334        svn update ${WORK_PATH} || \
335                {       echo "Your working copy didn't update correctly." >&4 ; \
336                        conf_clean_exit 1
337                }
338        svn commit -m "Renaming ${oldmod} to ${newmod}, phase 1." \
339                ${WORK_PATH}/{,${REPO_CHECKPTS}}/{${oldmod},${newmod}} || \
340                {       echo "Committing the changes failed." >&4 ; conf_clean_exit 1
341                }
342
343        # Next, we have to rename any singularities
344        for file in ${SINGULARITIES} ; do
345                if [ -f "${WORK_PATH}/${newmod}${file}-${oldmod}" ] ; then
346                        svn mv ${WORK_PATH}/${newmod}${file}-${oldmod} \
347                                        ${WORK_PATH}/${newmod}${file}-${newmod}
348                fi
349        done
350
351        svn update ${WORK_PATH} || \
352                {       echo "Your working copy didn't update correctly." >&4 ; \
353                        conf_clean_exit 1
354                }
355        svn commit -m "Renaming ${oldmod} to ${newmod}, phase 2." 
356                ${WORK_PATH}/${newmod} || \
357                {       echo "Committing the changes failed." >&4 ; conf_clean_exit 1
358                }
359
360        # Now, we have to go fix all the confman headers in all the files...
361        find ${WORK_PATH}/${newmod} -type f -not -path '*/.svn/*' -exec \
362                gsed -i -r "s/^(# Managed under )${oldmod}( module)/\1${newmod}\2/" \
363                {} \;
364       
365        svn update ${WORK_PATH} || \
366                {       echo "Your working copy didn't update correctly." >&4 ; \
367                        conf_clean_exit 1
368                }
369        svn commit -m "Renaming ${oldmod} to ${newmod}, complete." \
370                ${WORK_PATH}/${newmod} || \
371                {       echo "Committing the changes failed." >&4 ; conf_clean_exit 1
372                }
373}
374
375function conf_mv {
376        local oldname=$1
377        local newname=$2
378        svn mv $oldname $newname
379}
380
381function conf_cp {
382        local oldname=$1
383        local newname=$2
384        svn cp $oldname $newname
385}
386
387function conf_diff {
388        svn diff $*
389}
390
391function conf_log {
392        svn log $*
393}
394
395function conf_cleanexit {
396        echo "Abort, Abort! Patience is a virtue." >&2
397        echo "Please wait until I finish cleaning up after you." >&4
398        rm -f /tmp/confman*
399
400        # And in case we got an interrupt during a rollout, we still want the
401        # permissions here to be in a consistent state.
402        chmod 700 ${WORK_PATH}
403
404        # And this clears any locks we may have created on our working copy:
405        svn cleanup ${WORK_PATH}
406        echo "All clean. Terminating." >&2
407
408        if [ -z $1 ] ; then
409                exit 1
410        else
411        exit $1
412        fi
413}       
414
415# vim:ts=4
416
Note: See TracBrowser for help on using the repository browser.