Add Scroogle to your search area in Firefox 2.0 Install the 'Scroogle Scraper' search plugin.

photo 1(14)Sometimes you need to charge your cell phone in the wilderness, I guess, so you can play Angry Birds. And that’s where Goal Zero comes into play.

I’ve tested Goal Zero’s line of portable solar gear, and it’s not bad. It’s not particularly good either, but that may be because my expectations of the sun are too high. On one model I tested, it took FOREVER (translation: 8+ hours) to charge the battery from the sun. After all of that charging, you can then use the battery to power your laptop for only about an hour. That’s a poor charge-to-use ratio, in my opinion.

I digress.

Portable Solar Battery Packs are easy to build. Here’s what you need:

  • A battery (or two)
  • A solar panel (or three)
  • Some cables
  • A charge controller
  • An inverter with AC and USB ports
  • A battery charge meter
  • An AC battery charger
  • A box to carry it all in

Our Goal is to match the Goal Zero Yeti 400 combined with the Boulder 30 Solar Panel:

Goal Zero Yeti 400 — $459.99
Output Features:
110V, 2.6A (300W continuous, 600W surge max) Inverter
AGM Lead Acid 396Wh (12V, 33Ah)
USB 5V, up to 1.5A (7.5W max), regulated
12V Car Port 12V, up to 10A (120W max)
Input Features
Wall Charger 75W
Car Charger 30W
Other Features
Charging indicator
Battery display
Easy to carry
Easy to use
Attractive case
29 lbs
10.25 x 8 x 8 in (26 x 20.3 x 20.3 cm)

Boulder 30 Solar Panel — $239.99
Monocrystalline 30W
21 x 18 x 1 in (53 x 2.5 x 46 cm)
14-16V, 2.0A max (30W), not regulated

My first stop was Cabelas. There I purchased three 2.5 W SunForce Solar Chargers (Solar Panels). They were on sale for $19.99. Next I purchased a SunForce 8.5A Solar Charge Controller. It cost $29.99. Then I purchased a 400 W Power Inverter. It has 2 AC outlets and a 5V USB outlet (for charging my iPhone.) It cost $39.99. The next item I picked up was a plastic Ammo cost with a sturdy carrying handle. The case is about 1/2 the size of the traditional 50 cal ammo can. It cost about $10. I still needed one more thing– a 3-IN-1 Solar add-a-panel adapter for attaching the 3 panels in parallel. That cost $13.99.

Next the batteries. I chose two 6v uninterruptible power supply (UPS) batteries I had on hand. You can pick two up, depending on the amp-hour rating (8-18), run $9 to $40.

The remaining items for our solar battery pack are a 12v charge indicator (available from auto parts stores for $15), a bit of wire from a power cord, some terminal ends and some wire nuts.

Here are some pics of what it all looks like:
solarphoto 3(10)photo 5(10)photo 4(13)photo 4(12)photo 3(11)photo 2(15)photo 1(15)photo 2(14)
Next time I’ll answer these questions:
How much did it cost and how much does it weight and how well does it perform?
What didn’t we accomplish with PROTOTYPE 1?
What is in store for PROTOTYPE 2?

Using a Google Spreadsheet probably isn’t the best way to to manage your project tasks, but for those of you who use this method, now with an google script API call (SOAP or otherwise) to your task tracker you can get the status of any task and highlight the task cell appropriately!

Here is the Google apps for business google script proof of concept script I wrote. It’s hard-coded to check the first column only of a Google Spreadsheet for task ids. Modifying the rest is left as an exercise for the reader.

function GetTaskStatus() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  var dataformat = rows.getBackgrounds();
  var color;
  var apiUserName = 'USERNAME_HERE';
  var apiPassword = 'PASSWORD_HERE';
 
  for (var i = 1; i <= numRows - 1; i++) {
    var cell = values[i][0]; //constructing SOAP envelope manually, per https://developers.google.com/apps-script/articles/soap_geoip_example   
//if not SOAP, it's much easier!
//var apiurl = 'https://taskapi.example.com/?module=task&action=view_task_status&task[id]='+ cell;
//var response = UrlFetchApp.fetch(apiurl);
 
    var xml= "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tns=\"http://taskapi.example.com/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ><SOAP-ENV:Body><tns:getTaskStatus xmlns:tns=\"http://taskapi.example.com/\"><tns:authInfo><ns1:username>"+apiUserName+"</ns1:username><ns1:password>"+apiPassword+"</ns1:password></tns:authInfo><tns:intTaskId>"+cell+"</tns:intTaskId></tns:getTaskStatus></SOAP-ENV:Body></SOAP-ENV:Envelope> ";
    var options =
   {
     "method" : "post",
     "contentType" : "text/xml",
     "payload" : xml
   };
  var result = UrlFetchApp.fetch("https://taskapi.example.com/index.php?service_type=tasks&is_server_request=1", options).getContentText();
  var taskPattern=new RegExp("<ns1:taskStatus>(.*)</ns1:taskStatus>"); ////XmlService didn't work for my task tracker, because we're not returning a DTD! reverting to regex :( 
  response=taskPattern.exec(result)[1];    
    response=response.trim();
    switch(response)
    {
      case 'New':
      case 'Acknowledged':
      case 'Reassigned':
      case 'In Progress':
      case 'On Hold':
      case 'Cancelled':
      case 'Under Review':
      case 'Backlog':
      case 'Dev Ready':
        color='RED';
        break;
      case 'Dev in Progress':
        color='YELLOW';
        break;
      case 'Completed':
      case 'QA Ready':
      case 'QA in Progress':
      case 'Release Ready':
      case 'Awaiting Response':
      case 'Committed':
      case 'Released':
      case 'Verified':
      case 'Released on Stage':
      case 'Verified on Stage':
        color='GREEN';
        break;
      default:
        color='BLUE'
    }
    sheet.getRange(i+1,2).setValue(response);
    dataformat[i][0]=color;
  }
   rows.setBackgrounds(dataformat); 
};

Cloud computing is awesome until there is an error on booting and the SSH service doesn’t load for you. In that case, there isn’t an out-of-band console(ipmi/DRAC) to let you fix the issue like you’d have with a physical machine.

Recently, in response to the heartbleed/openssl vulnerability, we patched openssl. Then, after a reboot, we realized we couldn’t ssh into the instance, because something wasn’t right with sshd, so it didn’t load:

ssh: connect to host W.X.Y.Z port 22: Connection refused

The system logs from the ec2 management console showed ssh didn’t start because of a library conflict.

Starting sshd: /usr/sbin/sshd: /usr/local/firefox/libnssutil3.so: version `NSSUTIL_3.15' not found (required by /usr/lib64/libssl3.so) Cannot load /etc/httpd/modules/mod_ldap.so into server: /usr/local/firefox/libnssutil3.so: version `NSSUTIL_3.15' not found (required by /usr/lib64/libssl3.so)

Time to debug this by detaching and attaching that EBS root volume to another similar instance type:

  1. Create a similar instance “instance 2″ in the same availability zone
  2. Stop instance 1
  3. Take a snapshot of your root volume on instance 1 (for safety) and detach the root volume
  4. On the new instance, instance 2, attach the root volume as a secondary volume see: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html
  5. Mount the volume: $ sudo mount /dev/xvdf /mnt/secondaryvol/ (/dev/xvdf as specified it in management console)
  6. chroot your secondary volume: sudo chroot /mnt/secondaryvol/
  7. DEBUG! (in this case: mv /usr/local/firefox/libnssutil3.so /usr/local/firefox/libnss3.so.old; mv /usr/local/firefox/libnss3.so /usr/local/firefox/libnssutil3.so.old)
  8. type ‘exit’ to exit from chroot
  9. Umount the volume: $ sudo umount /mnt/secondaryvol/
  10. Detach the volume from instance 2
  11. Attach the volume back to instance 1 as /dev/sda1
  12. Start the instance

pingdom.com is great for monitoring websites and for exposing that data to your customers. But what if you have scheduled maintenance and want to pause the checking, say weekly? Pingdom fails you!*

Fortunately, they have an API!

<?php
	viewCheckStatus();
	echo "////////////////// PAUSE //////////////////////\r\n";
	pauseAll();
	viewCheckStatus();
	echo "////////////////// RESUME //////////////////////\r\n";
	resumeAll();
	viewCheckStatus();
	exit;
 
	function getCurlObject() {
    	$curl = curl_init();
    	curl_setopt($curl, CURLOPT_URL, "https://api.pingdom.com/api/2.0/checks");
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    	curl_setopt($curl, CURLOPT_USERPWD, "YOUR_EMAIL_HERE:PASSWORD_HERE");
    	curl_setopt($curl, CURLOPT_HTTPHEADER, array("App-Key: APP_KEY_GOES_HERE"));
    	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    	return $curl;
	}
 
	function viewCheckStatus() {
	$curl = getCurlObject();
    	curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
    	$response = getResponse( $curl );
    	$checksList = $response['checks'];
    	if(isset($checksList)){
			foreach ($checksList as $check) {
				print $check['name'] . " is " . $check['status'] . "\r\n";
			}
		}
		return;
	}
 
	function pauseAll() {
		$curl = getCurlObject();
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
		curl_setopt($curl, CURLOPT_POSTFIELDS, "paused=true");
		$response = getResponse( $curl );
		echo "\r\n" . $response['message'] . "\r\n";
		return;
	}
 
	function resumeAll(){
		$curl = getCurlObject();
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
		curl_setopt($curl, CURLOPT_POSTFIELDS, "paused=false");
		$response = getResponse( $curl );
		echo "\r\n" . $response['message'] . "\r\n";
		return;
	}
 
	function getResponse( $curl ) {
		$response = json_decode( curl_exec( $curl ),true );
		if( isset( $response['error'] ) ) {
			print "Error: " . $response['error']['errormessage'] . "\n";
			exit;
		}
		return $response;
	}
 
?>

**
*

Hi Ryan,

Thanks for contacting us!

At the moment [scheduled maintenance] isn't possible I'm afraid, the only type of maintenance windows we currently have are in the beta version of beep manager, and these only allow the suspension of alerts.

However, we will soon be introducing this feature to allow you to schedule maintenance windows.

In the meantime you can pause the checks before the maintenance windows and then start them up again after, this unmonitored time would not show up as downtime in the public status page or the reports. It can be automated with a bit of coding and using our API, documentation here:

https://www.pingdom.com/features/api/documentation/

Don't hesitate to contact us again if you have any further questions, comments or feedback for us.

Best regards,
Andreas Larsson
www.pingdom.com

* thx gthomas!

Recently I was in charge of a computer programming contest where we needed VM environments for each participant. I launched the ec2 console (https://console.aws.amazon.com/ec2), spun up a new amazon linux instance, configured it with a LAMP stack and vsftp, modified /etc/sshd/ssh_config to allow password ssh auth (for the config step), set apache to run as ec2-user and set ec2-user’s home directory to be /var/www/html. Also, I configured sudo to not require tty. I configured vsftp to use ports 20, 21 and 1024-1048. I added those ports to the launch-wizard-1 security group. Then I created an image(AMI) of that machine (ami-MYAMI).

Then I wrote this bash script which loops through a string array of usernames and spins up a new VM with a custom password for that user, displaying the user, password, and FQDN (tab delimited) for that instance on the screen:

user@local:~/amazon$ ssh -i passfile.pem ec2-user@FQDN.compute-1.amazonaws.com
[ec2-user@ip-INTERNAL_IP]$ cat create_instances.sh
#!/bin/bash
array=( entrant23 entrant24 entrant25 entrant26 entrant27 entrant28 entrant29 entrant30 entrant31 entrant32 entrant33 )
for i in "${array[@]}"
do
	INSTANCE_ID=`ec2-run-instances ami-MYAMI --instance-type c1.medium --group launch-wizard-1 -z us-east-1e -k keyname|grep 'INSTANCE'|awk '{print $2}'`
	SET_NAME=`id=$INSTANCE_ID;name=$i;ec2-create-tags $id --tag Name=$name`
	sleep 30s
	URL=`ec2-describe-instances | grep INSTANCE|grep $INSTANCE_ID|awk '{print $4}'`
	PASSWORD=`date +%s | sha256sum | base64 | head -c 8 ; echo`
	sleep 2m
	CHANGING_PASS=`ssh -i passfile.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ec2-user@$URL "sudo echo 'ec2-user:$PASSWORD' | /usr/sbin/chpasswd"`
	FTP_IP=`ec2-describe-instances | grep INSTANCE|grep $INSTANCE_ID|awk '{print $14}'`
	CHANGING_FTP_IP=`ssh -i passfile.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ec2-user@$URL "sudo /usr/bin/perl -p -i -e 's/IP_HERE/$FTP_IP/' /etc/vsftpd/vsftpd.conf"`
	RESTARTING_FTP=`ssh -i passfile.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ec2-user@$URL "sudo /sbin/service vsftpd restart"`
	echo -e "$i\t$URL\t$PASSWORD"
done

The next step is to remove those pesky sleep statements and instead fire up all the instances at the start, and then create a wait loop checking statuses and sleeping, say 15 seconds. Once they come online, then run the post-launch steps (changing passwords, ftp settings, restarting ftp.)

One caveat– Amazon limits accounts to 20 VMs to start with. If you want more, you can request more, but that request could take up to 2 days to be approved. In my case, I used a personal account as well to created the instances we needed (40.)

LY3-enThanks to Quanta, the company no one has ever heard of, but which company makes all of Facebook’s servers and switches, for 6 or 7 grand, you can now get a 48 port Ethernet switch with 48 10GB ports, 8 of which are fiber. That’s nuts.

A friend dropped by last night with two Quanta T3040-LY3 and wanted to get them configured. I fired up the Byrd Super Lab, and with some cat6 cables I had laying around, I created an eight port MLAG connection between the two Quanta switches. Then I set up port channels for many of the 48 ports and then used LACP on the Linux side to create redundant paths for my test network.

photo(11)You should know there isn’t presently a lot of Google search results outside of retail establishments for Quanta hardware. So hopefully this post will be a good starting point for many people. I think you’ll find that the Quanta CLI is very similar to Cisco IOS. That said, there are some annoying differences. There is no enable mode, even though the manual refers to it and lets you set in and enable password. Also some commands cannot be undone by putting the word “no” in front of them like you can with Cisco. As well, it seems impossible to disable router rip or router IPv6. Hopefully someone from quanta can weigh in here and let us know what’s up.

That said here’s a sample of config for MLAG and LACP. Also I’ll provide a longer config for Quanta so that you can see how create VLANs on port channels running over MLAG.
mlag doc

Yes, I said MLAG. Some people call it MCLAG, but basically you contect two switch together with dedicated ports. Since they’re not Cisco switches, there’s no magical stacking cable included with these Quanta Servers.

It’s demeaning to refer to yourself as a dummy if you’re not, isn’t it? Here is the second session of PHP Programming for those non-dummies who want to get up to speed with this web programming language. Spoiler: you get to find a terrorist!

Other topics include FizzBuzz, Arrays, Functions, Objects and Forms. And Big-O notation. And, again, you get to find a terrorist.

Or, if you prefer, the PDF version of PHP Training Session Two

You’re not dumb, so why should the trainings be?

Here (below) is a quick introduction to PHP programming for the generally intelligent but uninformed would-be programmer. You’ll learn about conditionals, control structures(loops), operators and such. Originally, we planned on catching evil-doers (terrorists), but that will have to wait for session 2.

Or, if you prefer, the PDF version of PHP Training Session One

Imagine you have a set of cards. On one side of each card is a letter and on the reverse side of each is a number. You lay down four such cards:
A F 2 7

Your task is to determine which cards you must flip over in order to show that the following statement holds true: “If there is a vowel on one side of the card, there is an even number on the other side.”

This nagiosified Bash script sends a JSON payload to a webservice and parses the output for an expected string:

[root@server apitest]# ./webservice_check.sh
Usage: ./webservice_check.sh [API_NAME]
[root@server apitest]# ./webservice_check.sh service1
OK - service1 API working
[root@server apitest]# cat webservice_check.sh
#!/bin/bash
 
if [ $# -ne 1 ]; then
        echo "Usage: $0 [API_NAME]"
        exit
fi
E_SUCCESS="0"
E_CRITICAL="2"
case "$1" in
'service1')
API_NAME="service1"
URL="https://******.example.com/api"
JSONPAYLOAD='{"auth": {"type" : "basic","password": "******","username": "******"},"requestId" : 15,"method": {"name": "service1"}}'
COMMAND_STRING="curl -s -H \"Content-type: application/json; charset=UTF-8\" --data '$JSONPAYLOAD' $URL 2>/dev/null"
OUTPUT=`eval $COMMAND_STRING`
EXPECTED_RESULT="result"
;;
*)
echo "INVALID API Argument"
exit 1
esac
 
if grep -q "$EXPECTED_RESULT" <<< $OUTPUT; then
        echo "OK - $API_NAME API working"
        exit ${E_SUCCESS}
        else
        echo "CRITICAL - $API_NAME API not working"
        exit ${E_CRITICAL}
fi

Next Page »

Send to a friend * Print this page * Join the club * Talk with my robot * Advertise here * Search this Site * Donate * Link to me


Web hosting by Utah Hub *  Powered by CreativeTap *  In association with Segomo
Unless otherwise noted, Copyright 2004-2013, Ryan Byrd. All Rights Reserved.
Ryan Byrd dot net -- probably the coolest site in Utah