Changeset 30004 for trunk/base


Ignore:
Timestamp:
Oct 17, 2007, 10:35:05 PM (12 years ago)
Author:
nox@…
Message:

portstartupitem.tcl: Whitespace changes (expanded tabs).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/src/port1.0/portstartupitem.tcl

    r28768 r30004  
    3636
    3737#
    38 #       Newly added keys:
    39 #
    40 #       startupitem.executable  the command to start the executable
    41 #               This is exclusive of init, start, stop, restart
    42 #               - This may be composed of exec arguments only--not shell code
    43 #
    44 #       startupitem.pidfile             none
    45 #               There is no pidfile we can track
    46 #
    47 #       startupitem.pidfile             auto [filename.pid]
    48 #               The daemon is responsible for creating/deleting the pidfile
    49 #
    50 #       startupitem.pidfile             clean [filename.pid]
    51 #               The daemon creates the pidfile, but we must delete it
    52 #
    53 #       startupitem.pidfile             manual [filename.pid]
    54 #               We create and destroy the pidfile to track the pid we receive from the executable
    55 #
    56 #       startupitem.logfile             logpath
    57 #               Log to the specified file -- if not specified then output to /dev/null
    58 #               - for launchd, just set this as the standard out key
    59 #               - for systemstarter, redirect to this
    60 #
    61 #       startupitem.logevents   yes/no
    62 #               Log events to the log
    63 #               - for launchd, generate log messages inside daemondo
    64 #               - for systemstarter, generate log messages in our generated script
     38#   Newly added keys:
     39#
     40#   startupitem.executable  the command to start the executable
     41#       This is exclusive of init, start, stop, restart
     42#       - This may be composed of exec arguments only--not shell code
     43#
     44#   startupitem.pidfile     none
     45#       There is no pidfile we can track
     46#
     47#   startupitem.pidfile     auto [filename.pid]
     48#       The daemon is responsible for creating/deleting the pidfile
     49#
     50#   startupitem.pidfile     clean [filename.pid]
     51#       The daemon creates the pidfile, but we must delete it
     52#
     53#   startupitem.pidfile     manual [filename.pid]
     54#       We create and destroy the pidfile to track the pid we receive from the executable
     55#
     56#   startupitem.logfile     logpath
     57#       Log to the specified file -- if not specified then output to /dev/null
     58#       - for launchd, just set this as the standard out key
     59#       - for systemstarter, redirect to this
     60#
     61#   startupitem.logevents   yes/no
     62#       Log events to the log
     63#       - for launchd, generate log messages inside daemondo
     64#       - for systemstarter, generate log messages in our generated script
    6565#
    6666
     
    7171
    7272proc startupitem_create_rcng {args} {
    73         global prefix destroot portname os.platform
    74         global startupitem.name startupitem.requires
    75         global startupitem.start startupitem.stop startupitem.restart
    76         global startupitem.type
    77 
    78         set scriptdir ${destroot}/${prefix}/etc/rc.d
    79 
    80         if { ![exists startupitem.requires] } {
    81                 set startupitem.requires ""
    82         }
    83 
    84         # XXX We can't share defaults with startupitem_create_darwin
    85         foreach item {startupitem.start startupitem.stop startupitem.restart} {
    86                 if {![info exists $item]} {
    87                         return -code error "Missing required option $item"
    88                 }
    89         }
    90 
    91         file mkdir ${destroot} ${scriptdir}
    92         set fd [open [file join ${scriptdir} ${startupitem.name}.sh] w 0755]
    93 
    94         puts ${fd} "#!/bin/sh"
    95         puts ${fd} "#"
    96         puts ${fd} "# MacPorts generated RCng Script"
    97         puts ${fd} "#"
    98         puts ${fd} ""
    99         puts ${fd} "# PROVIDE: ${startupitem.name}"
    100         puts ${fd} "# REQUIRE: ${startupitem.requires}"
    101         # TODO: Implement BEFORE support
    102         puts ${fd} "# BEFORE:"
    103         puts ${fd} "# KEYWORD: MacPorts"
    104         puts ${fd} ""
    105         puts ${fd} ". ${prefix}/etc/rc.subr"
    106         puts ${fd} ""
    107         puts ${fd} "name=\"${startupitem.name}\""
    108         puts ${fd} "start_cmd=\"${startupitem.start}\""
    109         puts ${fd} "stop_cmd=\"${startupitem.stop}\""
    110         puts ${fd} "restart_cmd=\"${startupitem.restart}\""
    111         puts ${fd} ""
    112         puts ${fd} "load_rc_config \"${startupitem.name}\""
    113         puts ${fd} ""
    114         puts ${fd} "run_rc_command \"\$1\""
    115         close ${fd}
     73    global prefix destroot portname os.platform
     74    global startupitem.name startupitem.requires
     75    global startupitem.start startupitem.stop startupitem.restart
     76    global startupitem.type
     77
     78    set scriptdir ${destroot}/${prefix}/etc/rc.d
     79
     80    if { ![exists startupitem.requires] } {
     81        set startupitem.requires ""
     82    }
     83
     84    # XXX We can't share defaults with startupitem_create_darwin
     85    foreach item {startupitem.start startupitem.stop startupitem.restart} {
     86        if {![info exists $item]} {
     87            return -code error "Missing required option $item"
     88        }
     89    }
     90
     91    file mkdir ${destroot} ${scriptdir}
     92    set fd [open [file join ${scriptdir} ${startupitem.name}.sh] w 0755]
     93
     94    puts ${fd} "#!/bin/sh"
     95    puts ${fd} "#"
     96    puts ${fd} "# MacPorts generated RCng Script"
     97    puts ${fd} "#"
     98    puts ${fd} ""
     99    puts ${fd} "# PROVIDE: ${startupitem.name}"
     100    puts ${fd} "# REQUIRE: ${startupitem.requires}"
     101    # TODO: Implement BEFORE support
     102    puts ${fd} "# BEFORE:"
     103    puts ${fd} "# KEYWORD: MacPorts"
     104    puts ${fd} ""
     105    puts ${fd} ". ${prefix}/etc/rc.subr"
     106    puts ${fd} ""
     107    puts ${fd} "name=\"${startupitem.name}\""
     108    puts ${fd} "start_cmd=\"${startupitem.start}\""
     109    puts ${fd} "stop_cmd=\"${startupitem.stop}\""
     110    puts ${fd} "restart_cmd=\"${startupitem.restart}\""
     111    puts ${fd} ""
     112    puts ${fd} "load_rc_config \"${startupitem.name}\""
     113    puts ${fd} ""
     114    puts ${fd} "run_rc_command \"\$1\""
     115    close ${fd}
    116116}
    117117
    118118proc startupitem_create_darwin_systemstarter {args} {
    119         global UI_PREFIX prefix destroot destroot.keepdirs  portname os.platform
    120         global startupitem.name startupitem.requires startupitem.init
    121         global startupitem.start startupitem.stop startupitem.restart startupitem.executable
    122         global startupitem.pidfile startupitem.logfile startupitem.logevents
    123        
    124         set scriptdir ${prefix}/etc/startup
    125        
    126         set itemname                    ${startupitem.name}
    127         set uppername                   [string toupper ${startupitem.name}]
    128         set itemdir                             /Library/StartupItems/${itemname}
    129         set startupItemDir              ${destroot}${itemdir}
    130         set startupItemScript   ${startupItemDir}/${itemname}
    131         set startupItemPlist    ${startupItemDir}/StartupParameters.plist
    132        
    133         # Interpret the pidfile spec
    134         #
    135         # There are four cases:
    136         #       (1) none (or none specified)
    137         #       (2) auto [pidfilename]
    138         #       (3) clean [pidfilename]
    139         #       (4) manual [pidfilename]
    140         #
    141         set createPidFile false
    142         set deletePidFile false
    143         set pidFile ""
    144         set pidfileArgCnt [llength ${startupitem.pidfile}]
    145         if { ${pidfileArgCnt} > 0 } {
    146                 if { $pidfileArgCnt == 1 } {
    147                         set pidFile "${prefix}/var/run/${itemname}.pid"
    148                         lappend destroot.keepdirs "${destroot}${prefix}/var/run"
    149                 } else {
    150                         set pidFile [lindex ${startupitem.pidfile} 1]
    151                 }
    152                 if { $pidfileArgCnt > 2 } {
    153                         ui_error "$UI_PREFIX [msgcat::mc "Invalid parameter count to startupitem.pidfile: 2 expected, %d found" ${pidfileArgCnt}]"
    154                 }
    155                
    156                 set pidStyle [lindex ${startupitem.pidfile} 0]
    157                 switch ${pidStyle} {
    158                         none    { set createPidFile false; set deletePidFile false; set pidFile ""      }
    159                         auto    { set createPidFile false; set deletePidFile false      }
    160                         clean   { set createPidFile false; set deletePidFile true       }
    161                         manual  { set createPidFile true;  set deletePidFile true       }
    162                         default {
    163                                 ui_error "$UI_PREFIX [msgcat::mc "Unknown pidfile style %s presented to startupitem.pidfile" ${pidStyle}]"
    164                         }
    165                 }
    166         }
    167 
    168         if { [llength ${startupitem.executable}] &&
    169                         ![llength ${startupitem.init}] &&
    170                         ![llength ${startupitem.start}] &&
    171                         ![llength ${startupitem.stop}] &&
    172                         ![llength ${startupitem.restart}] } {
    173                 # An executable is specified, and there is no init, start, stop, or restart
    174         } else {
    175                 if { ![llength ${startupitem.start} ] } {
    176                         set startupitem.start [list "sh ${scriptdir}/${portname}.sh start"]
    177                 }
    178                 if { ![llength ${startupitem.stop} ] } {
    179                         set startupitem.stop [list "sh ${scriptdir}/${portname}.sh stop"]
    180                 }
    181         }
    182         if { ![llength ${startupitem.requires} ] } {
    183                 set startupitem.requires [list Disks NFS]
    184         }
    185         if { ![llength ${startupitem.logfile} ] } {
    186                 set startupitem.logfile "/dev/null"
    187         }
    188        
    189         ########################
    190         # Create the startup item directory
    191         file mkdir ${startupItemDir}
    192         file attributes ${startupItemDir} -owner root -group wheel
    193        
    194         ########################
    195         # Generate the startup item script
    196         set item [open "${startupItemScript}" w 0755]
    197         file attributes "${startupItemScript}" -owner root -group wheel
    198        
    199         # Emit the header
    200         puts ${item} {#!/bin/sh
     119    global UI_PREFIX prefix destroot destroot.keepdirs  portname os.platform
     120    global startupitem.name startupitem.requires startupitem.init
     121    global startupitem.start startupitem.stop startupitem.restart startupitem.executable
     122    global startupitem.pidfile startupitem.logfile startupitem.logevents
     123   
     124    set scriptdir ${prefix}/etc/startup
     125   
     126    set itemname            ${startupitem.name}
     127    set uppername           [string toupper ${startupitem.name}]
     128    set itemdir             /Library/StartupItems/${itemname}
     129    set startupItemDir      ${destroot}${itemdir}
     130    set startupItemScript   ${startupItemDir}/${itemname}
     131    set startupItemPlist    ${startupItemDir}/StartupParameters.plist
     132   
     133    # Interpret the pidfile spec
     134    #
     135    # There are four cases:
     136    #   (1) none (or none specified)
     137    #   (2) auto [pidfilename]
     138    #   (3) clean [pidfilename]
     139    #   (4) manual [pidfilename]
     140    #
     141    set createPidFile false
     142    set deletePidFile false
     143    set pidFile ""
     144    set pidfileArgCnt [llength ${startupitem.pidfile}]
     145    if { ${pidfileArgCnt} > 0 } {
     146        if { $pidfileArgCnt == 1 } {
     147            set pidFile "${prefix}/var/run/${itemname}.pid"
     148            lappend destroot.keepdirs "${destroot}${prefix}/var/run"
     149        } else {
     150            set pidFile [lindex ${startupitem.pidfile} 1]
     151        }
     152        if { $pidfileArgCnt > 2 } {
     153            ui_error "$UI_PREFIX [msgcat::mc "Invalid parameter count to startupitem.pidfile: 2 expected, %d found" ${pidfileArgCnt}]"
     154        }
     155       
     156        set pidStyle [lindex ${startupitem.pidfile} 0]
     157        switch ${pidStyle} {
     158            none    { set createPidFile false; set deletePidFile false; set pidFile ""  }
     159            auto    { set createPidFile false; set deletePidFile false  }
     160            clean   { set createPidFile false; set deletePidFile true   }
     161            manual  { set createPidFile true;  set deletePidFile true   }
     162            default {
     163                ui_error "$UI_PREFIX [msgcat::mc "Unknown pidfile style %s presented to startupitem.pidfile" ${pidStyle}]"
     164            }
     165        }
     166    }
     167
     168    if { [llength ${startupitem.executable}] &&
     169            ![llength ${startupitem.init}] &&
     170            ![llength ${startupitem.start}] &&
     171            ![llength ${startupitem.stop}] &&
     172            ![llength ${startupitem.restart}] } {
     173        # An executable is specified, and there is no init, start, stop, or restart
     174    } else {
     175        if { ![llength ${startupitem.start} ] } {
     176            set startupitem.start [list "sh ${scriptdir}/${portname}.sh start"]
     177        }
     178        if { ![llength ${startupitem.stop} ] } {
     179            set startupitem.stop [list "sh ${scriptdir}/${portname}.sh stop"]
     180        }
     181    }
     182    if { ![llength ${startupitem.requires} ] } {
     183        set startupitem.requires [list Disks NFS]
     184    }
     185    if { ![llength ${startupitem.logfile} ] } {
     186        set startupitem.logfile "/dev/null"
     187    }
     188   
     189    ########################
     190    # Create the startup item directory
     191    file mkdir ${startupItemDir}
     192    file attributes ${startupItemDir} -owner root -group wheel
     193   
     194    ########################
     195    # Generate the startup item script
     196    set item [open "${startupItemScript}" w 0755]
     197    file attributes "${startupItemScript}" -owner root -group wheel
     198   
     199    # Emit the header
     200    puts ${item} {#!/bin/sh
    201201#
    202202# MacPorts generated StartupItem
     
    204204
    205205}
    206         puts ${item} "prefix=$prefix"
    207         # Source the utilities package and the MacPorts config file
    208         puts ${item} {[ -r "/etc/rc.common" ] && . "/etc/rc.common"}
    209         puts ${item} {[ -r "${prefix}/etc/rc.conf" ] && . "${prefix}/etc/rc.conf"}
    210 
    211         # Emit the Configuration Section
    212         puts ${item} "NAME=${itemname}"
    213         puts ${item} "ENABLE_FLAG=\${${uppername}:=-NO-}"
    214         puts ${item} "PIDFILE=\"${pidFile}\""
    215         puts ${item} "LOGFILE=\"${startupitem.logfile}\""
    216         puts ${item} "EXECUTABLE=\"${startupitem.executable}\""
    217         puts ${item} ""
    218         puts ${item} "HAVE_STARTCMDS=[expr [llength ${startupitem.start}] ? "true" : "false"]"
    219         puts ${item} "HAVE_STOPCMDS=[expr [llength ${startupitem.stop}] ? "true" : "false"]"
    220         puts ${item} "HAVE_RESTARTCMDS=[expr [llength ${startupitem.restart}] ? "true" : "false"]"
    221         puts ${item} "DELETE_PIDFILE=${createPidFile}"
    222         puts ${item} "CREATE_PIDFILE=${deletePidFile}"
    223         puts ${item} "LOG_EVENTS=[expr [tbool ${startupitem.logevents}] ? "true" : "false"]"
    224         puts ${item} ""
    225 
    226         # Emit the init lines
    227         foreach line ${startupitem.init} { puts ${item} ${line} }
    228         puts ${item} ""
    229        
    230         # Emit the _Cmds
    231         foreach kind { start stop restart } {
    232                 if {[llength [set "startupitem.$kind"]]} {
    233                         puts ${item} "${kind}Cmds () \{"
    234                         foreach line [set "startupitem.$kind"] {
    235                                 puts ${item} "\t${line}"
    236                         }
    237                         puts ${item} "\}\n"
    238                 }
    239         }
    240        
    241         # vvvvv START BOILERPLATE vvvvvv
    242         # Emit the static boilerplate section
    243         puts ${item} {
     206    puts ${item} "prefix=$prefix"
     207    # Source the utilities package and the MacPorts config file
     208    puts ${item} {[ -r "/etc/rc.common" ] && . "/etc/rc.common"}
     209    puts ${item} {[ -r "${prefix}/etc/rc.conf" ] && . "${prefix}/etc/rc.conf"}
     210
     211    # Emit the Configuration Section
     212    puts ${item} "NAME=${itemname}"
     213    puts ${item} "ENABLE_FLAG=\${${uppername}:=-NO-}"
     214    puts ${item} "PIDFILE=\"${pidFile}\""
     215    puts ${item} "LOGFILE=\"${startupitem.logfile}\""
     216    puts ${item} "EXECUTABLE=\"${startupitem.executable}\""
     217    puts ${item} ""
     218    puts ${item} "HAVE_STARTCMDS=[expr [llength ${startupitem.start}] ? "true" : "false"]"
     219    puts ${item} "HAVE_STOPCMDS=[expr [llength ${startupitem.stop}] ? "true" : "false"]"
     220    puts ${item} "HAVE_RESTARTCMDS=[expr [llength ${startupitem.restart}] ? "true" : "false"]"
     221    puts ${item} "DELETE_PIDFILE=${createPidFile}"
     222    puts ${item} "CREATE_PIDFILE=${deletePidFile}"
     223    puts ${item} "LOG_EVENTS=[expr [tbool ${startupitem.logevents}] ? "true" : "false"]"
     224    puts ${item} ""
     225
     226    # Emit the init lines
     227    foreach line ${startupitem.init} { puts ${item} ${line} }
     228    puts ${item} ""
     229   
     230    # Emit the _Cmds
     231    foreach kind { start stop restart } {
     232        if {[llength [set "startupitem.$kind"]]} {
     233            puts ${item} "${kind}Cmds () \{"
     234            foreach line [set "startupitem.$kind"] {
     235                puts ${item} "\t${line}"
     236            }
     237            puts ${item} "\}\n"
     238        }
     239    }
     240   
     241    # vvvvv START BOILERPLATE vvvvvv
     242    # Emit the static boilerplate section
     243    puts ${item} {
    244244IsEnabled () {
    245         [ "${ENABLE_FLAG}" = "-YES-" ]
    246         return $?
     245    [ "${ENABLE_FLAG}" = "-YES-" ]
     246    return $?
    247247}
    248248
    249249CreatePIDFile () {
    250         echo $1 > "$PIDFILE"
     250    echo $1 > "$PIDFILE"
    251251}
    252252
    253253DeletePIDFile () {
    254         rm -f "$PIDFILE"
     254    rm -f "$PIDFILE"
    255255}
    256256
    257257ReadPID () {
    258         if [ -r "$PIDFILE" ]; then
    259                 read pid < "$PIDFILE"
    260         else
    261                 pid=0
    262         fi
    263         echo $pid
     258    if [ -r "$PIDFILE" ]; then
     259        read pid < "$PIDFILE"
     260    else
     261        pid=0
     262    fi
     263    echo $pid
    264264}
    265265
    266266CheckPID () {
    267         pid=$(ReadPID)
    268         if (($pid)); then
    269                 kill -0 $pid >& /dev/null || pid=0
    270         fi
    271         echo $pid
     267    pid=$(ReadPID)
     268    if (($pid)); then
     269        kill -0 $pid >& /dev/null || pid=0
     270    fi
     271    echo $pid
    272272}
    273273
    274274NoteEvent () {
    275         ConsoleMessage "$1"
    276         $LOG_EVENTS && [ -n "$LOGFILE" ] && echo "$(date) $NAME: $1" >> $LOGFILE
     275    ConsoleMessage "$1"
     276    $LOG_EVENTS && [ -n "$LOGFILE" ] && echo "$(date) $NAME: $1" >> $LOGFILE
    277277}
    278278
    279279StartService () {
    280         if IsEnabled; then
    281                 NoteEvent "Starting $NAME"
    282                
    283                 if $HAVE_STARTCMDS; then
    284                         startCmds
    285                 elif [ -n "$EXECUTABLE" ]; then
    286                         $EXECUTABLE &
    287                         pid=$!
    288                         if $CREATE_PIDFILE; then
    289                                 CreatePIDFile $pid
    290                         fi
    291                 fi
    292                
    293         fi
     280    if IsEnabled; then
     281        NoteEvent "Starting $NAME"
     282       
     283        if $HAVE_STARTCMDS; then
     284            startCmds
     285        elif [ -n "$EXECUTABLE" ]; then
     286            $EXECUTABLE &
     287            pid=$!
     288            if $CREATE_PIDFILE; then
     289                CreatePIDFile $pid
     290            fi
     291        fi
     292       
     293    fi
    294294}
    295295
    296296StopService () {
    297         NoteEvent "Stopping $NAME"
    298        
    299         gaveup=false
    300         if $HAVE_STOPCMDS; then
    301                 # If we have stop cmds, use them
    302                 stopCmds
    303         else           
    304                 # Otherwise, get the pid and try to stop the program
    305                 echo -n "Stopping $NAME..."
    306                
    307                 pid=$(CheckPID)
    308                 if (($pid)); then
    309                         # Try to kill the process with SIGTERM
    310                         kill $pid
    311                        
    312                         # Wait for it to really stop
    313                         for ((CNT=0; CNT < 15 && $(CheckPID); ++CNT)); do
    314                                 echo -n "."
    315                                 sleep 1
    316                         done
    317                        
    318                         # Report status
    319                         if (($(CheckPID))); then
    320                                 gaveup=true
    321                                 echo "giving up."
    322                         else
    323                                 echo "stopped."
    324                         fi
    325                 else
    326                         echo "it's not running."
    327                 fi
    328         fi
    329        
    330         # Cleanup the pidfile if we've been asked to
    331         if ! $gaveup && $DELETE_PIDFILE; then
    332                 DeletePIDFile
    333         fi
     297    NoteEvent "Stopping $NAME"
     298   
     299    gaveup=false
     300    if $HAVE_STOPCMDS; then
     301        # If we have stop cmds, use them
     302        stopCmds
     303    else       
     304        # Otherwise, get the pid and try to stop the program
     305        echo -n "Stopping $NAME..."
     306       
     307        pid=$(CheckPID)
     308        if (($pid)); then
     309            # Try to kill the process with SIGTERM
     310            kill $pid
     311           
     312            # Wait for it to really stop
     313            for ((CNT=0; CNT < 15 && $(CheckPID); ++CNT)); do
     314                echo -n "."
     315                sleep 1
     316            done
     317           
     318            # Report status
     319            if (($(CheckPID))); then
     320                gaveup=true
     321                echo "giving up."
     322            else
     323                echo "stopped."
     324            fi
     325        else
     326            echo "it's not running."
     327        fi
     328    fi
     329   
     330    # Cleanup the pidfile if we've been asked to
     331    if ! $gaveup && $DELETE_PIDFILE; then
     332        DeletePIDFile
     333    fi
    334334}
    335335
    336336RestartService () {
    337         if IsEnabled; then
    338                 NoteEvent "Restarting $NAME"
    339                
    340                 if $HAVE_RESTARTCMDS; then
    341                         # If we have restart cmds, use them
    342                         restartCmds
    343                 else
    344                         # Otherwise just stop/start it
    345                         StopService
    346                         StartService
    347                 fi
    348                
    349         fi
     337    if IsEnabled; then
     338        NoteEvent "Restarting $NAME"
     339       
     340        if $HAVE_RESTARTCMDS; then
     341            # If we have restart cmds, use them
     342            restartCmds
     343        else
     344            # Otherwise just stop/start it
     345            StopService
     346            StartService
     347        fi
     348       
     349    fi
    350350}
    351351
    352352RunService "$1"
    353353}
    354         # ^^^^^^ END BOILERPLATE ^^^^^^
    355        
    356         close ${item}
    357        
    358         ########################
    359         # Generate the plist
    360         set para [open "${startupItemPlist}" w 0644]
    361         file attributes "${startupItemPlist}" -owner root -group wheel
    362        
    363         puts ${para} "\{"
    364         puts ${para} "\tDescription\t= \"${itemname}\";"
    365         puts ${para} "\tProvides\t= (\"${itemname}\");"
    366         puts -nonewline ${para} "\tRequires\t= ("
    367         puts -nonewline ${para} [format {"%s"} [join ${startupitem.requires} {", "}]]
    368         puts ${para} ");"
    369         puts ${para} "\tOrderPreference\t= \"None\";"
    370         puts ${para} "\}"
    371         close ${para}
    372        
    373         # Emit some information for the user
    374         ui_msg "###########################################################"
    375         ui_msg "# A startup item has been generated that will aid in"
    376         ui_msg "# starting ${portname} with SystemStarter. It is disabled"
    377         ui_msg "# by default. Add the following line to /etc/hostconfig"
    378         ui_msg "# or ${prefix}/etc/rc.conf to start it at startup:"
    379         ui_msg "#"
    380         ui_msg "# ${uppername}=-YES-"
    381         ui_msg "###########################################################"
     354    # ^^^^^^ END BOILERPLATE ^^^^^^
     355   
     356    close ${item}
     357   
     358    ########################
     359    # Generate the plist
     360    set para [open "${startupItemPlist}" w 0644]
     361    file attributes "${startupItemPlist}" -owner root -group wheel
     362   
     363    puts ${para} "\{"
     364    puts ${para} "\tDescription\t= \"${itemname}\";"
     365    puts ${para} "\tProvides\t= (\"${itemname}\");"
     366    puts -nonewline ${para} "\tRequires\t= ("
     367    puts -nonewline ${para} [format {"%s"} [join ${startupitem.requires} {", "}]]
     368    puts ${para} ");"
     369    puts ${para} "\tOrderPreference\t= \"None\";"
     370    puts ${para} "\}"
     371    close ${para}
     372   
     373    # Emit some information for the user
     374    ui_msg "###########################################################"
     375    ui_msg "# A startup item has been generated that will aid in"
     376    ui_msg "# starting ${portname} with SystemStarter. It is disabled"
     377    ui_msg "# by default. Add the following line to /etc/hostconfig"
     378    ui_msg "# or ${prefix}/etc/rc.conf to start it at startup:"
     379    ui_msg "#"
     380    ui_msg "# ${uppername}=-YES-"
     381    ui_msg "###########################################################"
    382382}
    383383
    384384proc startupitem_create_darwin_launchd {args} {
    385         global UI_PREFIX prefix destroot destroot.keepdirs portname os.platform
    386         global startupitem.name startupitem.requires startupitem.init
    387         global startupitem.start startupitem.stop startupitem.restart startupitem.executable
    388         global startupitem.pidfile startupitem.logfile startupitem.logevents
    389 
    390         set scriptdir ${prefix}/etc/startup
    391        
    392         set itemname            ${startupitem.name}
    393         set uniquename          org.macports.${itemname}
    394         set plistname           ${uniquename}.plist
    395         set daemondest          LaunchDaemons
    396         set itemdir                     ${prefix}/etc/${daemondest}/${uniquename}
    397         set args                        [list \
    398                                                         "${prefix}/bin/daemondo" \
    399                                                         "--label=${itemname}" \
    400                                                         ]
    401        
    402         file mkdir ${destroot}${itemdir}
    403         file attributes ${destroot}${itemdir} -owner root -group wheel
    404                
    405         if { [llength ${startupitem.executable}] &&
    406                         ![llength ${startupitem.init}] &&
    407                         ![llength ${startupitem.start}] &&
    408                         ![llength ${startupitem.stop}] &&
    409                         ![llength ${startupitem.restart}] } {
    410                        
    411                 # An executable is specified, and there is no init, start, stop, or restart
    412                 # code; so we don't need a wrapper script
    413                 set args [concat $args "--start-cmd" ${startupitem.executable} ";"]
    414                
    415         } else {
    416        
    417                 # No executable was specified, or there was an init, start, stop, or restart
    418                 # option, so we do need a wrapper script
    419                
    420                 set wrappername         ${itemname}.wrapper
    421                 set wrapper                     "${itemdir}/${wrappername}"
    422 
    423                 if { ![llength ${startupitem.start}] } {
    424                         set startupitem.start [list "sh ${scriptdir}/${portname}.sh start"]
    425                 }
    426                 if { ![llength ${startupitem.stop}] } {
    427                         set startupitem.stop [list "sh ${scriptdir}/${portname}.sh stop"]
    428                 }
    429                 if { ![llength ${startupitem.restart}] } {
    430                         set startupitem.restart [list Stop Start]
    431                 }
    432 
    433                 lappend args \
    434                         "--start-cmd"   ${wrapper} start   ";" \
    435                         "--stop-cmd"    ${wrapper} stop    ";" \
    436                         "--restart-cmd" ${wrapper} restart ";"
    437 
    438                 # Create the wrapper script
    439                 set item [open "${destroot}${wrapper}" w 0755]
    440                 file attributes "${destroot}${wrapper}" -owner root -group wheel
    441 
    442                 puts ${item} "#!/bin/sh"
    443                 puts ${item} "#"
    444                 puts ${item} "# MacPorts generated daemondo support script"
    445                 puts ${item} "#"
    446                 puts ${item} ""
    447                
    448                 puts ${item} "#"
    449                 puts ${item} "# Init"
    450                 puts ${item} "#"
    451                 puts ${item} "prefix=$prefix"
    452                 foreach line ${startupitem.init}        { puts ${item} ${line} }
    453                 puts ${item} ""
    454 
    455                 puts ${item} "#"
    456                 puts ${item} "# Start"
    457                 puts ${item} "#"
    458                 puts ${item} "Start()"
    459                 puts ${item} "\{"
    460                 foreach line ${startupitem.start}       { puts ${item} "\t${line}" }
    461                 puts ${item} "\}"
    462                 puts ${item} ""
    463                
    464                 puts ${item} "#"
    465                 puts ${item} "# Stop"
    466                 puts ${item} "#"
    467                 puts ${item} "Stop()"
    468                 puts ${item} "\{"
    469                 foreach line ${startupitem.stop}        { puts ${item} "\t${line}" }
    470                 puts ${item} "\}"
    471                 puts ${item} ""
    472        
    473                 puts ${item} "#"
    474                 puts ${item} "# Restart"
    475                 puts ${item} "#"
    476                 puts ${item} "Restart()"
    477                 puts ${item} "\{"
    478                 foreach line ${startupitem.restart} { puts ${item} "\t${line}" }
    479                 puts ${item} "\}"
    480                 puts ${item} ""
    481 
    482                 puts ${item} "#"
    483                 puts ${item} "# Run"
    484                 puts ${item} "#"
    485                 puts ${item} "Run()"
    486                 puts ${item} "\{"
    487                 puts ${item} "case \$1 in"
    488                 puts ${item} "  start  ) Start   ;;"
    489                 puts ${item} "  stop   ) Stop    ;;"
    490                 puts ${item} "  restart) Restart ;;"
    491                 puts ${item} "  *      ) echo \"\$0: unknown argument: \$1\";;"
    492                 puts ${item} "esac"
    493                 puts ${item} "\}"
    494                 puts ${item} ""
    495 
    496                 puts ${item} "#"
    497                 puts ${item} "# Run a phase based on the selector"
    498                 puts ${item} "#"
    499                 puts ${item} "Run \$1"
    500                 puts ${item} ""
    501 
    502                 close ${item}
    503         }
    504                
    505         # To log events then tell daemondo to log at verbosity=1
    506         if { [tbool startupitem.logevents] } {
    507                 lappend args "--verbosity=1"
    508         }
    509        
    510         # If pidfile was specified, translate it for daemondo.
    511         #
    512         # There are four cases:
    513         #       (1) none
    514         #       (2) auto [pidfilename]
    515         #       (3) cleanup [pidfilename]
    516         #       (4) manual [pidfilename]
    517         #
    518         set pidfileArgCnt [llength ${startupitem.pidfile}]
    519         if { ${pidfileArgCnt} > 0 } {
    520                 if { $pidfileArgCnt == 1 } {
    521                         set pidFile "${prefix}/var/run/${itemname}.pid"
    522                         lappend destroot.keepdirs "${destroot}${prefix}/var/run"
    523                 } else {
    524                         set pidFile [lindex ${startupitem.pidfile} 1]
    525                 }
    526 
    527                 if { ${pidfileArgCnt} > 2 } {
    528                         ui_error "$UI_PREFIX [msgcat::mc "Invalid parameter count to startupitem.pidfile: 2 expected, %d found" ${pidfileArgCnt}]"
    529                 }
    530                
    531                 # Translate into appropriate arguments to daemondo
    532                 set pidStyle [lindex ${startupitem.pidfile} 0]
    533                 switch ${pidStyle} {
    534                         none    { lappend args "--pid=none" }
    535                         auto    { lappend args "--pid=fileauto" "--pidfile" ${pidFile} }
    536                         clean   { lappend args "--pid=fileclean" "--pidfile" ${pidFile} }
    537                         manual  { lappend args "--pid=exec" "--pidfile" ${pidFile} }
    538                         default {
    539                                 ui_error "$UI_PREFIX [msgcat::mc "Unknown pidfile style %s presented to startupitem.pidfile" ${pidStyle}]"
    540                         }
    541                 }
    542         } else {
    543                 if { [llength ${startupitem.executable}] } {
    544                         lappend args "--pid=exec"
    545                 } else {
    546                         lappend args "--pid=none"
    547                 }
    548         }
    549        
    550         # Create the plist file
    551         set plist [open "${destroot}${itemdir}/${plistname}" w 0644]
    552        
    553         puts ${plist} "<?xml version='1.0' encoding='UTF-8'?>"
    554         puts ${plist} "<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN"
    555         puts ${plist} "http://www.apple.com/DTDs/PropertyList-1.0.dtd >"
    556         puts ${plist} "<plist version='1.0'>"
    557         puts ${plist} "<dict>"
    558        
    559         puts ${plist} "<key>Label</key><string>${uniquename}</string>"
    560        
    561         puts ${plist} "<key>ProgramArguments</key>"
    562         puts ${plist} "<array>"
    563         foreach arg ${args} { puts ${plist} "\t<string>${arg}</string>" }
    564         puts ${plist} "</array>"
    565        
    566         puts ${plist} "<key>Debug</key><false/>"
    567         puts ${plist} "<key>Disabled</key><true/>"
    568         puts ${plist} "<key>OnDemand</key><false/>"
    569         puts ${plist} "<key>RunAtLoad</key><false/>"
    570        
    571         if { [llength ${startupitem.logfile}] } {
    572                 puts ${plist} "<key>StandardOutPath</key><string>${startupitem.logfile}</string>"
    573         }
    574        
    575         puts ${plist} "</dict>"
    576         puts ${plist} "</plist>"
    577 
    578         close ${plist}
    579 
    580         # Make a symlink to the plist file
    581         file mkdir "${destroot}/Library/${daemondest}"
    582         system "cd ${destroot}/Library/${daemondest} && ln -sf ${itemdir}/${plistname}"
    583        
    584         # If launchd is not available, warn the user
    585         set haveLaunchd ${portutil::autoconf::have_launchd}
    586         if {![tbool haveLaunchd]} {
    587                 ui_msg "###########################################################"
    588                 ui_msg "# WARNING:"
    589                 ui_msg "# We're building a launchd startup item, but launchd wasn't"
    590                 ui_msg "# found by configure. Are you sure you didn't mess up your"
    591                 ui_msg "# ports.conf settings?"
    592                 ui_msg "###########################################################"
    593         }
    594        
    595         # Emit some information for the user
    596         ui_msg "###########################################################"
    597         ui_msg "# A startup item has been generated that will aid in"
    598         ui_msg "# starting ${portname} with launchd. It is disabled"
    599         ui_msg "# by default. Execute the following command to start it,"
    600         ui_msg "# and to cause it to launch at startup:"
    601         ui_msg "#"
    602         ui_msg "# sudo launchctl load -w /Library/${daemondest}/${plistname}"
    603         ui_msg "###########################################################"
     385    global UI_PREFIX prefix destroot destroot.keepdirs portname os.platform
     386    global startupitem.name startupitem.requires startupitem.init
     387    global startupitem.start startupitem.stop startupitem.restart startupitem.executable
     388    global startupitem.pidfile startupitem.logfile startupitem.logevents
     389
     390    set scriptdir ${prefix}/etc/startup
     391   
     392    set itemname        ${startupitem.name}
     393    set uniquename      org.macports.${itemname}
     394    set plistname       ${uniquename}.plist
     395    set daemondest      LaunchDaemons
     396    set itemdir         ${prefix}/etc/${daemondest}/${uniquename}
     397    set args            [list \
     398                            "${prefix}/bin/daemondo" \
     399                            "--label=${itemname}" \
     400                            ]
     401   
     402    file mkdir ${destroot}${itemdir}
     403    file attributes ${destroot}${itemdir} -owner root -group wheel
     404       
     405    if { [llength ${startupitem.executable}] &&
     406            ![llength ${startupitem.init}] &&
     407            ![llength ${startupitem.start}] &&
     408            ![llength ${startupitem.stop}] &&
     409            ![llength ${startupitem.restart}] } {
     410           
     411        # An executable is specified, and there is no init, start, stop, or restart
     412        # code; so we don't need a wrapper script
     413        set args [concat $args "--start-cmd" ${startupitem.executable} ";"]
     414       
     415    } else {
     416   
     417        # No executable was specified, or there was an init, start, stop, or restart
     418        # option, so we do need a wrapper script
     419       
     420        set wrappername     ${itemname}.wrapper
     421        set wrapper         "${itemdir}/${wrappername}"
     422
     423        if { ![llength ${startupitem.start}] } {
     424            set startupitem.start [list "sh ${scriptdir}/${portname}.sh start"]
     425        }
     426        if { ![llength ${startupitem.stop}] } {
     427            set startupitem.stop [list "sh ${scriptdir}/${portname}.sh stop"]
     428        }
     429        if { ![llength ${startupitem.restart}] } {
     430            set startupitem.restart [list Stop Start]
     431        }
     432
     433        lappend args \
     434            "--start-cmd"   ${wrapper} start   ";" \
     435            "--stop-cmd"    ${wrapper} stop    ";" \
     436            "--restart-cmd" ${wrapper} restart ";"
     437
     438        # Create the wrapper script
     439        set item [open "${destroot}${wrapper}" w 0755]
     440        file attributes "${destroot}${wrapper}" -owner root -group wheel
     441
     442        puts ${item} "#!/bin/sh"
     443        puts ${item} "#"
     444        puts ${item} "# MacPorts generated daemondo support script"
     445        puts ${item} "#"
     446        puts ${item} ""
     447       
     448        puts ${item} "#"
     449        puts ${item} "# Init"
     450        puts ${item} "#"
     451        puts ${item} "prefix=$prefix"
     452        foreach line ${startupitem.init}    { puts ${item} ${line} }
     453        puts ${item} ""
     454
     455        puts ${item} "#"
     456        puts ${item} "# Start"
     457        puts ${item} "#"
     458        puts ${item} "Start()"
     459        puts ${item} "\{"
     460        foreach line ${startupitem.start}   { puts ${item} "\t${line}" }
     461        puts ${item} "\}"
     462        puts ${item} ""
     463       
     464        puts ${item} "#"
     465        puts ${item} "# Stop"
     466        puts ${item} "#"
     467        puts ${item} "Stop()"
     468        puts ${item} "\{"
     469        foreach line ${startupitem.stop}    { puts ${item} "\t${line}" }
     470        puts ${item} "\}"
     471        puts ${item} ""
     472   
     473        puts ${item} "#"
     474        puts ${item} "# Restart"
     475        puts ${item} "#"
     476        puts ${item} "Restart()"
     477        puts ${item} "\{"
     478        foreach line ${startupitem.restart} { puts ${item} "\t${line}" }
     479        puts ${item} "\}"
     480        puts ${item} ""
     481
     482        puts ${item} "#"
     483        puts ${item} "# Run"
     484        puts ${item} "#"
     485        puts ${item} "Run()"
     486        puts ${item} "\{"
     487        puts ${item} "case \$1 in"
     488        puts ${item} "  start  ) Start   ;;"
     489        puts ${item} "  stop   ) Stop    ;;"
     490        puts ${item} "  restart) Restart ;;"
     491        puts ${item} "  *      ) echo \"\$0: unknown argument: \$1\";;"
     492        puts ${item} "esac"
     493        puts ${item} "\}"
     494        puts ${item} ""
     495
     496        puts ${item} "#"
     497        puts ${item} "# Run a phase based on the selector"
     498        puts ${item} "#"
     499        puts ${item} "Run \$1"
     500        puts ${item} ""
     501
     502        close ${item}
     503    }
     504       
     505    # To log events then tell daemondo to log at verbosity=1
     506    if { [tbool startupitem.logevents] } {
     507        lappend args "--verbosity=1"
     508    }
     509   
     510    # If pidfile was specified, translate it for daemondo.
     511    #
     512    # There are four cases:
     513    #   (1) none
     514    #   (2) auto [pidfilename]
     515    #   (3) cleanup [pidfilename]
     516    #   (4) manual [pidfilename]
     517    #
     518    set pidfileArgCnt [llength ${startupitem.pidfile}]
     519    if { ${pidfileArgCnt} > 0 } {
     520        if { $pidfileArgCnt == 1 } {
     521            set pidFile "${prefix}/var/run/${itemname}.pid"
     522            lappend destroot.keepdirs "${destroot}${prefix}/var/run"
     523        } else {
     524            set pidFile [lindex ${startupitem.pidfile} 1]
     525        }
     526
     527        if { ${pidfileArgCnt} > 2 } {
     528            ui_error "$UI_PREFIX [msgcat::mc "Invalid parameter count to startupitem.pidfile: 2 expected, %d found" ${pidfileArgCnt}]"
     529        }
     530       
     531        # Translate into appropriate arguments to daemondo
     532        set pidStyle [lindex ${startupitem.pidfile} 0]
     533        switch ${pidStyle} {
     534            none    { lappend args "--pid=none" }
     535            auto    { lappend args "--pid=fileauto" "--pidfile" ${pidFile} }
     536            clean   { lappend args "--pid=fileclean" "--pidfile" ${pidFile} }
     537            manual  { lappend args "--pid=exec" "--pidfile" ${pidFile} }
     538            default {
     539                ui_error "$UI_PREFIX [msgcat::mc "Unknown pidfile style %s presented to startupitem.pidfile" ${pidStyle}]"
     540            }
     541        }
     542    } else {
     543        if { [llength ${startupitem.executable}] } {
     544            lappend args "--pid=exec"
     545        } else {
     546            lappend args "--pid=none"
     547        }
     548    }
     549   
     550    # Create the plist file
     551    set plist [open "${destroot}${itemdir}/${plistname}" w 0644]
     552   
     553    puts ${plist} "<?xml version='1.0' encoding='UTF-8'?>"
     554    puts ${plist} "<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN"
     555    puts ${plist} "http://www.apple.com/DTDs/PropertyList-1.0.dtd >"
     556    puts ${plist} "<plist version='1.0'>"
     557    puts ${plist} "<dict>"
     558   
     559    puts ${plist} "<key>Label</key><string>${uniquename}</string>"
     560   
     561    puts ${plist} "<key>ProgramArguments</key>"
     562    puts ${plist} "<array>"
     563    foreach arg ${args} { puts ${plist} "\t<string>${arg}</string>" }
     564    puts ${plist} "</array>"
     565   
     566    puts ${plist} "<key>Debug</key><false/>"
     567    puts ${plist} "<key>Disabled</key><true/>"
     568    puts ${plist} "<key>OnDemand</key><false/>"
     569    puts ${plist} "<key>RunAtLoad</key><false/>"
     570   
     571    if { [llength ${startupitem.logfile}] } {
     572        puts ${plist} "<key>StandardOutPath</key><string>${startupitem.logfile}</string>"
     573    }
     574   
     575    puts ${plist} "</dict>"
     576    puts ${plist} "</plist>"
     577
     578    close ${plist}
     579
     580    # Make a symlink to the plist file
     581    file mkdir "${destroot}/Library/${daemondest}"
     582    system "cd ${destroot}/Library/${daemondest} && ln -sf ${itemdir}/${plistname}"
     583   
     584    # If launchd is not available, warn the user
     585    set haveLaunchd ${portutil::autoconf::have_launchd}
     586    if {![tbool haveLaunchd]} {
     587        ui_msg "###########################################################"
     588        ui_msg "# WARNING:"
     589        ui_msg "# We're building a launchd startup item, but launchd wasn't"
     590        ui_msg "# found by configure. Are you sure you didn't mess up your"
     591        ui_msg "# ports.conf settings?"
     592        ui_msg "###########################################################"
     593    }
     594   
     595    # Emit some information for the user
     596    ui_msg "###########################################################"
     597    ui_msg "# A startup item has been generated that will aid in"
     598    ui_msg "# starting ${portname} with launchd. It is disabled"
     599    ui_msg "# by default. Execute the following command to start it,"
     600    ui_msg "# and to cause it to launch at startup:"
     601    ui_msg "#"
     602    ui_msg "# sudo launchctl load -w /Library/${daemondest}/${plistname}"
     603    ui_msg "###########################################################"
    604604}
    605605
    606606proc startupitem_create {args} {
    607         global UI_PREFIX
    608         global startupitem.type os.platform
    609        
    610         set startupitem.type [string tolower ${startupitem.type}]
    611        
    612         # Calculate a default value for startupitem.type
    613         if {${startupitem.type} == "default" || ${startupitem.type} == ""} {
    614                 switch -exact ${os.platform} {
    615                         darwin {
    616                                 set haveLaunchd ${portutil::autoconf::have_launchd}
    617                                 if { [tbool haveLaunchd] } {
    618                                         set startupitem.type "launchd"
    619                                 } else {
    620                                         set startupitem.type "systemstarter"
    621                                 }
    622                         }
    623                         default {
    624                                 set startupitem.type "rcng"
    625                         }
    626                 }
    627         }
    628 
    629         ui_msg "$UI_PREFIX [msgcat::mc "Creating ${startupitem.type} control script"]"
    630 
    631         switch -- ${startupitem.type} {
    632                 launchd                 { startupitem_create_darwin_launchd }
    633                 systemstarter   { startupitem_create_darwin_systemstarter }
    634                 rcng                    { startupitem_create_rcng }
    635                 default                 { ui_error "$UI_PREFIX [msgcat::mc "Unrecognized startupitem type %s" ${startupitem.type}]" }
    636         }
    637 }
     607    global UI_PREFIX
     608    global startupitem.type os.platform
     609   
     610    set startupitem.type [string tolower ${startupitem.type}]
     611   
     612    # Calculate a default value for startupitem.type
     613    if {${startupitem.type} == "default" || ${startupitem.type} == ""} {
     614        switch -exact ${os.platform} {
     615            darwin {
     616                set haveLaunchd ${portutil::autoconf::have_launchd}
     617                if { [tbool haveLaunchd] } {
     618                    set startupitem.type "launchd"
     619                } else {
     620                    set startupitem.type "systemstarter"
     621                }
     622            }
     623            default {
     624                set startupitem.type "rcng"
     625            }
     626        }
     627    }
     628
     629    ui_msg "$UI_PREFIX [msgcat::mc "Creating ${startupitem.type} control script"]"
     630
     631    switch -- ${startupitem.type} {
     632        launchd         { startupitem_create_darwin_launchd }
     633        systemstarter   { startupitem_create_darwin_systemstarter }
     634        rcng            { startupitem_create_rcng }
     635        default         { ui_error "$UI_PREFIX [msgcat::mc "Unrecognized startupitem type %s" ${startupitem.type}]" }
     636    }
     637}
     638
Note: See TracChangeset for help on using the changeset viewer.