<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>second phase</title>
	<atom:link href="http://www.phase2.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phase2.net</link>
	<description>confessions of a geek</description>
	<lastBuildDate>Fri, 06 Jan 2012 19:51:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>HP SA &#8211; Client Side Software Policy Installs</title>
		<link>http://www.phase2.net/2011/12/hp-sa-client-side-software-policy-installs/</link>
		<comments>http://www.phase2.net/2011/12/hp-sa-client-side-software-policy-installs/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 07:44:56 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Opsware]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1556</guid>
		<description><![CDATA[Seems about the only time I post here now is to put up another script.  I really should figure out a nice little script listing page, but I find myself &#8230; <a class="more" href="http://www.phase2.net/2011/12/hp-sa-client-side-software-policy-installs/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>Seems about the only time I post here now is to put up another script.  I really should figure out a nice little script listing page, but I find myself too busy playing Skyrim when I have any free time nowadays!</p>
<p>The following script is intended to be placed on your clients.  It allows you to search for a software policy to install, as well as for the host you wish to install it on.  If you don&#8217;t specify a host, it&#8217;ll just install locally.  It should work on HP SA 7.86 and up.</p>
<p>&nbsp;</p>
<p>Here&#8217;s the usage:</p>
<pre class="code">install_policy.py -u USER [ -p PASSWORD ] -s POLICY [ --host HOSTNAME ]</pre>
<p>&nbsp;</p>
<p>And the script:</p>
<pre class="code">I've taken down the script for a day or so while I rewrite it! The host I develop on uses a python 2.4 binary for the agent and the script isn't compatible with the much more common 1.5.2 binary that comes with SA</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2011/12/hp-sa-client-side-software-policy-installs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Here&#8217;s an SA quickie</title>
		<link>http://www.phase2.net/2011/08/heres-an-sa-quickie/</link>
		<comments>http://www.phase2.net/2011/08/heres-an-sa-quickie/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 20:10:47 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[opsware]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1502</guid>
		<description><![CDATA[Not going to explain this one much &#8211; basically got asked by a coworker to write up a script real quick for him to update the Deployment Stage against every &#8230; <a class="more" href="http://www.phase2.net/2011/08/heres-an-sa-quickie/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>Not going to explain this one much &#8211; basically got asked by a coworker to write up a script real quick for him to update the Deployment Stage against every system in a device group.</p>
<pre class="brush:py">#!/opt/opsware/agent/bin/python

import sys
sys.path.append("/opt/opsware/pylibs")
sys.path.append("/opt/opsware/agent/pylibs")

from pytwist import *
from pytwist.com.opsware.device import DeviceGroupRef

ts = twistserver.TwistServer()
ds = ts.device.DeviceGroupService
ss = ts.server.ServerService

# Enter your username and password here
ts.authenticate("username","password")

# Enter the device group object ID for the group you want to iterate over
# You can get this object ID from the GUI
dgref = DeviceGroupRef(#######)
srefs = ds.getDevices(dgref)
for sref in srefs:
    svo = ss.getServerVO(sref)
    print "Updating %s" % svo.name
    # Set the stage.  This has to be a valid option - these are always in caps.
    svo.stage = "PRODUCTION"
    ss.update(sref, svo, 0, 0)</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2011/08/heres-an-sa-quickie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HP SA &#8211; Running a known script from pytwist</title>
		<link>http://www.phase2.net/2011/08/hp-sa-running-a-known-script-from-pytwist/</link>
		<comments>http://www.phase2.net/2011/08/hp-sa-running-a-known-script-from-pytwist/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 20:06:04 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[opsware]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1497</guid>
		<description><![CDATA[I was asked to put up a script that displays an easy way to find a script reference and then start that script. One thing to realize is that the &#8230; <a class="more" href="http://www.phase2.net/2011/08/hp-sa-running-a-known-script-from-pytwist/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>I was asked to put up a script that displays an easy way to find a script reference and then start that script. One thing to realize is that the hardest part about the pytwist API, besides some of the obscure functions, is actually finding your references so that you can get the objects to work on.</p>
<p>There are a few ways you can go around doing this. You can use filters and the search capability, you can manually create your ref, or you can find the refs via other objects, like device groups. The last one I mentioned is actually a very good way to loop through a set of systems to perform a task.</p>
<p>I&#8217;ll display the first method in this article and write up the other two later.</p>
<p>The first thing we need to do is get our script reference. Every object you work with in SA generally has a reference object and what I call the &#8216;virtual object&#8217; ( or whatever VO really stands for ). The VO contains all the important attributes where as the reference only contains the id of the object in SA and the name. There are some methods contained in the VO, but the pytwist API makes common use of a &#8216;Service&#8217; interface for specific types of objects, like the ServerService, the ServerScriptService, the SearchService, JobService, DeviceGroupService and so on that contain the methods that really make use of the VOs.</p>
<p>This first script enables us to run a known SA script on a known host thru SA from a command line. Note that the command line can be any host that has an agent &#8211; this doesn&#8217;t need to be run from the core.</p>
<p>I&#8217;ll show the script first, then explain it. This script is a version that can be run from an agent that has the Python 2 API Access for Server module installed.</p>
<pre class="brush:py">import sys
from optparse import OptionParser
from getpass import getpass
sys.path.append('/opt/opsware/smopylibs2')
sys.path.append('/opt/opsware/agent_tools/') 

import agenttools_common
from pytwist import *
from pytwist.com.opsware.server import ServerRef
from pytwist.com.opsware.script import ServerScriptRef
from pytwist.com.opsware.custattr import NoSuchFieldException

ts = twistserver.TwistServer()

ss = ts.server.ServerService
scs = ts.script.ServerScriptService

# This is the same basic authentication scheme used in most of
# my scripts.  You can tear this out and just use the
# ts.authenticate method with the values already filled in.
parser = OptionParser()
parser.add_option("-u","--user",dest="sauser",
                  help="SA login id")
parser.add_option("-p","--pass",dest="sapasswd",
                  help="SA login password")
parser.add_option("-r","--prompt",action="store_true",dest="readstdin",
                  help="Prompt for passwords instead of using arguments")

(options, args) = parser.parse_args()

if not options.sapasswd and not options.readstdin:
        print "You must specify a password to login to SA."
        sys.exit(1)

if not options.sauser:
        print "You must specify a username to login to SA."
        sys.exit(1)

if options.readstdin:
    options.sapasswd = getpass("Enter Opsware Password: ")

ts.authenticate(options.sauser, options.sapasswd)

# Now the real work starts

# Create a reference to a script we know the ID of
# The ID can be obtained from the SA Gui
scriptRef = ServerScriptRef(22530102)

# Create a reference to a server we know about
serverRef = ServerRef(730102)

# In order to run the script, we'll use the startServerScript method
# from the ServerScriptService.  It requires the script ref, an arugments
# object.  We can optionally give it a tag that it will put under
# the ticket ID.  There are also optional arguments for a job notification
# and job schedule that I won't cover here.
#
# We have the reference already, so we need to create the job argument
# object.  We only need to set the list of targets, although there are
# options for setting the username and password of the script

# Creates the object
scriptArgs = com.opsware.script.ServerScriptJobArgs()

# Requires a list of scriptableRefs, which can be ServerRefs,
# DeviceGroupRefs or HypervisorRefs.  In our case, ServerRefs
scriptArgs.targets = [serverRef]

# Now we can run the job
runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001', None, None)
print "Job started as id %d" % runScript.id</pre>
<p>So, besides the basic authentication and argument parsing, there isn&#8217;t too much to this script. We have to create the references needed and we do that by importing the references in from pytwist and then using them as constructors like so:</p>
<pre class="brush:py">from pytwist.com.opsware.server import ServerRef
from pytwist.com.opsware.script import ServerScriptRef
...
scriptRef = ServerScriptRef(22530102)
serverRef = ServerRef(730102)</pre>
<p>In order to run the script, we need to call the startServerScript, which is part of the ServerScriptService interface. But, in order to call it, we need to create one more object, the ServerScriptJobArgs object. We create the object by calling the constructor directly:</p>
<pre class="brush:py">scriptArgs = com.opsware.script.ServerScriptJobArgs()</pre>
<p>You should note that we could have done the same things with the ServerRef and ScriptRef constructors. Instead of importing them and then calling them, we could have simply done this:</p>
<pre class="brush:py">scriptRef = com.opsware.script.ScriptRef(22530102)
serverRef = com.opsware.server.ServerRef(730102)</pre>
<p>Generally I&#8217;m using alot of server refs, so I like to import to save on typing. Either way, we now have a blank ServerScriptJobArgs object that we need to fill. In our case, we only need to fill out the targets attribute, which is actually a list of any Scriptable Ref. This tells our script which targets it&#8217;s going to run on. As mentioned in the comments, a scriptable reference is either a DeviceGroupRef, a ServerRef or a HypervisorRef. Since we have a ServerRef, we just need to contain it in a list and assign it to the targets attribute:</p>
<pre class="brush:py">scriptArgs.targets = [serverRef]</pre>
<p>Everything is setup now, so I can just call the startServerScript method. The method takes 5 arguments, 3 of which are optional. The 3 optional requires are a ticket id tag, a job notification object and a job schedule object. The ticket id tag is just a string, so it&#8217;s easy to create but I&#8217;m not going to bother with the other two, so our call looks like this:</p>
<pre class="brush:py">runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001'
, None, None)</pre>
<p>Remember that the &#8216;scs&#8217; is just a shortcut to the ServerScriptService. We could have called this method another way:</p>
<pre class="brush:py">runScript = scs.startServerScript(scriptRef, scriptArgs, 'Ticket ID #001', None, None)</pre>
<p>Again, I prefer the former just to save on typing if I plan on using the service multiple times. The method returns a Run Server Script instance, which we can do other things with, but that&#8217;ll have to wait for another article. In the example, I print out the job ID so that I can find and verify the job in the GUI easily.</p>
<p>That&#8217;s it for now &#8211; in the next article I&#8217;ll show how you can use the filter to give the user a way to specify the name of the script they want to run and on which servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2011/08/hp-sa-running-a-known-script-from-pytwist/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>HP SA &#8211; Finding offline agents</title>
		<link>http://www.phase2.net/2011/07/hp-sa-finding-offline-agents/</link>
		<comments>http://www.phase2.net/2011/07/hp-sa-finding-offline-agents/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 22:49:25 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1492</guid>
		<description><![CDATA[A common issue we experience is that agents often go offline in the SA console. Whether it is because the admin of the system screwed up a gateway, shutdown the &#8230; <a class="more" href="http://www.phase2.net/2011/07/hp-sa-finding-offline-agents/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>A common issue we experience is that agents often go offline in the SA console. Whether it is because the admin of the system screwed up a gateway, shutdown the server without deactivating it from SA or for one of a hundred other reasons it may happen, when you have 20,000+ devices in SA, it becomes painful to track them. Pile on that we don&#8217;t want to track every single offline agent, just ones that have been offline for awhile, meaning the agent has some type of an permanent issue, rather than occasionally flapping.</p>
<p>For our solution, we wrote up the following simple python script to do the job for us.</p>
<pre class="brush:py">import sys
import time
import smtplib
from email.MIMEText import MIMEText
from optparse import OptionParser
from getpass import getpass
sys.path.append('/opt/opsware/smopylibs2')
sys.path.append('/opt/opsware/agent_tools/') 

import agenttools_common
from pytwist import *
from pytwist.com.opsware.search import Filter
from pytwist.com.opsware.server import ServerRef

ts = twistserver.TwistServer()
ses = ts.search.SearchService
ss = ts.server.ServerService
DAY = 86400

parser = OptionParser()
parser.add_option("-u","--user",dest="sauser",
                  help="SA login id")
parser.add_option("-p","--pass",dest="sapasswd",
                  help="SA login password")
parser.add_option("-r","--prompt",action="store_true",dest="readstdin",
                  help="Prompt for passwords instead of using arguments")
parser.add_option("-c","--customer",dest="customer",
                  help="Customer name to search for")
parser.add_option("-d","--days",dest="days",
                  help="Expiration limit in days")

(options, args) = parser.parse_args()

if not options.customer:
        print "You must specify a customer to search for."
        sys.exit(1)

if not options.sapasswd and not options.readstdin:
        print "You must specify a password to login to SA."
        sys.exit(1)

if not options.sauser:
        print "You must specify a username to login to SA."
        sys.exit(1)

if options.readstdin:
    options.sapasswd = getpass("Enter Opsware Password: ")

ts.authenticate(options.sauser, options.sapasswd)

filt = Filter()
filt.objectType = 'device'
filt.expression = "(ServerVO.state = UNREACHABLE) &amp; " \
                  "(ServerVO.opswLifecycle != DEACTIVATED)  " \
                  "(device_customer_name = %s)" % options.customer

offline_servers = ses.findObjRefs(filt)
expired_servers = []

if len(offline_servers) == 0:
    print 'There are no unreachable servers'
    sys.exit(0)
else:
    print "Processing %d servers" % len(offline_servers)

now = int(time.time())
for sref in offline_servers:
    shvo = ss.getServerHardwareVO(sref)
    beginDate = shvo.beginDate
    if (now - int(beginDate)) &gt;= (DAY * int(options.days)):
        server_data = [sref.id, sref.name, beginDate]

        # this sorts the list.  if you don't care about
        # sorting, remove this section.

        # sort while create - could have sorted
        # after create, which would probably been
        # faster, but this was an educational exercise

        # if the list is blank, just append
        if len(expired_servers) == 0:
            expired_servers.append(server_data)
            continue

        # place it in the correct spot
        inserted = None
        for i in range(0,len(expired_servers)):
            if beginDate &lt; expired_servers[i][2]:
                expired_servers.insert(i,server_data)
                inserted = 1
                break

        if not inserted:
            expired_servers.append(server_data)
        # end of sorting

        # if you don't sort, then just uncomment this line
        # expired_servers.append(server_data)

if len(offline_servers) == 0:
    print "All unreachable servers have not been offline for more than %s" \
          "days" % options.days
    sys.exit(0)

report = "\r\n\r\nThe following servers have not registered for more than %s " \
         "days.\r\n\r\n" % options.days

for server in expired_servers:
    datestr = "%s/%s/%s %s:%s:%s" % time.gmtime(float(server[2]))[0:6]
    report += "%s : %s has not registered since %s.  \r\n" % \
            (server[0],server[1],datestr)

# If you want output to the screen
print report

# Create a text/plain message
msg = MIMEText(report)

sender = "root@example.com"
rcptto = ["user1@example.com", "user2@example.com"]
msg['Subject'] = "[opsware] Offline Servers for %s" % options.customer
msg['From'] = sender
msg['To'] = ",".join(rcptto)

# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(sender, rcptto, msg.as_string())
s.quit()</pre>
<p>A couple of notes are probably in order. First, this was written for our environment, so it may require some massaging to get it to work in your own. The multiple &#8216;/r/n&#8217; tags are so that it shows up in Outlook correctly and not as a huge, one line mess. By default, the script will sort by date. There are some comments in there if you&#8217;d like to remove that functionality.</p>
<p>We wanted to be able to run this from any agent, rather than from the cores, so that our internal groups that use SA could run this if they chose to. It only requires that the agent tools and the Python 2 API for Server Modules packages be installed.</p>
<p>To run, use something like the following:</p>
<pre class="terminal">/opt/opsware/smopython2/python ./offline.py -u username -p password -d 30 -c customername</pre>
<p>Make sure to change the bottom of the script to have the email addresses you&#8217;d like to use and then just cron the script.</p>
<p>Comments welcome.</p>
<p>( Thanks to <a href="http://www.stuckincustoms.com">Trey Ratcliffe</a> for the use of the photo used on the header of this post. )</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2011/07/hp-sa-finding-offline-agents/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Opsware Custom Attributes and You.</title>
		<link>http://www.phase2.net/2010/03/opsware-custom-attributes-and-you/</link>
		<comments>http://www.phase2.net/2010/03/opsware-custom-attributes-and-you/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 22:01:36 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[opsware]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1027</guid>
		<description><![CDATA[I realize most of the time I end up complaining about Opsware &#8211; that&#8217;s generally because it&#8217;s part of the human condition.  We say stuff when we&#8217;re upset or angry &#8230; <a class="more" href="http://www.phase2.net/2010/03/opsware-custom-attributes-and-you/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>I realize most of the time I end up complaining about Opsware &#8211; that&#8217;s generally because it&#8217;s part of the human condition.  We say stuff when we&#8217;re upset or angry or don&#8217;t like something.  How many times have you ever called up the phone company to tell them &#8216;Great job!&#8217;</p>
<p>Yeah, I thought so.</p>
<p>So I figured I&#8217;d write an article on one of the great things I love about Opsware &#8211; Custom Attributes! Combined with Dynamic Groups, these puppies provide the ability to create scripts that I don&#8217;t have to duplicate for different hosts.</p>
<p>First, however, I should explain what Dynamic Groups are.  Dynamic Groups allow the user to group systems based on certain criteria.  For instance, you want all the systems in a certain network to be grouped together.  Whenever you add a system from that network into Opsware, it automatically becomes a member of that group.  Neat by itself but nothing extraordinary.</p>
<p>However, you can assign Custom Attributes ( further known as CAs ) to the Dynamic Group.  So for my new dynamic group that I created ( for example, a group that pulls in all hosts in the 192.168.0.0/24 network ), I can assign some CAs to the group and the CAs get assigned to each host within the group.</p>
<p>You may ask yourself, &#8216;Why is this useful?&#8217;.  It&#8217;s not yet.  There&#8217;s one more piece that&#8217;s missing from the puzzle.  The piece that is missing is a software package that Opsware comes with &#8211; Agent Tools.  When you install the Agent Tools, it comes with a set of python Opsware APIs and small scripts that use the API to make calls back to the master Opsware system and get information &#8211; including those CAs!</p>
<p>Armed with these 3 pieces, it becomes easy to create a script that uses the CAs that are dynamically assigned to your host to do all sorts of things.  For example, let&#8217;s say you want to create a script that checks your /etc/resolv.conf on any system in that 192.168.0.0/24 network.  First, we&#8217;ll create the dynamic group and assign it the correct device membership.</p>
<p>Next, edit the group and add a CA named something like &#8216;<strong>DNS_SERVERS</strong>&#8216;.  For the value, put in a DNS server on separate lines and then save your group.  Make sure you&#8217;ve got the agent tools package installed and we can run a simple test.</p>
<pre class="terminal">[root@frenzy1a.star.dev:~]# /opt/opsware/agent_tools/get_cust_attr.sh DNS_SERVERS
192.168.0.20
192.168.0.21</pre>
<p>With that information, we can create a pretty simple shell or python script ( pick your poison ) to make sure that our /etc/resolv.conf has those servers defined.  For kicks, here&#8217;s an example script that checks to make sure the IPs in the <strong>DNS_SERVERS</strong> CA are set in /etc/resolv.conf.  You could easily modify this so that it actually inserts the values.</p>
<pre class="brush:py">#!/opt/opsware/agent/bin/python

import sys
sys.path.append('/opt/opsware/agent_tools/')
import agenttools_common
import re
from string import split
from pytwist.com.opsware.custattr import NoSuchFieldException

def searchFile(file,pattern):
    found = 0
    search = re.compile(pattern)
    try:
        f = open(file, "r")
    except IOError:
        sys.stderr.write("Could not open file %s.n" % (file))
        sys.exit(3)

    for line in f.readlines():
        if search.match(line):
            found = 1
        break

    return found

def main(args):
    ts = agenttools_common.ts
    servers = {}
    result = 0
    hostref = agenttools_common.getServerRef()

    try:
        custattr = ts.server.ServerService.getCustAttr(hostref,
        "DNS_SERVERS", 1)
    except NoSuchFieldException:
        sys.stderr.write("Could not find custom attribute DNS_SERVERS.n")
        sys.exit(3)

    servers = split(custattr)
    for s in servers:
        found = searchFile("/etc/resolv.conf","^nameservers+" + s)
        if not found:
            sys.stderr.write("The server %s was not configured in"
            " /etc/resolv.conf" % (s))
        result = 1

    return result

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))</pre>
<p>Now if I have another network, say, 192.168.120.0/24, I can do the same thing.  Make the group, assign the membership, create the <strong>DNS_SERVERS</strong> CA and assign the script and presto &#8211; it&#8217;s done! No duplication of work involved here and I can control the contents of the file from the Opsware console.</p>
<p>One last thing about CAs &#8211; they do support overrides.  For instance, I can override the CA by creating the same named CA on the host itself.  This will override the CA at the group level.  One thing you need to be careful, however, is that you don&#8217;t assign a host into two groups that define the same CA &#8211; there&#8217;s no priority between the groups and they don&#8217;t combine the contents of the CA to make one CA, so you&#8217;ll get random results.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2010/03/opsware-custom-attributes-and-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Restarting Cisco VPN Subsystem on OS X</title>
		<link>http://www.phase2.net/2009/06/restarting-cisco-vpn-subsystem-on-os-x/</link>
		<comments>http://www.phase2.net/2009/06/restarting-cisco-vpn-subsystem-on-os-x/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 06:39:14 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[cisco]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[vpn]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=1014</guid>
		<description><![CDATA[If you&#8217;re like me and you use your MacBook Pro for work, it might stand to reason that you have to VPN into your work network. If so, it also &#8230; <a class="more" href="http://www.phase2.net/2009/06/restarting-cisco-vpn-subsystem-on-os-x/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me and you use your MacBook Pro for work, it might stand to reason that you have to VPN into your work network. If so, it also may be a good chance that you use the Cisco VPN client and have run into this annoying message:</p>
<p><strong>Error 51: Unable to communicate with the VPN subsystem</strong></p>
<p>Thankfully, the solution is rather simple. Open up your favorite terminal client and simply type:</p>
<pre class="terminal">sudo /System/Library/StartupItems/CiscoVPN/CiscoVPN restart</pre>
<p>Enter your password and it&#8217;ll restart the subsystem. Then just re-open the Cisco VPN client and you&#8217;re golden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2009/06/restarting-cisco-vpn-subsystem-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Book Review: Victory of Eagles</title>
		<link>http://www.phase2.net/2009/06/book-review-victory-of-eagles/</link>
		<comments>http://www.phase2.net/2009/06/book-review-victory-of-eagles/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 07:27:23 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[reviews]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=982</guid>
		<description><![CDATA[Recently finished the book &#8216;Victory of Eagles&#8217; by Naomi Novik ( one of those female authors I mentioned that I actually do like ) &#8211; this is the fifth book &#8230; <a class="more" href="http://www.phase2.net/2009/06/book-review-victory-of-eagles/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>Recently finished the book &#8216;Victory of Eagles&#8217; by Naomi Novik ( one of those female authors I mentioned that I actually do like ) &#8211; this is the fifth book in the series and thankfully not the last.  As I was reading this novel I <strong>was</strong> under the impression that it had was the last book in the series and I think that skewed my mindset a bit.</p>
<p>I try to prevent myself from posting any spoilers, although it makes it hard to really explain the areas I didn&#8217;t like about the book.  It kept up the pace rather well and there was always action to be had; unfortunately this is also a flaw as well as about the last third of the book seems rather rushed and sloppy.  Also, I&#8217;m not sure if the speech patterns are supposed to be so laden with incorrect grammar or whether she just had a bad editor but there were dozens of tiny errors that grated on me while reading.</p>
<p>I&#8217;m starting to lose my interest in these books as Temeraire never seems to be maturing from his child-like state.  Then again, many of the dragons seem to exhibit child behaviors so I shouldn&#8217;t be too surprised at that.  I just wish in some sections he wasn&#8217;t such a brat and at least displayed a bit of maturity.</p>
<p>All in all, it&#8217;s not a bad novel but I&#8217;m definitely glad that I waited until it was out in paperback before picking it up.  The hardcover would have been a waste of cash.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2009/06/book-review-victory-of-eagles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gitorious setup: RSTRING_LEN in rdiscount</title>
		<link>http://www.phase2.net/2009/06/gitorious-setup-rstring_len-in-rdiscount/</link>
		<comments>http://www.phase2.net/2009/06/gitorious-setup-rstring_len-in-rdiscount/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 22:29:20 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Unix]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=983</guid>
		<description><![CDATA[Ran into an issue recently where I was trying to install gitorious on a local RHEL5 system. The site would crash every time I tried to view a repo with &#8230; <a class="more" href="http://www.phase2.net/2009/06/gitorious-setup-rstring_len-in-rdiscount/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>Ran into an issue recently where I was trying to install gitorious on a local RHEL5 system.  The site would crash every time I tried to view a repo with the error:</p>
<pre class="terminal">
ruby: symbol lookup error: /usr/lib64/ruby/gems/1.8/gems/rdiscount-1.3.1.1/lib/rdiscount.so: undefined symbol: RSTRING_LEN
</pre>
<p>The solution ended up being the following &#8211; In the file <strong>/usr/lib64/ruby/1.8/x86_64-linux/ruby.h</strong> ( note I&#8217;m running on 64bit, on 32bit it&#8217;d be /usr/lib/ruby/1.8/i386-linux/ ), add these lines somewhere near the top:</p>
<pre class="terminal">
#define RSTRING_LEN(s) (RSTRING(s)->len)
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
</pre>
<p>After that, uninstall and reinstall rdiscount</p>
<pre class="terminal">
gem uninstall rdiscount
gem install rdiscount -v 1.3.1.1
</pre>
<p>And you should be good to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2009/06/gitorious-setup-rstring_len-in-rdiscount/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Productivity and my misconceptions</title>
		<link>http://www.phase2.net/2009/05/productivity-and-my-misconceptions/</link>
		<comments>http://www.phase2.net/2009/05/productivity-and-my-misconceptions/#comments</comments>
		<pubDate>Wed, 27 May 2009 06:30:24 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Emo]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=974</guid>
		<description><![CDATA[Growing up, I&#8217;ve always been the type of person who was interested in just about everything. I list my drive to always be learning as one of my most favorable &#8230; <a class="more" href="http://www.phase2.net/2009/05/productivity-and-my-misconceptions/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>Growing up, I&#8217;ve always been the type of person who was interested in just about everything.  I list my drive to always be learning as one of my most favorable attributes.  I love to experience things, whether they be simple ( a new game to play ) to the extreme ( learning to fly a plane ) to the somewhat eccentric and esoteric ( falconry ).  Mix that in a bowl with a combination of a beautiful girlfriend, my close group of friends, my love of video games, reading fiction and watching television.  It all points to the most obvious fact that I have alot of crap to do and not alot of time to do it in.</p>
<p>This leads me into my topic; how does one measure productivity?</p>
<p>For some this may simply be defined as staying busy.  Of course, then you&#8217;d have to define busy because I believe most people would be in agreement that watching television is not what one could call &#8216;busy&#8217; or productive.  Then again, you could just define busy as not being bored but that still doesn&#8217;t grasp the concept.  Another train of thought would suggest that productivity is measured by the result of what you produce through your efforts.  But then how does one actually measure certain insubstantial things such as keeping relationships running smoothly?  Because that is most certainly what I would call being productive.  Hard to measure tho, no?</p>
<p>Still others may argue that productivity is simply measured by a feeling of self &#8211; after all, being productive is certainly a feeling that one may experience and this would be the argument I would have to be the most inclined to agree with.  Sort of a &#8216;Beauty is in the eye of beholder&#8217; mantra.</p>
<p>Why then, after a full day of work, an hour of studying guitar, reading my fiction, playing a video game, spending time with my girlfriend and taking care of my dogs do I still <strong>feel</strong> unproductive?</p>
<p>Is it because I did not produce anything from my efforts?  Because I hold myself to higher standards? Because I feel, when I browse the internet and see the works that others have produced, I feel insignificant in the grand scheme?</p>
<p>Again, it&#8217;s the last statement that I feel is the most important to me.  I usually pop open my laptop while I&#8217;m watching TV or a movie and take the time to browse, catch up with my social networking, blog here, studying some design and brainstorm for new ideas.  It&#8217;s while I&#8217;m browsing the web that I start to feel less unproductive, page by page, as I view the works of artists, designers, programmers, writers and the like.  It&#8217;s when I&#8217;m seeing the fruit of their labor that I feel that I have not taken full advantage of the six or so hours I have when I get home to better myself and to produce my own world on the internet for others to share and contribute to.</p>
<p>That is the scariest part of this whole monologue &#8211; the fear of not being able to balance my life ( dogs, work, girlfriend, friends ) versus the feeling of productiveness.  It gives a glossy coat of evil and seduction to the idea of being more productive, as if it were something that I shouldn&#8217;t be doing, that is wrong if I spend my time working towards as it takes me away from the more narcissistic goal of improving <strong>me</strong>.  I think it&#8217;s something I&#8217;m going to have to struggle with for a very long time.</p>
<p>So I ask &#8211; how do you measure your productiveness by?  What measures and balances do use to make sure that your goals, albeit selfish in nature, balance with those goals that concern the lives that you are intermingled with?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2009/05/productivity-and-my-misconceptions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adobe AIR twitter clients on Ubuntu Jaunty 64bit</title>
		<link>http://www.phase2.net/2009/04/adobe-air-twitter-clients-on-ubuntu-jaunty-64bit/</link>
		<comments>http://www.phase2.net/2009/04/adobe-air-twitter-clients-on-ubuntu-jaunty-64bit/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 02:43:15 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Unix]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.phase2.net/?p=939</guid>
		<description><![CDATA[So if you found this post, you probably had the same problem that I had.  You installed the latest Ubuntu on your nice 64 bit hardware, loaded up AIR and &#8230; <a class="more" href="http://www.phase2.net/2009/04/adobe-air-twitter-clients-on-ubuntu-jaunty-64bit/">Continue reading</a>]]></description>
			<content:encoded><![CDATA[<p>So if you found this post, you probably had the same problem that I had.  You installed the latest Ubuntu on your nice 64 bit hardware, loaded up AIR and got all the 32 bit libraries you thought you needed.  Then you tried to load up your favorite twitter client ( which, on Linux, means it&#8217;s probably an adobe air app ) and found that you could not, for the life of you, connect to twitter.</p>
<p>Generally, you&#8217;ll find messages like &#8220;Could not connect to Twitter, check your firewall&#8221; or &#8220;Verification Failed&#8221;.</p>
<p>You check your browser, it works fine.  You change your password and retry &#8211; nope, still not working.</p>
<p>Well, here&#8217;s the answer, found in a random comment on some random blog -</p>
<pre class="terminal">sudo apt-get install lib32nss-mdns</pre>
<p>That&#8217;s it! Install that one library and you&#8217;ll be all set.  AIR is still funky on 64bit but at least you don&#8217;t have to run Twitux now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phase2.net/2009/04/adobe-air-twitter-clients-on-ubuntu-jaunty-64bit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

