Changes between Initial Version and Version 1 of PlasticSlices/Tools


Ignore:
Timestamp:
07/25/11 15:08:35 (13 years ago)
Author:
Josh Smift
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PlasticSlices/Tools

    v1 v1  
     1[[PageOutline]]
     2
     3For the [wiki:PlasticSlices Plastic Slices] project, we used a variety of simplistic tools to make it easier to manage slices and experiments.
     4
     5Many of the things we did here were to simplify the task of running ten slices simultaneously, but many of them are useful even if you're only running one slice.
     6
     7''FIXME: Much of this page is still under construction.''
     8
     9= rspecs =
     10
     11For each slice, we kept a directory of rspecs for the slice in a Subversion repository. The MyPLC rspecs were the same for each slice, so we actually stored them in a 'misc' directory and then created symlinks pointing to them in the per-slice directories. The OpenFlow rspecs were different for each slice -- very similar to each other, but e.g. the IP subnet, the URL of the controller, etc, were different.
     12
     13A copy of the plastic-101 and plastic-102 directories are here. (''FIXME: Figure out the best way to put them here. GENI wiki SVN? Need to strip out passwords, so we can't have them actually live here, this is just a snapshot. Sub-pages?'')
     14
     15We could then use these directories as input to omni commands to operate on "all the slivers in a slice", conceptually, e.g. with
     16
     17{{{
     18for rspec in ~/rspecs/reservation/$slicename/* ; do <something> ; done
     19}}}
     20
     21such as the omni commands below.
     22
     23= omni =
     24
     25We used the command-line tool 'omni' to manage all of the slices and slivers.
     26
     27== somni ==
     28
     29Short for "setup omni", we defined a bash function to set some variables for use by subsequent omni commands:
     30
     31{{{
     32somni () { slicename=$1 ; rspec=$2 ; am=$(grep AM: $rspec | sed -e 's/^AM: //') ; }
     33}}}
     34
     35See below for usage examples.
     36
     37== Creating slices ==
     38
     39We used these loops to create the ten plastic-* slices, and renew them until August 4th:
     40
     41{{{
     42for slicename in plastic-{101..110} ; do omni createslice $slicename ; done
     43for slicename in plastic-{101..110} ; do omni renewslice $slicename $(date +%Y%m%dT%H:%M:%S -d "August 4 15:00") ; done
     44}}}
     45
     46== Creating slivers ==
     47
     48We then used the rspec directories to create all of the slivers in each slice:
     49
     50{{{
     51for slicename in plastic-{101..110}
     52do
     53  for rspec in ~/rspecs/reservation/$slicename/*
     54  do
     55    somni $slicename $rspec
     56    omni -n -a $am createsliver $slicename $rspec
     57  done
     58done
     59}}}
     60
     61== Renewing slivers ==
     62
     63We also used the rspec directories to renew all of the MyPLC slivers in each slice:
     64
     65{{{
     66for slicename in plastic-{101..110}
     67do
     68  for rspec in ~/rspecs/reservation/$slicename/myplc-*rspec
     69    do somni $slicename $rspec
     70    omni -n -a $am renewsliver $slicename $(date +%Y%m%dT%H:%M:%S -d "August 4 15:00")
     71  done
     72done
     73}}}
     74
     75= Managing logins =
     76
     77Once we had our slivers, it was handy to have a way to run commands on all of the compute resources in parallel, or copy files to or from all of them. We did that by creating a file for each slice with the logins for the slivers in that slice, which we'd then feed as input to rsync or shmux.
     78
     79== Specify which logins to use ==
     80
     81To do something with all the logins in a slice, we'd do:
     82
     83{{{
     84logins=$(cat ~/plastic-slices/logins/logins-plastic-101.txt)
     85}}}
     86
     87We'd sometimes use grep to use only a subset, e.g. all the ones at Clemson:
     88
     89{{{
     90logins=$(grep -h clemson ~/plastic-slices/logins/logins-plastic-101.txt)
     91}}}
     92
     93We often wanted to do something with the logins in multiple slices; for all logins on all slices, we'd do
     94
     95{{{
     96logins=$(cat ~/plastic-slices/logins/logins-plastic-{101..110}.txt)
     97}}}
     98
     99and for a subset (e.g. all the ones for Clemson), we'd do something like
     100
     101{{{
     102logins=$(grep -h clemson ~/plastic-slices/logins/logins-plastic-{101..110}.txt)
     103}}}
     104
     105You can also set $logins by hand, of course.
     106
     107== Run a command on all of those logins ==
     108
     109We'd sometimes use a 'for' loop to run a command on each login, one at a time, like this one, which enables non-interactive sudo without a terminal (which is disabled by default):
     110
     111{{{
     112for login in $logins ; do ssh -t $login sudo sed -i -e 's/!visiblepw/visiblepw/' /etc/sudoers ; done
     113}}}
     114
     115More often, we used 'shmux' to run the same command on each login in parallel. We aliased 'shmux' to include some useful options:
     116
     117{{{
     118alias shmux='shmux -Sall -m -B -T 15'
     119}}}
     120
     121We then used it to enable cron (which we can do now that non-interactive sudo is enabled):
     122
     123{{{
     124shmux -c 'sudo chkconfig crond on && sudo service crond start' $logins
     125}}}
     126
     127And to install 'screen':
     128
     129{{{
     130shmux -c 'sudo yum -y install screen' $logins
     131}}}
     132
     133We installed a crontab for each login (after copying the file to each login, see below):
     134
     135{{{
     136shmux -c 'crontab $HOME/.crontab' $logins
     137}}}
     138
     139After we were done running experiments, we checked to make sure nothing unexpected had been left running:
     140
     141{{{
     142shmux -c "ps -efwww | egrep -i -v '(grep|cron|PID|ping|ps)' || true" $logins
     143}}}
     144
     145== Transfer files to all of those logins ==
     146
     147We copied up a common directory of dotfiles (including the crontab mentioned above):
     148
     149{{{
     150for login in $logins ; do rsync -a ~/plastic-slices/dotfiles/ $login: && echo $login ; done
     151}}}
     152
     153(We echo the login name after each one finishes just so we can tell that it's making progress.)
     154
     155We also sometimes did this in parallel, by telling the for loop to run the commands in the background (replacing the final ; with an &):
     156
     157{{{
     158for login in $logins ; do rsync -a ~/plastic-slices/dotfiles/ $login: && echo $login & done
     159}}}
     160
     161If you had a login-specific directory of dotfiles, you could use that too:
     162
     163{{{
     164for login in $logins ; do rsync -a ~/plastic-slices/dotfiles/$login $login: && echo $login & done
     165}}}
     166
     167We also used this to copy files back from each login, such as to pull down the screen log from each login:
     168
     169{{{
     170for login in $logins ; do echo "getting $login" ; rsync -a $login:screenlog.0 $login.log ; done
     171}}}
     172
     173= Running experiments =
     174
     175As of Baseline 5, we used two layers of 'screen' processes to run the experiments. First, we ran screen on a local machine for each slice, with a virtual terminal for each login. We had a .screenrc file for each slice to automate this. (''FIXME: Include or link to these here.'')
     176
     177Then, on each login, we ran 'screen' with a single virtual terminal, so that (a) if the connection from the local system to the remote login got disconnected, we could log back in and reconnect to the screen process; (b) we could use screen's logging functionality to capture all the output from the experiment (and retrieve it later).
     178
     179== Launch them all ==
     180
     181We used this to launch them, one at a time:
     182
     183{{{
     184for slice in plastic-{101..110} ; do screen -S $slice -c ~/plastic-slices/screenrc/screenrc-$slice ; done
     185}}}
     186
     187Detach from each after it launches, and the next will launch.
     188
     189== Connect to one ==
     190
     191We could then connect to them, plastic-101 in this example:
     192
     193{{{
     194screen -r plastic-101
     195}}}
     196
     197The '-S $slice' in the initial launch command above is what enables this handy trick -- it's otherwise pretty hard to keep track of which 'screen' process corresponds to which slice.
     198
     199== Start screen running and logging on a remote plnode ==
     200
     201We had an alias for this:
     202
     203{{{
     204experiment-start
     205}}}
     206
     207This was an alias in .bashrc:
     208
     209{{{
     210alias experiment-start='sudo rm -f screenlog.0 ; sudo script -c screen /dev/null'
     211}}}
     212
     213That oddness is necessary because 'screen' on a MyPLC plnode can't handle long usernames, so we needed to become root in order to launch it... But if you just do 'sudo screen', it complains "Cannot access '/dev/pts/0': No such file or directory", because you're in a VM on the plnode, so the 'script ... /dev/null' trick avoids that problem (by using the 'script' command to redirect output to /dev/null). And then,
     214
     215We then had a .screenrc file containing
     216
     217{{{
     218screen -L su - $SUDO_USER
     219}}}
     220
     221on the remote plnode, because we didn't actually want to run the experiments as root, so we open a window running as the original user.
     222
     223== Reconnect to a screen session on a remote plnode ==
     224
     225{{{
     226reconnect
     227}}}
     228
     229This is an alias in .bashrc:
     230
     231{{{
     232alias reconnect='sudo script -c "screen -dr" /dev/null'
     233}}}
     234
     235which reconnects to one of the screens created earlier.
     236
     237== Dump hardcopy logs ==
     238
     239In Baseline 4, we just ran a local 'screen' process, and used somewhat different .screenrc files, to create long scrollback buffers and then dump them to disk with screen's 'hardcopy' function.
     240
     241This dumps the logs, removes zero-length logs (from screen windows that didn't exist), and removes the blank lines from the top and bottom of each file.
     242
     243{{{
     244cd ~/plastic-slices/baseline-logs/baseline-4
     245for slice in plastic-{101..110} ; do for i in {0..13} ; do screen -S $slice -p $i -X hardcopy -h $slice-hardcopy-$i.log ; sleep 1 ; done ; done
     246for i in * ; do test -s $i || rm $i ; done
     247sed -i -e '/./,$!d' *
     248sed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' *
     249}}}