Thursday, August 8, 2019

RHEL7.7 dracut Failed to install module libnvdimmvmxnet3

I just upgraded one of my systems from RHEL 7.6 to 7.7. During the update, I got the following error:
dracut[43998]: Failed to install module libnvdimmvmxnet3
The fix is this: in /etc/dracut.conf.d/*.conf -- in my case, both nvdimm-security.conf and vmware-tools.conf, edit the "add_drivers" line to add a leading and trailing space. e.g. in nvdimm-security.conf, change:
add_drivers+="libnvdimm"
to
add_drivers+=" libnvdimm "
and in vmware-tools.conf, change:
add_drivers+="vmxnet3 vmw_pvscsi"
to
add_drivers+=" vmxnet3 vmw_pvscsi "
Then, run "dracut --force" to rebuild your initramfs. You should no longer get the "Failed to install module libnvdimmvmxnet3" error. The reason for the problem is that dracut is concatenating all the "add_drivers" strings together, without any processing. See the dracut.conf man page for the warning that was apparently ignored by the open-vm-tools folks: "Space-separated lists have to have a leading and trailing space"

Tuesday, June 4, 2019

rpm command pauses for 20 seconds

I'd just built a new system and found that when I issued any 'rpm' command, it paused for 20 seconds before doing anything.

Turns out that I had a build error in my kickstart, and it made /etc/hosts empty! So 'rpm' was trying to do a DNS lookup on 'localhost' and timing out. I don't know why rpm needs to do a lookup at all, but..

In any case, the fix was to add the "standard" /etc/hosts entries for localhost:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

Tuesday, April 2, 2019

How to use firewalld to filter traffic to docker

Note: My platform is on Docker CE 18.09 on Centos 7. YMMV I only recently started using docker, but there is one very important thing you need to know:
By default, all external source IPs are allowed to connect to the Docker daemon

Filtering by IP is actually easy once you know how, but I had a hell of a time finding the key information and for me that was three-fold:
1. If the "DOCKER-USER" chain is not present when Docker starts, Docker will add it and allow all connections being passed to it, therefore:
2. You must stop the docker service before configuring the DOCKER-USER iptables chain
3. You must add the DOCKER-USER chain (and rules) before the docker service starts

partial reference: https://github.com/moby/moby/issues/35043

i.e.:

service docker stop
firewall-cmd --permanent --direct --remove-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --remove-rules ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 1 -i ens224 -s 1.2.3.4 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 2 -i ens224 -s 5.6.7.8 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 3 -i ens224 -j DROP
service firewalld reload
service docker start

Friday, October 19, 2018

yum repolist without connecting to repos


Here's how you get yum to list all the configured repos, without actually connecting to any of them (e.g. if your system is offline):

yum -C repolist all

The "-C" option tells yum to use the local cache, no matter how old the cache is.


Wednesday, August 15, 2018

Windows Schannel error event ID 36871 a fatal error occurred while creating an SSL server credential. The internal error state is 10011


I recently encountered this error on a Windows 7 system, after a vendor-provided update to some third-party software.  RDP stopped working after the update, and the problem turned out to be layered.  The TL;DR version is this:  FIPS was enabled but the Cipher suite settings did not have any FIPS-compliant algorithms defined.

First, the simple part:  the vendor disabled RDP via GPO.  That's an easy thing to undo and I won't detail it here.

But even after enabling RDP via GPO, it still wouldn't work.  The RDP client wouldn't connect.  When I connected with openssl s_client I got this:

# openssl s_client -connect system:3389
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 247 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
Looking in the Windows Event Log, I found an error from Schannel with Event ID 36871, and the error text "a fatal error occurred while creating an SSL server credential.  The internal error state is 10011."

I eventually narrowed this down to the fact that the vendor had turned on FIPS-compliant algorithms.  However, on this system, I had set the allowed cipher suites to "modern" algorithms like ECDHE-RSA-AES256-SHA384, which is not FIPS-compliant but is more secure; i.e. FIPS-compliant algorithms are old and less secure.

So the fix was to disable FIPS again.

Wednesday, August 9, 2017

Setup meinberg NTP client on Windows Server 2012 using ntp service account


I recently attempted to install the Meinberg NTP client on a Windows Server 2012 system, but ran into a problem during the installation.  At one point, the installer asks you what account to use for the service:  1)  a newly-created "ntp" service account, or 2) run as SYSTEM (there might be a third option, I don't remember.

Running ntp as SYSTEM seems like asking for trouble; you should always run services with the least privileges required.  So of course I chose to use the "ntp" service account.  I had successfully used it before on Windows 7 systems.

However, upon clicking "Next", the installer crashed!  Looks like the installer created an "ntp" account, but it was disabled, and had no password set.  Also, the service was not installed.

Here's what I did to workaround the issue:

  1. Run the installer again, this time using the SYSTEM account for the service
  2. Manually create the "ntp"user.  (optional:  set password to never expire)
  3. Open gpedit.msc 
  4. Under Local Computer Policy/Computer Configuration/Windows Settings/Security Settings/Local Policies/User Rights Assignment, add "ntp" to the following:
  • Change the system time
  • Deny access to this computer form the network
  • Deny log on as a batch job
  • Deny log on locally
  • Increase scheduling priority
  • Log on as a service
That done, you can open "services.msc" and change the service to log on as the "ntp" account.  Then restart the service.

Friday, August 4, 2017

Bonnie Tyler - Total Eclipse of the Heart - lyrics to the second verse

The complete lyrics to Bonnie Tyler's "Total Eclipse of the Heart" are nowhere to be found on the internet! They are all missing the second verse. I think this is it (transcribed by me)
Turn around, every now and then I get a little bit reckless
and I dream of something wild
Turnaround, every now and then I get a little bit helpless
and I'm lying like a child in your arms
Turnaround, every now and then I get a little bit angry
and I know I've got to get out and cry
Turnaround, every now and then I get a little bit terrified
but then I see the look in your eyes
Turnaround bright eyes, every now and then I fall apart
Turnaround bright eyes, every now and then I fall apart

Thursday, May 5, 2016

get vCenter Server or Replication appliance update URL from command line using xmllint

My vCenter appliances (Server and Replication) are on an internal network and cannot get to the outside world. To update them, I mirror the update repositories on an internal web server, using the script from http://www.virtuallyghetto.com/2013/05/how-to-create-offline-update-repository.html

The script requires the update URL, which is easy to get manually from the appliance web interface, but I want to automate the update.

I found that the default update URL is stored in

/opt/vmware/var/lib/vami/update/provider/provider-deploy.xml
and the user-entered update URL is stored in
/opt/vmware/var/lib/vami/update/provider/provider-runtime.xml

The appliances come with some command-line tools to parse XML; I'm using xmllint:

echo 'cat //property[@name="repositoryAddress"]/@value' | \
xmllint --shell /opt/vmware/var/lib/vami/update/provider/provider-deploy.xml | \
grep https
The output:
value="https://vapp-updates.vmware.com/vai-catalog/valm/vmw/05d561bc-f3c8-4115-bd9d-22baf13f7178/5.8.1.12927.latest"


Thursday, August 27, 2015

Fark Lite tampermonkey script updates

Updated Fark Lite to work with the current version of Fark.com (as of 2015-08-27)

download here

/*
 Fark Lite
 Copyright (c) 2005, Rick Fletcher 
 Released under the GPL license
 http://www.gnu.org/copyleft/gpl.html

 --------------------------------------------------------------------
 This is a Greasemonkey user script.

 To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
 Then restart Firefox and revisit this script.
 Under Tools, there will be a new menu item to "Install User Script".
 Accept the default configuration and install.

 To uninstall, go to Tools/Manage User Scripts,
 select "Fark Lite", and click Uninstall.
 --------------------------------------------------------------------
 
 Changelog

 0.3 2015-08-27 RCJ 
        update for Fark changes
 0.2.2  2005/10/08
  bug: no longer hiding the "view voting results" link on the comments page
 0.2.1  2005/10/03
  bug: updated to work with updated fark.com source
 0.2    2005/10/02
  new: refactored to use XPath
 0.1    2005/07/20
  initial release
*/

// ==UserScript==
// @name          Fark Lite
// @version       0.3
// @namespace     http://flet.ch/things/greasemonkey/
// @description   Strips fark.com down to just the links.  Hides links from categories you don't want to see.
// @include       http://*.fark.com/*
// @include       http://fark.com/*
// ==/UserScript==

(function () {

 var farklite = {

  config: {
   hide_search: true,           // remove the google search form at the top of the page
   hide_side_columns: true,     // remove the columns on either side of the page
   fix_link_target: true,       // make links open in the current window
   strip_passthru_script: true, // make links direct (instead of passing through the go.fark.com script)
   unwanted_categories:         // links that are in these categories will be removed
    [ "weeners", "satire", "video edit" ],
  },

  //fark_passthru_script_regex: /^http:\/\/\w+\.fark\.com.*l=([^&]+)/i,
  fark_passthru_script_regex: /^http:\/\/\w+\.fark\.com\/goto\/[0-9]+\/(.*)/i,

  // link_container_xpath: "//table[@class='nilink']/descendant::tr/td[position() = 1]/a",
  link_container_xpath: "//a[@class='outbound_link']",

  addCSS: function( css ) {
   var head = window.document.getElementsByTagName( "head" )[0];
   var style = window.document.createElement( "style" );
   style.setAttribute( "type", "text/css" );
   style.innerHTML = css;
   head.appendChild( style );
  },

  fixLinks: function() {
   var links = document.evaluate( this.link_container_xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
   for( var link = null, i = 0; ( link = links.snapshotItem( i ) ); i++ ) {
    this.config.fix_link_target       && link.setAttribute( "target", "" );
    this.config.strip_passthru_script && link.setAttribute( "href", unescape( link.getAttribute( "href" ).replace( this.fark_passthru_script_regex, "http://$1" ) ) );
    this.config.strip_passthru_script && link.setAttribute( "onmouseover", "" );
    this.config.strip_passthru_script && link.setAttribute( "onmouseout", "" );
   }
  },


  removeUnwanted: function() {
   for( var i = 0; i < this.config.unwanted_categories.length; i++ ) {
    this.config.unwanted_categories[i] = this.config.unwanted_categories[i].toLowerCase().replace( /[^a-z]/, "" );
   }

   var link_category_xpath = "//tr[@class='headlineRow']/descendant::img[translate(@alt,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='" + this.config.unwanted_categories.join( "' or translate(@alt,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" ) + "']/parent::*";
   var links = document.evaluate( link_category_xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
   for( var link = null, i = 0; ( link = links.snapshotItem( i ) ); i++ ) {
    link.parentNode.parentNode.removeChild( link.parentNode );
   }
  },
 }

 farklite.addCSS( "td.howto, form div.howto:first-child, .banhead div, div.footnote { display: none; }" );
 farklite.config.hide_search       && farklite.addCSS( ".banhead form { display: none; }" );
 farklite.config.hide_side_columns && farklite.addCSS( ".newtoolbar, .entirelefttoolbar, .entirerighttoolbar { display: none; }" );
 
 farklite.removeUnwanted();
 farklite.fixLinks();
 farklite.fixLinks2();

})();

Wednesday, July 15, 2015

Juniper Network Connect and Crashplan use the same network ports

I actually found this problem months ago. Today I decided I needed to blog it mostly as a reminder to myself.

After upgrading CrashPlan on my computer, I found that the service would not start. The tray icon reported "unable to connect to the backup engine".

CrashPlan has a good article on the problem and how to fix it.

A solution not listed -- uninstall Juniper Network Connect! (I didn't need it any more)

Tuesday, July 14, 2015

Open a console to a virtual guest on ESXi or vSphere cluster

This entry ties in nicely with a previous entry I made about creating SSH tunnels for vSphere.

Unfortunately, when you setup SSH tunnels for the Windows vSphere client (or even for the vSphere web client), you cannot open console windows to the guests using the normal methods -- they will always fail to connect.

To workaround this, use VMware's "Remote Console" program to connect through the tunnel to the host. Note that the tunnel must go to the host on which the guest is running.

Steps:

  1. Install VMware Remote Console (in Vmware downloads, vsphere 5.5, "Drivers & Tools" tab)
  2. find out the VMID of the desired guest using the ESXi cmd line:
        vim-cmd vmsvc/getallvms
  3. open url (assuming host tunnel is 127.0.0.4):
       vmrc://root@127.0.0.4/?moid=vmid
    where vmid is the id you found; e.g. if the ID is 29:
       vmrc://root@127.0.0.4/?moid=29

In case it is not obvious, you open the URL from the command prompt:

cd C:\Program Files (x86)\VMware\VMware Remote Console
vmrc.exe vmrc://root@127.0.0.4/?moid=29

Saturday, April 25, 2015

Use imagemagick to apply a GIMP gradient colormap (.ggr file)

I love using JHelioviewer to create amazing videos of the Sun using pictures from SDO (the Solar Dynamics Observatory).

However, jHelioviewer has a maximum of 1000 frames -- which is about 3 or 4 hours of SDO images (if you use every image taken). Another problem is that is nearly impossible in jHelioviewer to crop the frame in an exact way.

I already knew how to create a movie from a sequence of images using ffmpeg. However, the AIA images you download from SDO JSOC are grayscale; i.e. they don't have the standard SDO color maps.

JHelioviewer applies the SDO color maps using these GIMP gradient files, but I didn't know how to use imagemagick to apply GIMP gradient color maps.

ImageMagick can apply color maps, but they must be in the form of a color lookup table (CLUT) image. But how does one convert a ggr file (a text file!) to a CLUT image? I found a lot of examples on the web on how to convert a CLUT to a GGR, but not the other way around.

According to this jHelioviewer wiki page, you can export the color tables from jHelioviewer using exportColorTables.java somehow, but I didn't feel like figuring out how to compile it -- and also I didn't want to install the JDK.

So I posted a question on the imagemagick forums. You can go read the forum if you like, but I've summarized it here:

  1. Create a standard hald clut image using the imagemagick program "convert" from the command line:
    1. convert hald:8 hald.png
  2. Install GIMP
    1. Install ggr files in your GIMP configuration directory (on Windows 7 this is %USERPROFILE%\.gimp-2.8\gradients)
  3. Start GIMP and open hald.png
  4. Select All
  5. In the Layers Dialog, select the Gradient Tool, then select the desired gradient
  6. Apply the gradient by selecting Colors -> Map -> Gradient Map
  7. Export the file by selecting File -> Export As ... (save it as a PNG or BMP)
The resulting hald CLUT images are here:

Now, to apply any of the above color maps to a grayscale image, you do, e.g.:

convert gray-image.jp2 sdo-aia-171-colormap.png -hald-clut color-output.jpg

Thursday, April 2, 2015

Symantec 12.1.5 on Linux LiveUpdate failures -- BouncyCastleProvider

TL;DR version: To fix this, temporarily remove the "noexec" mount option from /tmp and run the install.sh program again.

We recently started using Symantec 12.1.5 on our Linux systems at work. I installed the client on a test system and immediately had issues with LiveUpdate:

/opt/Symantec/symantec_antivirus/sav liveupdate -u
Picked up JAVA_TOOL_OPTIONS:
Command failed: Problem with LiveUpdate.
Check that java directory is in PATH
Unable to perform update

In liveupdt.log:

Apr 1, 2015 11:32:26 AM There was a failure in reading the settings from the .conf file.
Apr 1, 2015 11:32:26 AM org.bouncycastle.jce.provider.BouncyCastleProvider
Apr 1, 2015 11:32:26 AM JLU received a DeleteSetting command.

Running Liveupdate in debug mode:

java -cp /opt/Symantec/LiveUpdate/jlu.jar com.symantec.liveupdate.LiveUpdate -d
Using character set UTF-8
Command-line Product Selections to update:
(ProdName, Version, Lang, ItemSeqName, SeqNum)
Debug - output[nIdx] = uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_java_t:s0-s0:c0.c1023
Adding JLU to the current command line
JLU Linux, 3.10, English, LiveUpdateSeq, 26
Trying to load jar file from /opt/Symantec/LiveUpdate/bcprov-jdk15on-148.jar
Trying to load jar file from current directory or mentioned in classpath
JLUException [
Nested Exception is:
[ java.lang.ClassNotFoundException ] org.bouncycastle.jce.provider.BouncyCastleProvider

java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider
at java.net.URLClassLoader.findClass(Unknown Source)
[...]

I will leave out the frustrating troubleshooting my coworker and I did and give you the reason: Our security configuration specifies that we set the "noexec" mount option on /tmp.

Unfortunately, the Symantec install script requires exec on /tmp to install correctly. Specifically, it creates some temporary scripts in /tmp and runs them to install the BC (bouncycastle) provider. Here's an excerpt from the sepjlu-install.log:


Java LiveUpdate version 3.10 Build 26.
Extracted out unixinstall.sh to /tmp/1427202521861/unixinstall.sh.
Extracted out unixuninstall.sh to /tmp/1427202521861/unixuninstall.sh.
Extracted out liveupdate.conf to /tmp/1427202521861/liveupdate.conf.
Extracted out bcprov-jdk15on-148.jar to /tmp/1427202521861/bcprov-jdk15on-148.jar.
Copied /opt/Symantec/LiveUpdate/jlu.jar to /tmp/1427202521861/jlu-3.10.0.26.jar.
Error running /tmp/1427202521861/unixinstall.sh with reason: java.io.IOException: Cannot run program "/tmp/1427202521861/unixinstall.sh": error=13, Permission denied.

The script is supposed to copy bcprov-jdk15on-148.jar into $SYMROOT/LiveUpdate/, but obviously because "noexec" was set on /tmp, it couldn't run.

So in full, the solution is:


mount -o remount,exec /tmp
$INSTALLER_DIR/install.sh -i
mount -o remount,noexec /tmp

Wednesday, March 18, 2015

Cisco 7841 PC headset adapter

Since I couldn't find this information elsewhere, even on the manufacturer's page, so... This PC headset adapter works with a Cisco 7841 phone: http://www.amazon.com/Headset-Buddy-Adapter-CISCO-Phone/dp/B003EALLHE
also:
http://www.headsetbuddy.com/cisco-pc-headset-adapter
SKU: 01-PC35-RJ9Cisco

Friday, February 13, 2015

rancid 3.x - juniper display set

I found a lot of directions on the net for how to change rancid 2.x to do "display set" for juniper switches, but none for rancid 3.x (this was tested on rancid 3.1.2 on CentOS 6.6)

It's actually pretty easy:
  1. Find your switch type (in this case "juniper") in /etc/rancid/rancid.types.base and copy those lines into /etc/rancid/rancid.types.conf:

    juniper;script;rancid -t juniper
    juniper;login;jlogin
    [...]
    juniper;command;junos::ShowConfiguration;show configuration


  2. Now change "juniper" to some unique string that doesn't exist in rancid.types.base, e.g. "juniper-dset"
  3. Modify all the "juniper" strings in rancid.types.conf to be "juniper-dset"

    juniper-dset;script;rancid -t juniper-dset
    juniper-dset;login;jlogin
    [...]
    juniper-dset;command;junos::ShowConfiguration;show configuration


  4. Add a new line to do the display set:

    juniper-dset;command;junos::ShowConfiguration;show configuration | display set | no-more

    It's up to you whether you want that before or after the normal multi-line "show configuration".

  5. Also, change /var/rancid/router.db to change the "juniper" switch type to "juniper-dset"

Tuesday, January 27, 2015

linux: how to determine if a binary is prelinked

On my systems I use aide to find changes to the system. On one of them, aide was complaining:

WARNING: AIDE detected prelinked binary objects on your system but the prelink tool (/usr/sbin/prelink) is missing!
WARNING: prelinked files will be processed without a prelink undo operation! Please install prelink to fix this.

This is because at one point, I did in fact use prelink. However, I had many issues with aide and prelink and finally just got fed up and removed it. Before doing that you're supposed to undo the prelink, but apparently I missed a file. But aide didn't tell me which one! I couldn't find any information on the net about how to determine whether a binary is prelinked, so here's the answer:

readelf -S | grep prelink

If the binary is prelinked, you'll get something like:

[30] .gnu.prelink_undo PROGBITS 0000000000000000 000e4790

But what if you don't know which file is prelinked? And /etc/prelink.cache is non-existent (because someone removed it) or empty? In that case, you have to examine every ELF binary on the system. I elected to break this into two steps. First, find all the ELF binaries:

find / -type f ! -path "/sys/*" ! -path "/dev/*" ! -path "/proc/*" \
! -path "/opt/splunk/var/*" ! -path "/mnt/*" ! -path "/media/*" ! -path "/srv/*" \
! -path "/net/*" ! -path "/selinux/*" | xargs file | grep ELF | cut -f1 -d':' \
> /tmp/elffiles

Now that you have a list of all the ELF binaries, test each of them to find out if they are prelinked. I did not use xargs in this case because although readelf works on multiple files, when combined with grep it would be hard to tell which of the arguments in the long argument list is the culprit:
for file in $(cat /tmp/elffiles) ; do
   readelf -S $file | grep -q prelink
   if [ $? -eq 0 ]; then echo $file is prelinked ; fi
done

I realize the above doesn't handle paths with spaces or other weird characters. I guess I'm lucky my system didn't have any of those.

Wednesday, January 14, 2015

Dell PERC command-line utility program perccli

This tool apparently works for all PERC9 controllers and the following operating systems are supported:
Novell SuSE Linux ES 11 
MS Windows Server 2012 
Red Hat Ent Linux 6 
Red Hat Ent Linux 7 
SUSE Linux ES 12 
MS Windows Server 2012 R2/SP 
MS Windows 2008 R2

Binaries are at: http://www.dell.com/support/home/us/en/19/Drivers/DriversDetails?driverId=3XDPP

HTML version of manual: http://www.dell.com/support/Manuals/us/en/19/Topic/poweredge-rc-h730/PERC_CLI_RG_Pub-v1/en-us

PDF of manual: http://topics-cdn.dell.com/pdf/poweredge-rc-h730_Reference%20Guide_en-us.pdf

Monday, January 5, 2015

Phonetic Alphabet of Confusion

I wanted to make a phonetic alphabet chart, but with words that all have the "wrong" sound at the start. e.g.A as in "aisle" I shamelessly stole most of this from

http://www.reddit.com/r/videos/comments/2g3fcw/i_had_another_phone_scammer_try_to_call_me_so_i/ckfs07x

I'd wanted to use words instead of names if possible (e.g. for "I", I'm used "Ian" because I couldn't find a word that starts with I but has an "e" or other sound.)

I thought about going through the Wiktionary database but that will take a while to program maybe...

Anyway, here's what I have so far:

A - aisle
B - bdellium
C - czar
D - djinn
E - euphrates
F - effluent (I would prefer a word that starts with "F")
G - gnome
H - honor
I - Ian  (can you think of a word not a proper name?)
J - jalapeno
K - knickers
L - elephant (I would prefer a word that starts with "L")
M - mnemonic
N - Nguyen (resorted to foreign language here :( )
O - ouija board
P - pterodactyl (bonus:  P sounds like T ) 
Q - qat
R - arse (I would prefer a word that starts with "R")
S - schadenfreude (can you think of a non-foreign word that starts "sch"
but sounds like "ch"?)
T - Tsunami (foreign origin, but has been adopted as English so I don't
feel bad about this one)
U - urn
V - vrow (frau) (optionally "vee") 
W - wren
X - Xian  (X is weird anyway, most words sound like "Z" anyway, so I
went with an "Sh" sound (Shee-an) instead! but again - it's a foreign
name, can't think of a word)
Y - yperite
Z - Zsa Zsa  (proper name :( )

Sunday, June 1, 2014

Perl script to quiz you for ARRL Ham radio exam

I've been studying for the Technician class amateur radio license. The ARRL sells a book that includes a CD with some nice software for practicing tests. However, if you don't have the book and/or CD, you might want to practice the test questions anyway. So I wrote a perl script that reads the text version of the question pool ( 2010 version or 2014 version), then asks you questions from it. example run:
# study.pl ~/Downloads/question_pool.txt

enter question # (blank for random question) or Ctrl-C to exit :

T6B07
What does the abbreviation "LED" stand for?
A. Low Emission Diode
B. Light Emitting Diode
C. Liquid Emission Detector
D. Long Echo Delay


answer? A
*** WRONG!      correct answer is (B)

enter question # (blank for random question) or Ctrl-C to exit :

T7A07
If figure T5 represents a transceiver in which block 1 is the transmitter portion and block 3 is the receiver portion, what is the function of block 2?
A. A balanced modulator
B. A transmit-receive switch
C. A power amplifier
D. A high-pass filter


answer? b
CORRECT!
Download the script

Thursday, April 3, 2014

Automating the VMware vSphere Perl SDK install with expect:


I couldn't find any other postings on the net about this, so here's my solution for automating the installation for the VMware vSphere Perl SDK on RHEL6 (this assumes you already have all the prerequisites installed.).  It probably works on any Linux OS but I only tested it on RHEL6.4.

Save this expect script (requires expect to be installed, duh!) in the same directory as the extracted tarball for the SDK (probably vmware-vsphere-cli-distrib/):
#!/usr/bin/expect

set timeout 120

spawn "./vmware-install.pl"

expect "Press enter to display " { send "\r" }
expect "vSphere Software Development Kit License Agreement" { send "q" }
expect "Do you accept" { send "yes\r" }
expect "Do you want to install precompiled Perl modules for RHEL" { send "\r" }
expect "In which directory do you want to install the executable files" { send "\r" }
# Wait for installation to finish
expect EOF
This accepts the defaults ("yes" to installing precompiled perl modules, "/usr/bin" for the installation directory) If you don't like that, edit the script!