Example: Installing a NetApp Simulator

The following extract demonstrates how to install a NetApp simulator into a target Linux host. The software tarball has already been uploaded to the remote host, and ssh keys configured for passwordless login.

The changes install the software as a clustered pair (rather than a standalone, single node install). Each node is then configured to a base level with hostname, IP address, gateway address, etc.

Three changes are chained together using dependencies, and an iterator is used to run the first two changes twice, once for each node in a cluster. This use of parameterised changes reduces the amount of code required.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Modipy definitions for installing a NetApp simulator onto
     a remote Linux box. Assumes the simulator software has
     already been loaded onto the remote server
-->

<config>

  <!-- define my provisioner -->

  <provisioner
      name="command_prov1"
      module="modipy.provisioner_command"
      type="ConnectingProvisioner">
    <command_timeout>30</command_timeout>
    <connect_command>ssh -t -i /home/daedalus/.ssh/localconnect root@%(device.ipaddress)s</connect_command>
  </provisioner>

  <!-- define some devices I want to provision to. Split this out later. -->
  <device name="netappsimhost">
    <ipaddress>192.168.8.71</ipaddress>
  </device>

  <!-- Some global variables that are used by multiple changes -->
  <namespace>
    <entry name="sim_src_dir">/home/daedalus/simulator-7.2.4</entry>
    <entry name="sim_install_dir">/sim/test-install</entry>
  </namespace>
    
  <!-- Variables for the 2 nodes of a sim cluster -->
  <iterator name="netapp_sim_cluster">
    <dict>
      <entry name="node">node1</entry>    

      <entry name="node_hostname">simtest01a</entry>
      <entry name="node_ns0_ipaddr">192.168.8.110</entry>
      <entry name="node_ns0_netmask">255.255.255.0</entry>

      <entry name="sim_default_gw">192.168.8.1</entry>
      <entry name="sim_admin_host">192.168.8.3</entry>
      <entry name="sim_timezone">Australia/Melbourne</entry>
      <entry name="sim_location">eigenlab</entry>
      <entry name="sim_language">en</entry>
      <entry name="sim_admin_passwd">netapp1</entry>
      <entry name="sim_workgroup">EIGENLAB</entry>
      <entry name="cluster_license">JQIGWWF</entry>
      
      <entry name="ssl_country">AU</entry>
      <entry name="ssl_state">VIC</entry>
      <entry name="ssl_locality">Melbourne</entry>
      <entry name="ssl_domain">melbourne.eigenmagic.net</entry>
      <entry name="ssl_org">eigenmagic.com</entry>
      <entry name="ssl_unit">eigenlab</entry>
      <entry name="ssl_contact_email">justin@eigenmagic.com</entry>
      <entry name="ssl_keysize">1024</entry>
      <entry name="ssl_expiredays">5524</entry>
    </dict>

    <dict>
      <entry name="node">node2</entry>    

      <entry name="sim_src_dir">/home/daedalus/simulator-7.2.4</entry>
      <entry name="sim_install_dir">/sim/test-install</entry>

      <entry name="node_hostname">simtest01b</entry>
      <entry name="node_ns0_ipaddr">192.168.8.111</entry>
      <entry name="node_ns0_netmask">255.255.255.0</entry>

      <entry name="sim_default_gw">192.168.8.100</entry>
      <entry name="sim_admin_host">192.168.8.3</entry>
      <entry name="sim_timezone">Australia/Melbourne</entry>
      <entry name="sim_location">eigenlab</entry>
      <entry name="sim_language">en</entry>
      <entry name="sim_admin_passwd">netapp1</entry>
      <entry name="sim_workgroup">EIGENLAB</entry>
      <entry name="cluster_license">JQIGWWF</entry>
      
      <entry name="ssl_country">AU</entry>
      <entry name="ssl_state">VIC</entry>
      <entry name="ssl_city">Melbourne</entry>
      <entry name="ssl_domain">melbourne.eigenmagic.net</entry>
      <entry name="ssl_location">eigenlab</entry>
      <entry name="ssl_contact_email">justin@eigenmagic.com</entry>
      <entry name="ssl_keysize">1024</entry>
      <entry name="ssl_expiredays">5524</entry>
    </dict>

  </iterator>

  <!-- Define the changes I want to apply -->

  <!--
      This change defines how to install the simulator software
      as a clustered pair of nodes, ready for configuration.
    -->
  <change name="install_sim_cluster"
	  module="modipy.change_command" type="CommandChange">

    <target name="netappsimhost"/>

    <impl>
      <command>
        <send>cd %(sim_src_dir)s</send>
      </command>
      <command>
        <send>./setup.sh 2>&amp;1</send>
      </command>

      <!-- set where to install simulator to -->
      <command>
        <expect>install to?</expect>
        <send>%(sim_install_dir)s</send>
      </command>

      <!-- set clustered mode to yes -->
      <command>
        <expect>cluster?</expect>
        <send>yes</send>
      </command>

      <!-- continue with installation? well, duh -->
      <command>
        <expect>installation?</expect>
        <send>yes</send>
      </command>

      <!-- Add some disks -->
      <command>
        <!-- Wait 5 minutes for data unpack to finish -->
        <expect timeout="600">like to add?</expect>
        <send>20</send>
      </command>

      <!-- How big? Size f == 1024meg -->
      <command>
        <expect>like to use?</expect>
        <send>f</send>
      </command>

      <!-- Disk adapter -->
      <command>
        <expect>disks on?</expect>
        <send>0</send>
      </command>

      <!-- Use DHCP? nope -->
      <command>
        <expect>first boot?</expect>
        <send>no</send>
      </command>

      <!-- Floppy boot? -->
      <command>
        <expect>floppy boot?</expect>
        <send>no</send>
      </command>

      <!-- interface to use? Just use the default -->
      <command>
        <expect>simulator use?</expect>
        <send>
</send>
      </command>

      <!-- How much memory to use? -->
      <command>
        <expect>simulator to use?</expect>
        <send>512</send>
      </command>

      <!-- New log each session? -->
      <command>
        <expect>session?</expect>
        <send>no</send>
      </command>

      <!-- Overwrite log each time -->
      <command>
        <expect>each time?</expect>
        <send>yes</send>
      </command>

      <command>
        <expect timeout="60">Complete</expect>
        <send>logout</send>
      </command>

    </impl>

    <backout>
      <command>
        <!-- Wait for a command prompt, then nuke the installation -->
        <expect>~#</expect>
        <send>rm -r %(sim_install_dir)s</send>
      </command>

      <command>
        <expect>~#</expect>
        <send>logout</send>
      </command>

    </backout>

  </change>

  <!-- Configure the sim to a given baseline config -->
  <change name="configure_sim_baseline_node" iterator="netapp_sim_cluster"
	  module="modipy.change_command" type="CommandChange">

    <target name="netappsimhost"/>

    <prereq>install_sim_cluster</prereq>

    <preimpl>
      <command>
        <expect>~#</expect>
      </command>
    </preimpl>

    <impl>
      <command>
        <send>%(sim_install_dir)s/%(node)s/runsim.sh</send>
      </command>

      <!-- set hostname -->
      <command>
        <!-- It might take a while for the sim to start up -->
        <expect timeout="600">new hostname</expect>
        <send>%(node_hostname)s</send>
      </command>

      <!-- virtual interfaces? no -->
      <command>
        <expect>virtual network interfaces?</expect>
        <send>no</send>
      </command>

      <!-- IP address for ns0 -->
      <command>
        <expect>ns0</expect>
        <send>%(node_ns0_ipaddr)s</send>
      </command>

      <!-- netmask for ns0 -->
      <command>
        <expect>]:</expect>
        <send>%(node_ns0_netmask)s</send>
      </command>

      <!-- partner takeover? -->
      <command>
        <expect>]:</expect>
        <send>y</send>
      </command>

      <!-- IP or interface to takeover. Use default. -->
      <command>
        <expect>ns0</expect>
        <send></send>
      </command>

      <!-- IP for ns1. None -->
      <command>
        <expect>ns1</expect>
        <send></send>
      </command>

      <!-- Partner takeover for ns1? No -->
      <command>
        <expect>]:</expect>
        <send>n</send>
      </command>

      <!-- Continue through web interface? No -->
      <command>
        <expect>web interface?</expect>
        <send>n</send>
      </command>

      <!-- Default gateway IP address -->
      <command>
        <expect>default gateway</expect>
        <send>%(sim_default_gw)s</send>
      </command>

      <!-- Sim admin host -->
      <command>
        <expect>administration host:</expect>
        <send>%(sim_admin_host)s</send>
      </command>

      <!-- timezone -->
      <command>
        <expect>timezone</expect>
        <send>%(sim_timezone)s</send>
      </command>

      <!-- location -->
      <command>
        <expect>filer located?</expect>
        <send>%(sim_location)s</send>
      </command>

      <!-- language -->
      <command>
        <expect>multi-protocol files</expect>
        <send>%(sim_language)s</send>
      </command>

      <!-- DNS resolver? -->
      <command>
        <expect>DNS resolver?</expect>
        <send>n</send>
      </command>

      <!-- NIS client? -->
      <command>
        <expect>NIS client?</expect>
        <send>n</send>
      </command>

      <!-- admin password -->
      <command>
        <expect>New password:</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>

      <command>
        <expect>Retype new password:</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>

      <!-- Visible via WINS? n -->
      <command>
        <expect>WINS?</expect>
        <send>n</send>
      </command>

      <!-- Multi-protocol filer? -->
      <command>
        <expect>Selection</expect>
        <send>1</send>
      </command>

      <!-- CIFS password -->
      <command>
        <expect>root user</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>
      <command>
        <expect>Retype the password:</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>

      <!-- CIFS name -->
      <command>
        <expect>change this name?</expect>
        <send>n</send>
      </command>

      <!-- CIFS user authentication. We'll just use /etc/passwd -->
      <command>
        <expect>Selection</expect>
        <send>4</send>
      </command>

      <!-- CIFS workgroup -->
      <command>
        <expect>Workgroup?</expect>
        <send>%(sim_workgroup)s</send>
      </command>

      <!-- Log in and enable clustering -->
      <command>
        <expect>Password:</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>

      <command>
        <expect>%(node_hostname)s&gt;</expect>
        <send>license add %(cluster_license)s</send>
      </command>

      <!-- And we're done! -->
      <!-- shut down the sim for now -->

      <command>
        <expect>%(node_hostname)s&gt;</expect>
        <send>halt</send>
      </command>

      <!-- all done -->

      <command>
        <expect>~#</expect>
        <send>logout</send>
      </command>

    </impl>

  </change>

  <!-- Configure the sim to a given baseline config -->
  <change name="configure_secureadmin" iterator="netapp_sim_cluster"
	  module="modipy.change_command" type="CommandChange">

    <target name="netappsimhost"/>

    <preimpl>
      <command>
        <expect>~#</expect>
        <send>%(sim_install_dir)s/%(node)s/runsim.sh</send>
      </command>

    </preimpl>

    <impl>
      <command>
        <expect timeout="600">Password:</expect>
        <send>%(sim_admin_passwd)s</send>
      </command>

      <command>
        <expect>%(node_hostname)s&gt;</expect>
        <send>secureadmin setup -q ssh 768 512 768</send>
      </command>

      <command>
        <expect>%(node_hostname)s&gt;</expect>
        <send>secureadmin setup -q ssl t %(ssl_country)s %(ssl_state)s %(ssl_locality)s %(ssl_org)s %(ssl_unit)s %(node_hostname)s.%(ssl_domain)s %(ssl_contact_email)s %(ssl_keysize)s %(ssl_expiredays)s</send>
      </command>

      <command>
        <expect>%(node_hostname)s&gt;</expect>
        <send>halt</send>
      </command>

      <command>
        <expect timeout="60">~#</expect>
        <send>logout</send>
      </command>

    </impl>

  </change>

  <prereq for="configure_secureadmin">configure_sim_baseline_node</prereq>

</config>