Numeric Illustration

perl-dyndns as a solaris service

Posted in Uncategorized by elevatorboy on October 4, 2011

I’ve switched a few things around at home and now my old way of doing dyndns won’t work for me. So I finally got a script based dyndns update client working. It was a close shave as I was able to download the SunStudeoExpress suite just before Oracle shut down the OpenSolaris pkg repo that I was using (I’m still running 134 but when I update to illumos/openindianna I’ll update this). Anyway, now CPAN works and I was able to build the prereqs for this nifty dyndns client written in perl.

But being a fan of SMF and wanting to do things the “right” way on Solaris, just adding a cron job myself wasn’t enough, so I went ahead and made adding the cron job an smf service.

Here’s the manifest and the method script. I clearly borrowed some ideas from the zfs snapshot service. Again, thanks Tim I still like zfs snapshot more than timeslider.

First the Method script. Don’t hate me because I like bash. Its probably technically supposed to be bourne shell or ksh93 for OpenSolaris. So much for doing it “right”.
Method:

#!/bin/bash -x
# I left it in -x mode to have entries in the service log.  This is optional

. /lib/svc/share/smf_include.sh

getproparg() {
  val=`svcprop -p $1 $SMF_FMRI`
  [ -n "$val" ] && echo $val
} 

# just in case
export PATH=/usr/bin:${PATH}

if [ -z "$SMF_FMRI" ]
then
  echo "SMF framework variables are not initialized."
  exit $SMF_EXIT_ERR
fi

PERLDYNDNSBIN='/opt/perl-dyndns/bin/dyndns.pl'
PERL='/usr/bin/perl'

CONFIG_FILE=`getproparg perl-dyndns/config_file`

if [ -z "$CONFIG_FILE" ]
then
  echo "perl-dyndns/config_file property not set"
  exit $SMF_EXIT_ERR_CONFIG
fi

case "$1" in
  'start')
    $PERL $PERLDYNDNSBIN --Config $CONFIG_FILE
    crontab -l > /tmp/saved-crontab.$$
    echo "0 6 * * * $PERL ${PERLDYNDNSBIN} --Config ${CONFIG_FILE}" >> /tmp/saved-crontab.$$
    crontab /tmp/saved-crontab.$$
    retval=$?
    if [[ ! $retval -eq 0 ]]
    then
      echo "WARNING - error adding cronjob"
      rm /tmp/saved-crontab.$$
      exit 1
    fi

    ;; 

  'stop')
    # removing a cron job is essentially just looking for an existing entry,
    # removing it, and reading the leftovers back to crontab
    crontab -l | grep -v "${PERLDYNDNSBIN}" > /tmp/saved-crontab.$$
    crontab /tmp/saved-crontab.$$
    #check_failure $? "Unable to remove cron job!"
    retval=$?
    if [[ ! $retval -eq 0 ]]
    then
      echo "WARNING - error removing cronjob"
      rm /tmp/saved-crontab.$$
      exit 1
    fi

    ;; 

  'refresh')
    echo "not implemented yet, not sure if it can be"
    ;; 

  *)
    echo "I don't understand that option, try one of these:"
    echo "Usage: $0 {start|stop|refresh}"
    exit 1
    ;;
esac 

exit $SMF_EXIT_OK

and now the manifest. I hosed it a few times until I remembered that you have to specify transient for things that you want to not run as a daemon, else smf will try to restart it, detect that its failing a lot, and put it in maintenance.

Manifest:

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">

<service_bundle 
  type="manifest" 
  name="perl-dyndns">

  <service 
    name="application/network/perl-dyndns" 
    type="service" 
    version="1">
    
    <dependency 
      name="network" 
      grouping="require_all" 
      restart_on="none" 
      type="service">
      <service_fmri 
        value="svc:/milestone/network:default"/>
    </dependency>
    
    <exec_method 
      type="method" 
      name="start" 
      exec="/lib/svc/method/perl-dyndns.sh %m" 
      timeout_seconds='0'/>
    <exec_method 
      type="method" 
      name="stop" 
      exec="/lib/svc/method/perl-dyndns.sh %m" 
      timeout_seconds='0'>
    </exec_method>

          <property_group name='startd' type='framework'>
                  <propval name='duration' type='astring' value='transient' />
          </property_group>

    <instance 
      name="config-file" 
      enabled="false">
      <method_context>
        <method_credential 
          user="root" 
          group="root"/>
      </method_context>
      <property_group 
        name="perl-dyndns" 
        type="application">
        <propval 
          name="config_file" 
          type="astring" 
          value="/etc/opt/perl-dyndns/dyndns-dynamic.conf" />
      </property_group>
    </instance>

    <stability 
      value="Evolving"/>

    <template>
      <common_name>
        <loctext xml:lang="C">perl-dydndns</loctext>
      </common_name>
      <description>
        <loctext xml:lang="C">
       Perl dyndns - A Perl Dynamic DNS (DDNS) update client
-----------------------------------------------------
Map dynamic IP address into your.hostname.example.org. A
cross-platform solution for DHCP ISP-connected users to obtain
permanent DNS, MX, and Web hosting service from a DDNS provider (e.g.
dyndns.org). Works anywhere where Perl is installed.

Requirements

        Extra Perl CPAN modules need to be install before program
        can be used:

            HTTP::Request::Common
            HTTP::Headers
            LWP::UserAgent
            LWP::Simple
            Sys::Syslog

        You can install these one by one with perl command:

            perl -MCPAN -e shell
            at cpan prompt install module name

        External commands needed:

            ipconfig            (Under WIndows)
            ifconfig            (Under POSIX compliant OS)

        </loctext>
      </description>
      <documentation>
        <doc_link 
          name="Perl Dynamic DNS (DDNS) Update Client"
          uri="https://savannah.nongnu.org/projects/perl-dyndns" />
      </documentation>
    </template>
  </service>
</service_bundle>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: