Xenoblade Chronicles 2 Review

I bought Xenoblade Chronicles 2 as a fluke- I’d heard the first one was good, and there was an article prior to it coming out suggesting that it was the game to play after Breath of the Wild. Well, I’ve put a week or so into it so far and here are the takeaways.

  • The battle system is an over-complicated mess where you don’t actually battle, you just wait for permission to press buttons. It’s completely chaotic and near impossible to follow and you feel like a spectator rather than a participant.
  • Once a battle is done, all damage is healed. There’s no consequences. other than dying and having to “try again”
  • Oh, each of these battles takes an eternity to finish. Walk from point A to point B, and have 30 battles. But if you die half way through, you get to go back to the beginning and do it all over again.
  • The map system sucks, as does the fast travel. You can’t scroll the overlay map to figure out where you need to go, just follow the stupid compass arrow and hope it’s leading you the right way (it’s led me to solid walls already, resulting in me giving up on that side quest. The fast travel screen is just unintuitive, and the map it shows doesn’t correlate with the overlap map in any meaningful way.
  • The voice acting. My god- I was embarrassed when the first mustashe-twirling govenor guy showed up because it sounded like… I don’t know, like a horrible person doing a Scotty from Star Trek impression.

I’m on chapter 3, and at this point it feels like a trudge. to get through the game. I keep hoping it’ll get better, but it isn’t. and to top it off, I bought the digital download like a fool so I can’t even resell it. I just spent 3 hours grinding my way to the next section only to die and start over.

What a disappointment.

 

Monoprice Maker Select Plus Upgrades

Because I don’t know when to stop, I’m going to start working on upgrades for my printer.

 

1. Filament Guide

Apparently one of the common problems is that slack in the filament can cause tangles- the best way to work around this is a filament guide. The first filament guide I printed was loose- too loose to use by itself. The second style just didn’t print properly, even trying to print it 2 different ways. I ended up using a command strip to stick the first one in place, and that seems to be working for the time being. Perhaps later I can modify the model and make it a little better fit.

2.  Thumbwheels

Another common problem is that the all-metal thumbwheels will jiggle free over time, causing the bed to unlevel. The Solution is to use nylon locking nuts (nylock nuts) , but they’re so tiny you wouldn’t be able to adjust them- that’s where the 3d printed thumbwheels come in. The nylocks go on the underside of the printed thumbwheel, allowing better control and a more coarse texture than the metal thumbwheels. So far they’re working well.

3. Octoprint

While it’s not a direct mod, I printed a 3d case for a raspberry pi and loaded the pi with a custom OS called Octoprint. It controls the printer over USB so you’re not constantly inserting and removing sdcards. In addition, it gives you a nice web interface where you can upload your gcode files, track the print progress, and tweak configurations. It even lets you time-lapse control a pi camera to see the status and verify things haven’t went off the rails.

4. Allen Wrench and Scraper Hook Support

This is more of a utility modification than anything- with the 3d prints, you usually need to scrape the print off the bed when it’s complete, which means you have a standard scraper always laying around. This gives you a hook to store the scraper on, as well as slots to place the allen wrenches.

5. Fun Fan cooler

My original intention was to go with the Dii cooler, but after some investigation I came across the fun fan cooler, which looks like an earwig’s behind.  it has a few print flaws which I’m going to attempt to fix and re-release it on thingiverse. So far it’s greatly improved the quality of my prints. Update: My attempt to fix the model failed miserably. I still have a lot to learn about organic modelling.

6. Pi Cam Arm

I’ve found a decent arm/camera holster for my raspberry pi camera, which should allow me to create timelapse videos. I still don’t have a great base due to the short cable I’m working with, but that should be remedied tomorrow. In the mean time, here’s a video:  https://goo.gl/photos/AiX6PCX5Z45nR1Bu8  This was my second print of the Earwig vent/ Fun Fan Cooler.

7. Glass Bed

My glass bed has arrived, but the thermal pad won’t be here until Saturday. Between now and then I’ll have to print clips.

 

Future Plans

Right now I’m planning on the following upgrades:

  1. Z braces. I saw the tower shake a surprising amount during quick y axis movements- Z braces basically add a hypotenuse to the intersecting structure of the printer. The ones I’m looking at will have levelling feet. Update: Unfortunately, these are for the maker select, not the select plus, so they won’t fit. I’ll need to design my own.
  2. Metal Hotend with slotted block. Microswiss makes a nice hotend that supposedly works much better.
  3. Hardened steel nozzle. Another Microswiss upgrade that’ll let me work with a wider array of materials and temperatures.
  4. Machined lever and extruder plate. The existing level that holds the filament in place will warp over time- this one won’t.

Overall this has been an interesting diversion so far.

 

Time to Print

After finally getting my 3d printer, I thought I should start keeping track of what I’m doing.

Printer: Monoprice Maker Select Plus

Standard Filament: MP Select PLA Plus+ Premium 3D Filament (white)

After Unboxing it and getting everything aligned, I printed 1.gcode and 2.gcode from the SD card that came with it using the yellow PLA filament that came with it. The first was a small elephant, the second was a swan.

Quick Backstory

I had played a bit with FreeCAD while waiting for the print and had followed a tutorial for creating a “lego.”

As you may or may not know, There are 2 steps in designing a 3d part

  • designing the regular 3d object in 3d modeling software like 3DSM, Maya, Blender, FreeCAD, etc to create an STL file.
  • converting the STL with a slicer program like Cura into a gcode file.

The Gcode is basically a set of assembly-like instructions for controlling the printer- move 2mm, extrude, move 3mm, retract, travel 10mm, etc. What’s important to note is that Cura needs to be configured for your specific printer model.

  • The good news is that Monoprice ships with a free copy of Cura
  • The bad news is that they only include the exe version
  • The good news is you can run it with wine
  • The bad news is that it’s not only in chinese(?), but fails to install with an error (that is also not in english).

This makes it really hard to configure Cura properly. My first attempts did not go great, but after doing a bit of research, I found that the  “Prusa i3 Mk2” model was “close enough” with some minor modifications:

Monoprice Maker Select Plus Cura Settings, Mostly correct

 

Back to the Real Story

The Lego

After some tinkering and trial and error, I was able to print my self-designed lego sliced with my own copy and configured version of Cura, however somewhere along the way it became supersized. It fits roughly 3 regular lego pegs to every 2 on my block. I’m not sure where things fell apart, but I need to re-examine the FreeCad file and get the calipers out to figure out if the instructions were wrong or if I did something incorrect.

Anyways, the Lego used up almost the last of my sample yellow, so I opened my new standard filament, the white PLA from monoprice.

The Drow Wizard

The first thing I printed was a Drow Wizard from Shapeways. it was fairly complex, and so-far the printer is completely untuned, so it’d give me a good idea of what I’m working with.

It was pretty rough. There were a lot of strings between the staff and the figure, and the face had no detail. After a bit of cleanup, it’d be passable for kids, but it was still lower quality than I was hoping for

The Filament Guide

The next thing I printed was the filament guide upgrade for the printer itself. This was my first time using a support, and man did it waste a lot of filament. After some cleanup, it came out decent, but still had some print flaws- namely a hole in the top of the guide arm where the top layer wasn’t think enough and inside the “C” at the top, the edges pulled away from the rest of the print. It’s probably still usable, but I’ll eventually print a better one.

The first “real use” part was a Raspberry Pi 3 case I found on Thingiverse. The Top came out rather nice (but still has some flaws), and I’m waiting for the bottom to finish as I type this.

While waiting, I’ve done a bit of research on some of the flaws I’ve noticed and am coming up with a list of things to try. Before I make any further adjustments, I’m going to print a 3dSketchy boat that is commonly used for calibration tests. Once I do that, I’ll probably print 3 or 4 more, trying different configurations and tweaks.

 

3d Printer Ahoy!

I’ve finally gotten the go-ahead to get a 3d printer. It’s something I’ve wanted for a long time, but I’m just now at the point where I can get into it. As I wait for my tax return, I’ve started learning how to use Freecad.

 

So far I’ve finished the following tutorials:

  • https://www.freecadweb.org/wiki/Basic_Part_Design_Tutorial
  • https://www.freecadweb.org/wiki/Aeroplane
  • https://www.freecadweb.org/wiki/Manual:Modeling_for_product_design
  • https://www.freecadweb.org/wiki/Sketcher_tutorial (2017-03-26)

It’s taken a bit of time, but I’m slowly getting there. With any luck I’ll be fabricating parts with relative ease, then can move on to sculpting with blender.

 

A Brief Review of Ansible Redis Modules

I’m currently investigating the best ansible module to manage redis for my server. The good news is that ansible galaxy has plenty of options; the bad news is that most of them are terrible. This is my first attempt to find the best of the bunch.

 

For the sake of simplicity, I’m limiting my search to roles that support Enterprise_Linux (e.g. Redhat, Centos, etc). In addition, I’m going to be examining the github repos rather than the galaxy entries.

 

It’s important to note that I’m not judging the authors, only their usefulness to me.

https://github.com/hostclick/redis

Last Commit: Sept 15th, 2015

Commits: 2    Contributors: 1

Branches: 1    Releases: 0

Pros:

  • Default values used
  • Remi repo used
  • config templatized
  • vars used

Cons

  • Installs its own Remi repo config
  • docker stuff included
  • extensive template hardcodeds content
  • README example is limited.

https://github.com/jtyr/ansible-redis

Last Commit: May 25th, 2016

Commits: 15    Contributors: 3

Branches: 1    Releases: 0

Redis versions supported explicity: 2.4, 2.6, 2.8

Pros:

  • Extensive defaults
  • simple tasks and template
  • Estensive README

Cons:

  • overly simplistic module, complex variables
  • uses default redis package

https://github.com/officel/ansible-role-redis

Last Commit: September 8th, 2016

Commits: 5    Contributors:1

Branches: 1  Releases: 0

Pros:

  • includes spec file
  • enables remi and epel repos

Cons:

  • includes docker for tests
  • doesn’t include repos as requirements

https://github.com/sbaerlocher/ansible.redis

Last Commit: September 27th, 2016

Commits: 7    Contributors: 1

Branches: 1    Releases: 3

Pros:

  • Good Defaults
  • Excellent README
  • multilayer vars configuration
  • includes test playbook and inventory
  • Supports multiple distributions

Cons:

  • complex vars configuration
  • default packages only, no repo support

https://github.com/AerisCloud/ansible-redis

Last Commit: June 20th, 2016

Commits: 5    Contributors: 3

Branches: 1     Releases: 3

Pros:

  • includes good repo dependencies

Cons:

  • Poor defaults
  • Bad formatting with redirects
  • Bad README

https://github.com/mrlesmithjr/ansible-redis

Last Commit: June 7th, 2016

Commits: 18    Contributors: 1

Branches: 1     Releases: 0

Pros:

  • includes performance tweaks

Cons:

  • includes docker file
  • bad defaults
  • mentions epel, no include or dependencies
  • no repo dependencies
  • Poor vars

https://github.com/dgnest/ansible-role-redis

Last Commit: March 10th, 2016

Commits: 36    Contributors: 1

Branches: 2    Releases: 6

Pros:

  • includes build status

Cons:

  • No repo dependencies
  • Weird tasks layout
  • Configuration not really EL specific (more debian than Redhat)

Results

Wow…. that was, uh, painful. The good news is a lot of them are still active, though the number of commits is relatively low. across the board. The low commit numbers could mean one of two things:

  1. Ansible roles are easy to get right the first time, or
  2. they’re slapped together and not really polished.

There’s a few we can rule out straight away: mrlesmithjr, dgnest, AerisCloud- there just wasn’t a lot of useful content.

 

That leaves hostclick, jtyr, officel, and sbaerlocher with useful content. I think the right answer will be to roll my own taking parts from each. I’ll give it a closer look tomorrow.

 

Update: AAAND I feel dumb. I didn’t notice during my first search that those were the first 10 results- 3 rows of 3 and one row of 1 made it look like that was the end of the list.

 

I’ll have to re-evaluate, probably based on “most downloaded.”

Puppet Enterprise + firewall = pain.

I’ve been tasked with setting up puppet enterprise. For numerous reasons it’s shaping up to be the project from hell (some the fault of puppet, but many that aren’t), but I’d like to share this little tidbit for posterity.

The main issue I’ve run into is that our puppet server is in a highly restricted vlan with no internet access. Since puppet pulls its modules from puppetforge, this becomes problematic.  The solution we came up with is to explicitly state the git repo to use for each module in the Puppetfile.

Problem 1: Naming conventions.

I can’t keep 100% fidelity on the projectnames when we migrate them over- for the puppetmodule KyleAnderson/consul, I don’t want to create a KyleAnderson user, so I have to mangle it to merge the user and project name together (since project names alone may not be unique; e.g. if bob/ntp wrote his module for windows and kevin/ntp wrote his module for linux, we can’t just call either puppet/ntp or we’ll get a collision.

We go from this:

forge "http://forge.puppetlabs.com"
mod "KyleAnderson/consul", :latest
mod "arioch/redis", :latest
...

to

forge "http://forge.puppetlabs.com"
mod "KyleAnderson/consul", :latest
  :git => 'https://internalgit/puppet/KyleaAderson-consul'
mod "arioch/redis", :latest
  :git => 'https://internalgit/puppet/arioch-redis'
...

In order to do this, we needed to get the git repo for each and mirror it. Well, that was the intent.

Problem 2: Names don’t match

KyleAnderson/consul does not exist on github. After manually searching the forge, I see his URL is actually solarkennedy/consul. So this means we need to get the project URL for each module to be able to clone the git repo. After much experimentation with puppet help module, I realized I can search for the module name, export as yaml and grep out the project name. I end up using the following command to check out the 51 modules I need:

for i in `cat .file |sed -e 's/.*"\(.*\)".*/\1/'`; do puppet module search ${i} --render-as=yaml |grep project_url |sed -e 's/.*: //' |xargs git clone ; done;

Problem 3: Inconsistent project URLs

…except that only works for about 80% of the modules- the rest have bad urls. Oh well, 43 is better than nothing.

ok, I have the modules now, time to check them into my git repo…

Problem 4: can’t check modules into git without the project existing first.

I have to create all 43 projects in the github enterprise web interface; that’s painful. I search and find documentation that eventually leads me to this little nugget:

for i in `ls` ; do curl -u "jmorgan3:$token" http://internalgit/api/v3/orgs/puppet/repos -d '{"name": "'${i}'"}' ; done

which creates 43 glorious repos. Then, I set the origin URL to my server:

for i in `ls` ; do cd $i ; echo $i ; git remote set-url origin git@internalgit:puppet/${i}.git ; cd ~/Projects/puppetmods/ ; done

and finally push them up

for i in `ls` ; do cd $i ; echo $i ; git remote -v ; cd ~/Projects/puppetmods/ ; done
for i in `ls` ; do cd $i ; echo $i ; git push ; cd ~/Projects/puppetmods/ ; done

Now I have all 43 modules checked into my internal git server.

 

I need to match up repos with modules (since the names may not match).

Problem 5: Repos were horribly named.

By using the repo names from the project URL, I still ended up with names like realmd, puppet-wordpress, and sssd. Hopefully this won’t bite us later.

 

I’ve commented out the remaining 7 unmatched projects, committed and pushed my Puppetfile changes, and am now rerunning “r10k deploy environment -pv”

 

Fingers crossed that this will work.

 

Problem 6: Bad syntax, I guess?

There were 100 little syntax issues with the Puppetfile. While I fixed most, this one was not resolvable:

# r10k deploy environment -pv
INFO -> Deploying environment /etc/puppetlabs/code/environments/master
INFO -> Environment master is now at 2481f9677469711705bcdb20dd9f0260466b955d
ERROR -> Failed to evaluate /etc/puppetlabs/code/environments/master/Puppetfile
Original exception:
wrong number of arguments (3 for 1..2)
INFO -> Deploying environment /etc/puppetlabs/code/environments/production
INFO -> Environment production is now at a6a7d5eda88334b0293d8534de81191a1375cf06
ERROR -> Failed to evaluate /etc/puppetlabs/code/environments/production/Puppetfile
Original exception:
wrong number of arguments (3 for 1..2)

Problem 7:  The control Repo changed!

Between originally checking this out 3 weeks ago and now, they have gutted and rebuilt the example I was using. The rationale makes total sense (it was over-opinionated previously), but now the new version is incomplete, so I’m left twisting in the wind.

 

I have a call with our puppet reps scheduled shortly and will pick up there.

The Pain and Fury of vmware-cli on CentOS 7, Part 4

Once more into the breach? Sure. Lets see what else we can remove, and destroy some dependencies as well. Our changelist includes:

  • removing “-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip “
  • adding -x “**Digest/MD5**” -x “**Crypt/OpenSSL/RSA**”  -x “**/Module/**” -x “**/Test/**”  -x “**/ExtUtils/**” \
  • updating iteration to 3
  • Adding perl-Crypt-OpenSSL-RSA perl-Digest-MD5 as a tentative rpm dependencies
  • removing symlinks via vmunlinker script

And here’s what I’m going to run.

echo '#!/bin/bash'> /tmp/vmunlinker.sh ; echo 'cd /opt/vmwarecli/bin/ ; for i in * ; do rm /usr/bin/$i ; done' >>/tmp/vmunlinker.sh
chmod 755 /tmp/vmunlinker.sh


fpm -f --pre-uninstall /tmp/vmunlinker.sh --post-install /tmp/vmlinker.sh -s dir -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=3 -C / \
 \
-x "**Devel/StackTrace**" -x "**Class/Data/Inheritable**" -x "**Convert/ASN1**" -x "**Exception/Class**" -x "**Compress/Raw/Zlib**" -x "**Try/Tiny**" -x "**Crypt/SSLeay**" -x "**XML/NamespaceSupport**" -x "**Archive/Zip**" \
 \
-x "**Class/MethodMaker**" -x "**Devel/CheckLib**" -x "**Compress/Raw/Bzip2**" -x "**Encode/Locale**" -x "**Env**" -x "**IO/HTML**" -x "**Import/Into**" -x "**IO/Socket/INET6**" -x "**Locale/Maketext/Simple**" -x "**Mozilla/CA**" -x "**Net/SSLeay**" -x "**Perl/OSType**" -x "**Params/Check**" -x "**Path/CLass**" -x "**Socket6**" -x "**Sub/Uplevel**" -x "**Task/Weaken**" -x "**Test/Warn**" -x "**autodie**" -x "**/version**" \
-x "**Digest/MD5**" -x "**Crypt/OpenSSL/RSA**" -x "**/Module/**" -x "**/Test/**" -x "**/ExtUtils/**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan


 

once that finishes, create a snapshot as “v3 built”, revert back to the raw build. I installed the RPM and:

  • Confirmed “-d perl-Archive-Zip -d perl-Data-Dumper -d perl-Crypt-SSLeay” are the only dependencies needed to make vmware-cmd work.
  • Confirmed symlinks worked

then removed rpm and:

  • confirmed symlinks were removed

It seems like we have all of the relevant information. revert to “v3 built” and run this hopefully final command:

fpm -f --pre-uninstall /tmp/vmunlinker.sh --post-install /tmp/vmlinker.sh -s dir -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=3 -C / \
 \
-d perl-Archive-Zip -d perl-Data-Dumper -d perl-Crypt-SSLeay \
-x "**Devel/StackTrace**" -x "**Class/Data/Inheritable**" -x "**Convert/ASN1**" -x "**Exception/Class**" -x "**Compress/Raw/Zlib**" -x "**Try/Tiny**" -x "**Crypt/SSLeay**" -x "**XML/NamespaceSupport**" -x "**Archive/Zip**" \
 \
-x "**Class/MethodMaker**" -x "**Devel/CheckLib**" -x "**Compress/Raw/Bzip2**" -x "**Encode/Locale**" -x "**Env**" -x "**IO/HTML**" -x "**Import/Into**" -x "**IO/Socket/INET6**" -x "**Locale/Maketext/Simple**" -x "**Mozilla/CA**" -x "**Net/SSLeay**" -x "**Perl/OSType**" -x "**Params/Check**" -x "**Path/CLass**" -x "**Socket6**" -x "**Sub/Uplevel**" -x "**Task/Weaken**" -x "**Test/Warn**" -x "**autodie**" -x "**/version**" \
-x "**Digest/MD5**" -x "**Crypt/OpenSSL/RSA**" -x "**/Module/**" -x "**/Test/**" -x "**/ExtUtils/**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

 

You now have your final product vmware-cli RPM.

 

Note that I have only been testing vmware-cmd; it’s possible the other 95% of the functionality may be borked.

The Pain and Fury of vmware-cli on CentOS 7, Part 3

So a bit of followup since my last post; I’ve begun reinstalling icinga and my other plugins and have already ran into some resistance- perl-net-SNMP is required by morgnagplug, and has a dependency on perl-Socket6, which conflicts with the vmware-cli rpm.

The Plan

I’m going to do the following:

  1. snapshot my current “production-run” version of the server
  2. jump back to my “package-created” snapshot
  3. add modules listed below to the exclude list
  4. rebuild the RPM
  5. save newest RPM locally
  6. revert to the raw snapshot
  7. upload the newest version of the RPM
  8. install it
  9. test vmware-cmd
  10. If I get an error, install corresponding RPM, then repeat until it runs properly.
    1. If this doesn’t work, revert back to the package-created snapshot
    2. exclude all EXCEPT the troublesome module
    3. rebuild RPM and repeat test.

In addition to Socket6, I will attempt to replace at the same time:

  • Class::MethodMaker with perl-Class-MethodMaker
  • Compress::Raw::Bzip2 with perl-Compress-Raw-Bzip2
  • Devel::CheckLib with perl-Devel-CheckLib
  • Encode::Locale with perl-Encode-Locale
  • Env with perl-Env
  • IO::HTML with perl-IO-HTML
  • Import::Into with perl-Import-Into
  • IO::Socket::INET6 with perl-IO-Socket-INET6.noarch
  • Locale::Maketext::Simple with perl-Locale-Maketext-Simple and perl-Locale-Maketext
  • Mozilla::CA with perl-Mozilla-CA
  • Net::SSLeay with perl-Net-SSLeay
  • Perl::OSType with perl-Perl-OSType
  • Params::Check with perl-Params-Check
  • Path::CLass with perl-Path-Class
  • Socket6 with perl-Socket6
  • Sub::Uplevel with perl-Sub-Uplevel
  • Task::Weaken with perl-Task-Weaken
  • Test::Warn with perl-Test-Warn
  • autodie with perl-autodie
  • version with perl-version

Once I’ve reached a stable point where I can install the newest RPM and it’s dependencies:

  • I’ll rebuild the module with the proper excludes and add the new dependence
  • copy it locally
  • revert to my “production-run” snapshot
  • uninstall the old RPM
  • install the new RPM
  • verify the new dependencies install
  • verify vmware-cmd works as well as check_vmware_esx.pl

It’s also worth nothing that I’ll be updating FPM to use –iteration 2 since this is such a big departure from the last one.

 

The Implementation

Reverted back to package-created snapshot

fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=2 -C / \
 \
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \
 \
-x "**Devel/StackTrace**" -x "**Class/Data/Inheritable**" -x "**Convert/ASN1**" -x "**Exception/Class**" -x "**Compress/Raw/Zlib**" -x "**Try/Tiny**" -x "**Crypt/SSLeay**" -x "**XML/NamespaceSupport**" -x "**Archive/Zip**" \
 \
-x "**Class/MethodMaker**" -x "**Devel/CheckLib**" -x "**Compress/Raw/Bzip2**" -x "**Encode/Locale**" -x "**Env**" -x "**IO/HTML**" -x "**Import/Into**" -x "**IO/Socket/INET6**" -x "**Locale/Maketext/Simple**" -x "**Mozilla/CA**" -x "**Net/SSLeay**" -x "**Perl/OSType**" -x "**Params/Check**" -x "**Path/CLass**" -x "**Socket6**" -x "**Sub/Uplevel**" -x "**Task/Weaken**" -x "**Test/Warn**" -x "**autodie**" -x "**version**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

As I typed that out, I became nervous about those regexex- specifically version and autodie- they felt too generic.

I confirmed my fears by comparing the filelist from iteration 1 and iteration 2:

rpm -qlp vmware-cli-6.0.0_2503617-1.noarch.rpm >/tmp/1
rpm -qlp vmware-cli-6.0.0_2503617-2.noarch.rpm >/tmp/2
vimdiff /tmp/1 /tmp/2

That sloppy regex got rid of /opt/vmwarecli/lib/vmware-vcli/apps/general/viversion.pl, which I did NOT want.

Inserting a slash into that wildcart to change it to -x “**/version**” seemed to do the trick, but it made me curious what else I’d missed. I decided to remove ALL of the excludes and package it as iteration 0, then compare it to my new iteration 2 (with **/version**):

fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=0 -C / \
 \
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan


fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=2 -C / \
 \
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \
 \
-x "**Devel/StackTrace**" -x "**Class/Data/Inheritable**" -x "**Convert/ASN1**" -x "**Exception/Class**" -x "**Compress/Raw/Zlib**" -x "**Try/Tiny**" -x "**Crypt/SSLeay**" -x "**XML/NamespaceSupport**" -x "**Archive/Zip**" \
 \
-x "**Class/MethodMaker**" -x "**Devel/CheckLib**" -x "**Compress/Raw/Bzip2**" -x "**Encode/Locale**" -x "**Env**" -x "**IO/HTML**" -x "**Import/Into**" -x "**IO/Socket/INET6**" -x "**Locale/Maketext/Simple**" -x "**Mozilla/CA**" -x "**Net/SSLeay**" -x "**Perl/OSType**" -x "**Params/Check**" -x "**Path/CLass**" -x "**Socket6**" -x "**Sub/Uplevel**" -x "**Task/Weaken**" -x "**Test/Warn**" -x "**autodie**" -x "**/version**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

rpm -qlp vmware-cli-6.0.0_2503617-0.noarch.rpm >/tmp/0
rpm -qlp vmware-cli-6.0.0_2503617-2.noarch.rpm >/tmp/2
vimdiff /tmp/0 /tmp/2

The first thing I noticed was that while I excluded Locale/Maketext/Simple, it did not remove the Local/Maketext directory, leaving it empty. I dislike including empty directories, but it’s relatively minor. Perhaps I’ll explicitly remove them in a future iteration.

Next:

  • copied iteration2 of the RPM to my local machine
  • time to revert to the Raw snapshot.
  • upload iteration2
  • yum install rpm with it’s original 10 dependencies.
  • test vmware-cmd
/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54eaad0a-923ab37c-90b6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54eaad24-7c233c62-970e-b82a72d4d796/hostname2/hostname2.vmx
<...>

By some miracle, it works! This means that all of the packages we’ve excluded are not actually needed (at least for vmware-cmd). Our final test is to bounce back to our “production run” snapshot and swap out the iteration1 RPM for iteration2.

yum remove vmware-cli
yum install vmware-cli-6.0.0_2503617-2.noarch.rpm 
<...>
ln: failed to access ‘/usr/bin/dcli’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-advcfg’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-authconfig’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-cfgbackup’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-dns’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-dumppart’: Too many levels of symbolic links
ln: failed to access ‘/usr/bin/esxcfg-hostops’: Too many levels of symbolic links
<...>

Whoops. Remember that vmlinker.sh script we made? It didn’t clean up after itself on uninstall. Yes, that’s sloppy on my part; I should include a pre-uninstall script to remove those symlinks. It turns out the links were broken anyways (damnit). If I have to repackage this RPM, I’ll include the uninstaller and fix the symlinks. For now, at least the package is installed. (I’ve also changed the example in the last article to function properly.)

 

The important thing is vmware-cmd is functional, as is check_vmware_esx.pl. Now to get all of my other checks functional.

 

One thing I am bothered by though. Despite not requiring that third round of dependencies, I still have a bunch from the first and second rounds:

-d perl-Data-Dumper
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \

The only one I’m *sure* I need (as in it failed without it) was perl-Data-Dumper; the rest I inferred. Perhaps I should verify those as well. Perhaps another time.

I should also consider another round at the CPAN modules left behind- things Digest::MD5 might not need to be in there.

 

The Pain and Fury of vmware-cli on CentOS 7, Part 2

 

Last we left off with a functioning vmware-cli and no way to replicate this in ansible. Lets fix that. We’ll be using FPM to create an RPM containing all of the files that were created by the installer (including cpan modules).
But first, we need to figure out which files need to be packaged. VMWare aaallmost kinda makes this easy for us- each file it installs is tracked in /etc/vmware-vcli/locations (excluding cpan files). Parsing through this, we see

  • a list of all the CPAN modules installed
  • a list of directories it’s created
  • a list of the files it’s created (including symlinks

Step 1: Identifying vmware-cli Files to Package

We’ll hold off on CPAN modules for the moment and jump ahead to directories and files. We can trim this list down quite a bit because we can ignore the filenames in directories that the installer created- in other words, we can include /foo/bar/ and it’ll automatically include /foo/bar/baz.pm.  This allows us to cut down our 1400+ files and directories down to about 63- most of which are symlinks and can be simplified with a wild card. Once we refactor all that info,  the end result is something like this:

/etc/vmware-vcli/locations /usr/share/perl5/VMware/ /usr/share/perl5/WSMan/ /opt/vmwarecli/ /usr/bin/dcli /usr/bin/esxcfg-* /usr/bin/esxcli /usr/bin/resxtop /usr/bin/svmotion /usr/bin/vicfg-* /usr/bin/vifs /usr/bin/vihostupdate /usr/bin/vihostupdate35 /usr/bin/viperl-support /usr/bin/vmkfstools /usr/bin/vmware-cmd /usr/bin/vmware-uninstall-vSphere-CLI.pl /etc/vmware-vcli/config

Save this list for later.

An Aside- Thanks for the mess, CPAN.

 

If you recall, we took a snapshot of our perl modules before and after our installation.  You may remember us doing the following (don’t do this right now!!!):

perl -e 'use doesntexist;'
Can't locate doesntexist.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at -e line 1.
BEGIN failed--compilation aborted at -e line 
find /usr/local/lib64/perl5 /usr/local

then later:

find /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 >/tmp/final.list

Unfortunately that’s only part of the story. When we rerun that first command:

perl -e 'use doesntexist;'
Can't locate doesntexist.pm in @INC (@INC contains: /root/perl5/lib/perl5/x86_64-linux-thread-multi /root/perl5/lib/perl5 /root/perl5/lib/perl5/x86_64-linux-thread-multi /root/perl5/lib/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

What the heck? where did all those /root/perl5/ paths come from? from our /root/.bashrc:

<...>
export PERL_LOCAL_LIB_ROOT="$PERL_LOCAL_LIB_ROOT:/root/perl5";
export PERL_MB_OPT="--install_base /root/perl5";
export PERL_MM_OPT="INSTALL_BASE=/root/perl5";
export PERL5LIB="/root/perl5/lib/perl5:$PERL5LIB";
export PATH="/root/perl5/bin:$PATH";

export PERL_LOCAL_LIB_ROOT="$PERL_LOCAL_LIB_ROOT:/root/perl5";
export PERL_MB_OPT="--install_base /root/perl5";
export PERL_MM_OPT="INSTALL_BASE=/root/perl5";
export PERL5LIB="/root/perl5/lib/perl5:$PERL5LIB";
export PATH="/root/perl5/bin:$PATH";

These… these were not here before. So what is in /root/perl5/? The big takeaways are:

/root/perl5/lib/perl5/CPAN/Meta/*
/root/perl5/lib/perl5/ExtUtils/*
/root/perl5/lib/perl5/JSON/*
/root/perl5/lib/perl5/Parse/*
/root/perl5/bin/instmodsh

*sigh* I have no idea when or why or how these were inserted. I don’t know if that was CPAN not cleaning up after itself or what. all I know is that a script running as a user might now use different libraries than one running as root. I don’t know if those libs are important, but judging from the contents I’m presuming they’re only for building packages and are not functionally involved (I hope).

So we’ll blissfully ignore them and hope it doesn’t bite us later on.

Step 2: Identifying CPAN-Installed Files to Package

ok, so we have our two files- /tmp/pristine.list and /tmp/final.list. We can use the following to gather a list of new files:

cat /tmp/pristine.list /tmp/final.list |sort|uniq -u >/tmp/unique.list

We can do roughly the same thing with this list as we did with /etc/vmware-vcli/locations- ignore the files under any directories we’ve created. In addition, we can ignore any directories we’ve already documented, like /usr/share/perl5/VMware and /usr/share/perl5/WSMan/.  Unfortunately, there are some troublesome directories- /usr/local/share/perl5 and /usr/local/lib64/perl5 are pretty generic- if we include those, it may cause conflicts with other RPMs down the road- I honestly don’t know if this is the case, so we’ll hope for the best. We end up with the following list:

/usr/lib64/perl5/auto/Locale
/usr/lib64/perl5/auto/Params
/usr/lib64/perl5/perllocal.pod
/usr/local/lib64/perl5
/usr/local/share/perl5
/usr/share/perl5/Locale/Maketext
/usr/share/perl5/Params

Save this list for later.

Final Packages

Time to bundle everything up… But we’ll need fpm installed first:

yum install rpm-build ruby-devel gcc gem
gem install fpm

From here, we can take those file/directory lists and feed them a single file:

ls -d /etc/vmware-vcli/locations /usr/share/perl5/VMware/ /usr/share/perl5/WSMan/ /opt/vmwarecli/ /usr/bin/dcli /usr/bin/esxcfg-* /usr/bin/esxcli /usr/bin/resxtop /usr/bin/svmotion /usr/bin/vicfg-* /usr/bin/vifs /usr/bin/vihostupdate /usr/bin/vihostupdate35 /usr/bin/viperl-support /usr/bin/vmkfstools /usr/bin/vmware-cmd /usr/bin/vmware-uninstall-vSphere-CLI.pl /etc/vmware-vcli/config /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params > /tmp/fpm_final_list

now we’ll feed /tmp/fpm_final_list into FPM to create a shiny-new RPM:

fpm -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration 1 -C /  /etc/vmware-vcli/locations /usr/share/perl5/VMware/ /usr/share/perl5/WSMan/ /opt/vmwarecli/ /usr/bin/dcli /usr/bin/esxcfg-* /usr/bin/esxcli /usr/bin/resxtop /usr/bin/svmotion /usr/bin/vicfg-* /usr/bin/vifs /usr/bin/vihostupdate /usr/bin/vihostupdate35 /usr/bin/viperl-support /usr/bin/vmkfstools /usr/bin/vmware-cmd /usr/bin/vmware-uninstall-vSphere-CLI.pl /etc/vmware-vcli/config /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params

And because nothing is easy, this throws errors; apparently the current version of FPM doesn’t like symlinks (all of the files in /usr/bin). If we cut those out:

fpm -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=1 -C / /etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

 

This builds fine, BUT we have no symlinks. Ugh this is kludgy, but we can make a fugly little postinstall script and have FPM include that (I hope)

echo '#!/bin/bash'> /tmp/vmlinker.sh ; echo 'cd /opt/vmwarecli/bin/ ; for i in * ; do ln -s /opt/vmwarecli/bin/$i /usr/bin/$i ; done' >>/tmp/vmlinker.sh
chmod 755 /tmp/vmlinker.sh

and now we can include it in our fpm command:

fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=1 -C / /etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan
no value for epoch is set, defaulting to nil {:level=>:warn}
Force flag given. Overwriting package at vmware-cli-6.0.0_2503617-1.noarch.rpm {:level=>:warn}
no value for epoch is set, defaulting to nil {:level=>:warn}
Created package {:path=>"vmware-cli-6.0.0_2503617-1.noarch.rpm"}

And there we go. Time to test it.

Before we go, we need to snapshot our machine yet again as “package-created.” We also need to copy our wonderful RPM down to our local machine so we can revert back to the raw snapshot and test it.

Testing our RPM

Revert back to our Raw Snapshot, then copy our rpm to /tmp on it.

yum install /tmp/vmware-cli-6.0.0_2503617-1.noarch.rpm

Note that this will install perl-Data-Dumper as a dependency; why? because somehow the rpm was installed and I didn’t notice that it was still there and I don’t want to backtrack to have cpan build it. So now it’s a dependency- we’ll circle back to this in a moment- for now… does it work?

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54eaad0a-923ab37c-90b6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54eaad24-7c233c62-970e-b82a72d4d796/hostname2/hostname2.vmx
<...>

SUCCESS!

Now that we know our RPM works, we can touch back on some more uncomfortable questions. Right now we have about 28 perl modules installed via CPAN (possibly more). Many of our other apps (such as morgnagplug and manubulon) are dependent on the RPM versions of some of those modules. When we install them, we could have conflicts down the road. So how many of those modules could be installed as RPMs?

module Devel::StackTrace
module Class::Data::Inheritable
module Convert::ASN1
module Crypt::OpenSSL::RSA
module Crypt::X509
module Exception::Class
module UUID::Random
module Archive::Zip
module Compress::Zlib
module Compress::Raw::Zlib
module Path::Class
module Try::Tiny
module Crypt::SSLeay
module IO::Compress::Base
module IO::Compress::Zlib::Constants
module HTML::Parser
module UUID
module Data::Dump
module SOAP::Lite
module URI
module XML::SAX
module XML::NamespaceSupport
module XML::LibXML::Common
module XML::LibXML
module LWP
module LWP::Protocol::https
module IO::Socket::INET6
module Net::INET6Glue

I’m not sure. Let’s find out.

Lets snapshot this as “vmware rpm installed”. As an aside, the snapshot functionality almost makes up for the grief vmware is putting me through.

Which CPAN modules can be swapped for RPMs?

Here’s my plan of attack; for each module listed above,

  1. yum search modulename; Not all modules will have RPMs, but this is the best way to find out if it’s possible to replace.
  2. run rpm -ql vmware-cli |grep modulename ; Note that you should replace the :: with a slash, so Devel::StackTrace becomes Devel/StackTrace
  3. delete matching files from the filesystem (we can always reinstall the RPM if we get in trouble, or even revert back to the “vmware rpm installed” snapshot).
  4. yum install moduleRPM ; this should install ONLY one module, no dependencies; if it has dependencies, put it to the side.

I’m now going to run through each module and document it as I go

  • Devel::StackTrace   RPM exists, has no dependencies. Files removed, rpm installed, vmware-cmd still works
  • Class::Data::Inheritable   RPM exists, has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • Convert::ASN1  RPM exists, has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • Crypt::OpenSSL::RSA RPM exists, HAS DEPENDENCIES, shelved
  • Crypt::X509  No RPM currently exists
  • Exception::Class   RPM exists, has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • UUID::Random No RPM currently exists
  • Archive::Zip  RPM exists, HAS DEPENDENCIES, shelved
  • Compress::Zlib  RPM exists, HAS DEPENDENCIES, shelved
  • Compress::Raw::Zlib   RPM exists, has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • Path::Class No RPM currently exists
  • Try::Tiny RPM exists (perl-try-tiny), has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • Crypt::SSLeay   RPM exists, has no dependencies, Files removed, rpm installed, vmware-cmd still works
  • IO::Compress::Base  No RPM currently exists (probably installed with perl-IO-Compress, but it has dependencies)
  • IO::Compress::Zlib::Constants  No RPM currently exists (possibly installed with perl-IO-Compress, but it has dependencies)
  • HTML::Parser  RPM exists, HAS DEPENDENCIES, shelved (here be dragons)
  • UUID  Difficult to Discern- UUID RPMs doesn’t seem to line up; shelved.
  • Data::Dump No RPM currently exists (not to be confused with Data::Dumper)
  • SOAP::Lite No RPM currently exists
  • URI Difficult to discern… RPM exists, HAS DEPENDENCIES, shelved
  • XML::SAX RPM exists, HAS DEPENDENCIES, shelved
  • XML::NamespaceSupport  RPM exists, has no dependencies. Files removed, rpm installed, vmware-cmd still works
  • XML::LibXML::Common  No RPM currently exists (may be included in a different RPM)
  • XML::LibXML  RPM exists, HAS DEPENDENCIES, shelved
  • LWP  RPM exists, HAS DEPENDENCIES, shelved (here be dragons)
  • LWP::Protocol::https   RPM exists, HAS DEPENDENCIES, shelved (here be dragons)
  • IO::Socket::INET6   RPM exists, HAS DEPENDENCIES, shelved
  • Net::INET6Glue No RPM currently exists (may be included in a different RPM)

Circling back, lets see if any of the libs with dependencies have had their dependencies installed

  • Archive::Zip  RPM exists, has no dependencies. Files removed, rpm installed, vmware-cmd still works

The rest are dead ends. We can now hypothesize that the following libs are acceptable in RPM form:

perl-Devel-StackTrace perl-Class-Data-Inheritable perl-Convert-ASN1 perl-Exception-Class perl-Compress-Raw-Zlib perl-Try-Tiny perl-Crypt-SSLeay perl-XML-NamespaceSupport perl-Archive-Zip

if we exclude the following paths from our FPM build process:

/usr/local/lib64/perl5/auto/Devel/StackTrace/ /usr/local/share/perl5/Devel/StackTrace.pm /usr/local/share/perl5/Devel/StackTrace/ /usr/local/lib64/perl5/auto/Class/Data/ /usr/local/share/perl5/Class/Data /usr/local/lib64/perl5/auto/Convert/ /usr/local/share/perl5/Convert/ /usr/local/lib64/perl5/auto/Exception/ /usr/local/share/perl5/Exception/ /usr/local/lib64/perl5/Compress/ /usr/local/lib64/perl5/auto/Compress/ /usr/local/lib64/perl5/auto/Compress/ /usr/local/lib64/perl5/auto/Try/ /usr/local/share/perl5/Try/ /usr/local/lib64/perl5/Crypt/SSLeay/  /usr/local/lib64/perl5/Crypt/SSLeay.pm  /usr/local/lib64/perl5/auto/Crypt/SSLeay/ /usr/local/lib64/perl5/auto/XML/NamespaceSupport/ /usr/local/share/perl5/XML/NamespaceSupport.pm /usr/local/lib64/perl5/auto/Archive/ /usr/local/share/perl5/Archive/

 

Lets switch over to “package created” Snapshot and repackage our RPM with new dependencies and exclusions:

fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=1 -C / \
 \
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \
 \
-x "**usr/local/lib64/perl5/auto/Devel/StackTrace/**" -x "**usr/local/share/perl5/Devel/StackTrace.pm" -x "**usr/local/share/perl5/Devel/StackTrace/**" -x "**usr/local/lib64/perl5/auto/Class/Data/**" -x "**usr/local/share/perl5/Class/Data**" -x "**usr/local/lib64/perl5/auto/Convert/**" -x "**usr/local/share/perl5/Convert/**" -x "**usr/local/lib64/perl5/auto/Exception/**" -x "**usr/local/share/perl5/Exception/**" -x "**usr/local/lib64/perl5/Compress/**" -x "**usr/local/lib64/perl5/auto/Compress/**" -x "**usr/local/lib64/perl5/auto/Compress/**" -x "**usr/local/lib64/perl5/auto/Try/**" -x "**usr/local/share/perl5/Try/**" -x "**usr/local/lib64/perl5/Crypt/SSLeay/**" -x "**usr/local/lib64/perl5/Crypt/SSLeay.pm" -x "**usr/local/lib64/perl5/auto/Crypt/SSLeay/**" -x "**usr/local/lib64/perl5/auto/XML/NamespaceSupport/**" -x "**usr/local/share/perl5/XML/NamespaceSupport.pm" -x "**usr/local/lib64/perl5/auto/Archive/**" -x "**usr/local/share/perl5/Archive/**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

Note: fpm’s excludes are picky as hell- you need doublequotes around each one as well as double wildcards in place of a leading / and trailing it if a directory.

Even then, this STILL leaves the directories, just not the contents of the directory.

I’m trying too hard. Let’s try something slightly different:

fpm -f --post-install /tmp/vmlinker.sh -s dir -d perl-Data-Dumper -a noarch --rpm-user root --rpm-group root -t rpm -n vmware-cli -v '6.0.0_2503617' --iteration=1 -C / \
 \
-d perl-Devel-StackTrace -d perl-Class-Data-Inheritable -d perl-Convert-ASN1 -d perl-Exception-Class -d perl-Compress-Raw-Zlib -d perl-Try-Tiny -d perl-Crypt-SSLeay -d perl-XML-NamespaceSupport -d perl-Archive-Zip \
 \
-x "**Devel/StackTrace**" -x "**Class/Data/Inheritable**" -x "**Convert/ASN1**" -x "**Exception/Class**" -x "**Compress/Raw/Zlib**" -x "**Try/Tiny**" -x "**Crypt/SSLeay**" -x "**XML/NamespaceSupport**" -x "**Archive/Zip**" \
 \
/etc/vmware-vcli /opt/vmwarecli /usr/lib64/perl5/auto/Locale /usr/lib64/perl5/auto/Params /usr/lib64/perl5/perllocal.pod /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/share/perl5/Locale/Maketext /usr/share/perl5/Params /usr/share/perl5/VMware /usr/share/perl5/WSMan

Jackpot. None of the replaced modules are in the RPM, but it did reveal something else…

VMware didn’t track the dependencies that CPAN built, only the ones it needed. What do I mean? For example, /usr/local/lib64/perl5/Class/MethodMaker.pm appears in our RPM bundle and our final.list.  It was installed while vmware-cli was installing. but there is no trace of Class::MethodMaker in /etc/vmware-vcli/locations.

That means there’s an entirely new group of CPAN modules that exist that we probably don’t need. We’ll put this on the back burner and circle back later (maybe). In the meantime we need to switch over to our Raw snapshot and test this new RPM. Make sure to copy it to your local machine before rebooting.

Once it’s copied over, try installing it again:

yum install /tmp/vmware-cli-6.0.0_2503617-1.noarch.rpm
<...>
Install 1 Package (+10 Dependent packages)
<...>

It should be our friendly new RPMs.

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54eaad0a-923ab37c-90b6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54eaad24-7c233c62-970e-b82a72d4d796/hostname2/hostname2.vmx
<...>

SUCCESS!

 

At this point, our RPM is installing the following CPAN modules (based on packlist files):

Locale::Maketext::Simple
Params::Check
Class::Inspector
Class::MethodMaker
Compress::Raw::Bzip2
Crypt::OpenSSL::RSA
Crypt::OpenSSL::Random
Crypt::X509
Data::Dump
Devel::CheckLib
Digest::MD5
Encode::Locale
Env
ExtUtils::CBuilder
ExtUtils::MakeMaker
File::Listing
HTML::Parser
HTML::Tagset
HTTP::Cookies
HTTP::Daemon
HTTP::Date
HTTP::Message
HTTP::Negotiate
IO::CaptureOutput
IO::Compress
IO::HTML
IO::SessionData
IO::Socket::INET6
IO::Socket::SSL
IPC::Cmd
Import::Into
JSON::PP
LWP
LWP::MediaTypes
LWP::Protocol::https
Module::Build
Module::CoreList
Module::Load
Module::Load::Conditional
Module::Metadata
Module::Runtime
Mozilla::CA
Net::HTTP
Net::INET6Glue
Net::SSLeay
Path::Class
Perl::OSType
SOAP::Lite
Socket6
Sub::Uplevel
Task::Weaken
Test::Simple
Test::Warn
URI
UUID
UUID::Random
WWW::RobotRules
XML::LibXML
XML::Parser::Lite
XML::SAX
XML::SAX::Base
autodie
version

 

I’m positive we could trim out many if not most of these, but I’m exhausted. I still need to get the rest of my stuff installed.

 

If this was helpful, please leave a comment below.

The Pain and Fury of vmware-cli on CentOS 7

ok, this has reached the point of absurdity that I need to document it.

The Goal

Install vmware-cli on CentOS 7 for check_vmware_esx.pl to use.

The Requirements

  • installation needs to be reproducible with ansible.
  • the latest version of the cli, VMware-vSphere-CLI-6.0.0-2503617.x86_64.tar.gz

The Complications

  1. CentOS 7 uses a new version of Perl that is binary incompatible.
  2. VMware doesn’t pay attention.
  3. CPAN seemed like a great idea 22 years ago. Unfortunately it didn’t keep up with the times.

The Setup

  • Freshly installed CentOS 7
  • The following custom ansible packages are installed (to give you an idea of what’s I was starting with there without absurd detail):
    • vim
    • sudo
    • sshkeys
    • bashconfig
    • snmpd
    • mariadb
    • httpd
    • git
    • icinga2(nagios-plugins,nagios-plugins-all )
    • manubulonplugins (perl-Net-SNMP)
    • morgnagplug (perl-HTML-Parser,perl-Compress-Raw-Zlib,perl-IO-Zlib,perl-libxml-perl,perl-XML-LibXML,perl-Time-Duration,perl-Number-Format,perl-Config-IniFiles,perl-DateTime)
  • CPAN is NOT installed (it’s a PITA with ansible, so it’s a last resort).

I have currently have two snapshots:

  • a barebones snapshot without all this stuff installed (but it takes 20 minutes to reinstall it all). (Raw Snapshot)
  • a snapshot with all of the stuff listed above installed. (Configured Snapshot)

Test 1: Simplest possible install using –default

The initial installation demands openssl-devel be installed (I’m skipping that hassle for brevity).

yum install openssl-devel
./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes --default

This will select the perl modules pre-packaged by VMware. Note that it does complain about the following:

MIME::Base64 3.14 or newer 
Try::Tiny 0.22 or newer 
Socket6 0.23 or newer

Which are installed via RPM for net-snmp and other packages and are non-negotiable. It installs fine, except it doesn’t work:

 /opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
Hiding the command line arguments: symbol lookup error: /usr/lib64/perl5/auto/Crypt/SSLeay/SSLeay.so: undefined symbol: Perl_Gthr_key_ptr

This is where Complication #1 comes into play- SSLeay.so was compiled against a different system, so it’s incompatible. That’s a simple fix, right?

./bin/vmware-uninstall-vSphere-CLI.pl
yum install perl-Crypt-SSLeay
./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes --default
/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
 length() used on @array (did you mean "scalar(@array)"?) at /usr/lib64/perl5/IO/Compress/Zlib/Extra.pm line 198. SOAP request error - possibly a protocol issue: 500 read timeout

out of the frying pan and into the fire. There’s two actual problems here:

  1. The pre-packaged modules include a broken copy of IO::Compress::Zlib. This is annoying, but it doesn’t stop anything (I don’t think).
  2. There’s a problem with reading the soap stuff. what problem? Not sure yet.

That SOAP error first appears in 2009. it ties back to an old version of LWP (aka perl-libwww-perl.rpm). This is installed because morgnagplug uses perl-XML-LibXML.

OK, fine. I can break morgnagplug for the time being (testing purposes), so I remove that and rerun the installer. This pulls down the vmware-cli pre-packaged version of LWP and libxml (note that perl-libxml-perl.noarch.rpm is still installed through all of this). I’ve also removed it from my

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/usr/bin/perl: symbol lookup error: /usr/lib64/perl5/auto/XML/LibXML/Common/Common.so: undefined symbol: Perl_Gthr_key_ptr

So Now I’m at an impasse- two of the vmware prepackaged modules are not binary compatible- while I could work around Crypt::SSLeay, I couldn’t work around XML::LibXML because it’s dependent on perl-libwww-perl (LWP), which is incompatible.

At this point I can attempt to track down older versions of perl-libwww-perl, but that will then require older RPMs of half a dozen other libraries. This will require pinning them so they’re not accidentally upgraded and ignoring any security patches that may appear. Obviously this is not acceptable.

I don’t think I can go any further down this road. Time to consider CPAN.

Test 2: Maximum CPAN

I roll back to my Configured snapshot, then install openssl-devel like before, then cpan and friends. This includes libuuid-devel for UUID and gcc (!) to get everything CPAN wants to install first try. Note this was about 3 days of trial and error to figure out what was missing so that everything would install properly (mostly because of UUID).

yum install openssl-devel libuuid-devel perl-YAML perl-Devel-CheckLib gcc perl-CPAN

Just as an FYI, CPAN is dependent on perl-ExtUtils-Install, perl-ExtUtils-MakeMaker, perl-ExtUtils-Manifest, perl-ExtUtils-ParseXS, perl-Test-Harness, perl-devel, and perl-local-lib among other things. This is important in a moment (Note: RPM installed perl-ExtUtils-MakeMaker-6.68-3.el7.noarch)

./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes
<...>
Do you want to install precompiled Perl modules for RHEL?
[yes] no
<...>
Can't locate Module/Build.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
BEGIN failed--compilation aborted.
Below mentioned modules with their version needed to be installed,
these modules are available in your system but vCLI need specific 
version to run properly

Module: ExtUtils::MakeMaker, Version: 6.96 
Module: Module::Build, Version: 0.4205 
Module: LWP, Version: 5.837 
Do you want to continue? (yes/no)

Note that the compilation failure above is due to a missing Module::Build, which it looks like it’ll install below anyways.  Also note the three packages that need explicit versions-

  • perl-ExtUtils-MakeMaker 6.68 vs ExtUtils::MakeMaker 6.96 (Newer than RPM)
  • perl-Module-Build 0.40.05 vs Module::Build 0.4205 (Newer than RPM)
  • perl-libwww-perl 6.05 vs LWP 5.837 (Older than RPM)

In either case, this fails because Class::MethodMaker can’t be built and the script fails:

CPAN not able to install following Perl modules on the system. These must be 
installed manually for use by vSphere CLI:

Class::MethodMaker 2.10 or newer

Following it’s directions, I try to install it manually to see what it’s missing:

 cpan -i Class::MethodMaker
Reading '/root/.cpan/Metadata'
 Database was generated on Tue, 19 May 2015 16:17:02 GMT
Running install for module 'Class::MethodMaker'
Running make for S/SC/SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz
Checksum for /root/.cpan/sources/authors/id/S/SC/SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz ok

 CPAN.pm: Building S/SC/SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz

Checking if your kit is complete...
Looks good
JSON::PP 2.27103 is not available
 at /usr/local/share/perl5/CPAN/Meta/Converter.pm line 22.
 at /usr/local/share/perl5/ExtUtils/MM_Any.pm line 831.
JSON::PP 2.27103 is not available
 at /usr/local/share/perl5/CPAN/Meta/Converter.pm line 22.
Warning: No success on command[/usr/bin/perl Makefile.PL]
 SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz
 /usr/bin/perl Makefile.PL -- NOT OK
Running make test
 Make had some problems, won't test
Running make install
 Make had some problems, won't install
Could not read metadata file. Falling back to other methods to determine prerequisites

So CPAN fails because it requires JSON::PP; I have three choices- install JSON::PP via CPAN, install JSON::PP via RPM or install Class::MethodMaker via RPM. I don’t want to get into dependency hell with cpan, and I know from previous experience that it will complain that the rpm for JSON::PP is too old, so I’ll attempt to simply install the perl-Class-MethodMaker rpm (which oddly isn’t dependent on JSON::PP).  I’ll add this to my “always install first” list with openssl-devel.

(This is especially frustrating because I *know* that the installer will eventually use cpan to install JSON::PP, and this error is likely caused by poor dependency ordering.)

This works, and I’m able to run the install script again; this time with only two problematic modules:

The following Perl modules were found on the system but may be too old to work 
with vSphere CLI:

MIME::Base64 3.14 or newer 
Socket6 0.23 or newer

The real question- will vmware-cmd work?

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'

And that’s a no-go. It’ll hang for 5 minutes or so before erroring. I can tell 20 seconds in that this is the case, but for certainty I have to wait for the timeout before I can continue. What I get is even more interesting:

SOAP request error - possibly a protocol issue: <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
<GIGANTIC BLOCK OF XML>

Well what the hell. 4 screens full of solid xml code. Looking over it I see snippets like this:

<summary>ISO [Datastore 1] ISOs/SW_DVD9_Windows_Svr_Std_and_DataCtr_2012_R2_64Bit_English_-4_MLF_X19-82891.ISO</summary>

Which means at least it’s getting through.

So I google for that error and find this page, which indicates Net::HTTP needs to be an older version just like LWP.  The thing is I’m not intentionally installing the perl-Net-HTTP RPM; it’s installed by morgnagplug along with perl-XML-LibXML,  perl-XML-SAX and perl-XML-LibXML… so I guess I uninstall those four RPMs and rerun the installer? This is getting confusing. I suspect I should reimage this machine without morgnagplug and see if that makes things easier. I’ll save that for the next attempt.

yum remove perl-Net-HTTP perl-XML-LibXML perl-XML-SAX perl-libwww-perl
./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes
<...>
CPAN not able to install following Perl modules on the system. These must be 
installed manually for use by vSphere CLI:

XML::LibXML::Common 0.13 or newer 
XML::LibXML 1.63 or newer

*Sigh*

cpan -i XML::LibXML
<...>
Checking for ability to link against libxml2...libxml2, zlib, and/or the Math library (-lm) have not been found.
Try setting LIBS and INC values on the command line
Or get libxml2 from
 http://xmlsoft.org/
If you install via RPMs, make sure you also install the -devel
RPMs, as this is where the headers (.h files) are.

Also, you may try to run perl Makefile.PL with the DEBUG=1 parameter
to see the exact reason why the detection of libxml2 installation
failed or why Makefile.PL was not able to compile a test program.
No 'Makefile' created SHLOMIF/XML-LibXML-2.0121.tar.gz
<...>

If I read that correctly, cpan won’t build it because the libxml2-devel rpm is not installed.

yum install libxml2-devel.x86_64
cpan -i XML::LibXML
<...>
Warning: prerequisite XML::SAX 0.11 not found.
JSON::PP 2.27103 is not available
 at /usr/local/share/perl5/CPAN/Meta/Converter.pm line 22.
 at /usr/local/share/perl5/ExtUtils/MM_Any.pm line 831.
JSON::PP 2.27103 is not available
 at /usr/local/share/perl5/CPAN/Meta/Converter.pm line 22.
Warning: No success on command[/usr/bin/perl Makefile.PL]
 SHLOMIF/XML-LibXML-2.0121.tar.gz
 /usr/bin/perl Makefile.PL -- NOT OK
<...>

damnit. Looks like I’m going down the CPAN rabbit hole.

cpan -i JSON::PP
cpan -i XML::SAX
<...>
t/21saxini.t ..... Can't locate Fatal.pm in @INC (@INC contains: /root/.cpan/build/XML-SAX-0.99-OJOmqR/blib/lib /root/.cpan/build/XML-SAX-0.99-OJOmqR/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at t/21saxini.t line 6.
BEGIN failed--compilation aborted at t/21saxini.t line 6.
t/21saxini.t ..... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/40cdata.t ...... ok 
t/42entities.t ... ok 
t/99cleanup.t .... ok 

Test Summary Report
-------------------
t/21saxini.t (Wstat: 512 Tests: 0 Failed: 0)
 Non-zero exit status: 2
 Parse errors: No plan found in TAP output
Files=14, Tests=98, 2 wallclock secs ( 0.11 usr 0.02 sys + 2.07 cusr 0.16 csys = 2.36 CPU)
Result: FAIL
Failed 1/14 test programs. 0/98 subtests failed.
make: *** [test_dynamic] Error 255
 GRANTM/XML-SAX-0.99.tar.gz
 /bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
 reports GRANTM/XML-SAX-0.99.tar.gz
Running make install
 make test had returned bad status, won't install without force

what? Fine.

cpan -i Fatal
cpan -i XML::SAX
cpan -i XML::LibXML

FINALLY.

ok… where was I? Oh yes.

./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes

It runs and complains about MIME::Base64 and Socket6 again.

FINGERS CROSSED…

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
SOAP request error - possibly a protocol issue: <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
<...>

and it takes forever again… not a good sign… aaand another giant block of xml.

Searching again finds this page.

Again pointing out that Net::HTTP is the source of the problem…. but I uninstalled the bad version and let the installer install the correct one, right?

 perl -MNet::HTTP -le 'print $Net::HTTP::VERSION'
6.07
perl -e 'use LWP; print LWP->VERSION."\n"'
6.13

WAT?

OK… so lets install specific friggen version manually.  the installer mentions LWP 5.837

cpan -i GAAS/libwww-perl-5.837.tar.gz
perl -MNet::HTTP -le 'print $Net::HTTP::VERSION'
5.834
perl -e 'use LWP; print LWP->VERSION."\n"'
5.837

ok, 17th try is a charm…

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54aead0a-9231b37c-90a6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54aead24-7c23cb62-980e-b82a72d4d796/hostname2/hostname2.vmx
<...>

WOOOOOOOOOOOOO. IT FINALLY WORKS!

… so you remember how we did that, right?

It’s SOOOO tempting to throw my hand up, say done, and walk away, but it doesn’t fit our first requirement- reproducible from ansible.

Remember, you can’t use *cpan* from ansible. Sure, you can use cpanm, but not cpan.

 

Now that I roughly know what I need, I’m going to go back to the Raw Snapshot capture the state of all my perl module directories, reinstall vmware-cli, then bundle them all into a single RPM with FPM. Why? Because CPAN will not be needed at that point, and I will be able to rebuild that state much easier.

Test 3: Clean Slate and FPM

Clean slate sucks because I don’t have sudo set up along with a slew of other useful things. Oh well. First things first- lets get a list of all of our current perl modules

perl -e 'use doesntexist;'
Can't locate doesntexist.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at -e line 1.
BEGIN failed--compilation aborted at -e line 
find /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 >/tmp/pristine.list

Some of those dirs don’t even exist yet, but it’s still important to track them.

I copy the vmware folder back over, and begin installing all of my prereqs. At this point it’s only a few things:

yum install openssl-devel
yum install libuuid-devel perl-YAML perl-Devel-CheckLib gcc perl-CPAN libxml2-devel.x86_64

Next we’re gonna run the installation script. I’m pretty sure that it’ll fail, but at least it’ll configure CPAN the way it needs it rather than me bumbling through it on the first run.

./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes
<...>
Do you want to install precompiled Perl modules for RHEL?
[yes] no
<...>

Can't locate Module/Build.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
BEGIN failed--compilation aborted.
Can't locate LWP.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
BEGIN failed--compilation aborted.
Below mentioned modules with their version needed to be installed,
these modules are available in your system but vCLI need specific 
version to run properly

Module: ExtUtils::MakeMaker, Version: 6.96 
Module: Module::Build, Version: 0.4205 
Module: LWP, Version: 5.837 
Do you want to continue? (yes/no) yes
<...>

CPAN not able to install following Perl modules on the system. These must be 
installed manually for use by vSphere CLI:

Class::MethodMaker 2.10 or newer

OK, now that CPAN is installed, I should be able to simply install these two:

cpan -i JSON::PP
cpan -i Fatal
cpan -i Class::MethodMaker
<...>
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/array.t .............. Can't locate Env.pm in @INC (@INC contains: /root/.cpan/build/Class-MethodMaker-2.24-hloQDv/t /root/.cpan/build/Class-MethodMaker-2.24-hloQDv/blib/lib /root/.cpan/build/Class-MethodMaker-2.24-hloQDv/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /root/.cpan/build/Class-MethodMaker-2.24-hloQDv/t/test.pm line 135.
BEGIN failed--compilation aborted at /root/.cpan/build/Class-MethodMaker-2.24-hloQDv/t/test.pm line 135.
Compilation failed in require at t/array.t line 22.
BEGIN failed--compilation aborted at t/array.t line 22.
t/array.t .............. Dubious, test returned 2 (wstat 512, 0x200)
<...>
Files=8, Tests=0, 1 wallclock secs ( 0.04 usr 0.00 sys + 0.44 cusr 0.06 csys = 0.54 CPU)
Result: FAIL
Failed 8/8 test programs. 0/0 subtests failed.
make: *** [test_dynamic] Error 2
 SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz
 /bin/make test -- NOT OK
//hint// to see the cpan-testers results for installing this module, try:
 reports SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz
Running make install
 make test had returned bad status, won't install without force


Oh FFS. Maybe there’s an Env package I’m unfamiliar with that’s needed? I thought that was part of perl core… apparently not.

cpan -i Env
cpan -i Class::MethodMaker

and rerun the installer again…

./vmware-install.pl --prefix=/opt/vmwarecli EULA_AGREED=yes
<...>
Do you want to install precompiled Perl modules for RHEL?
[yes] no
<...>

SUCCESS.

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54eaad0a-923ab37c-90b6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54eaad24-7c233c62-970e-b82a72d4d796/hostname2/hostname2.vmx
<...>

HURRAY IT WORKS!

Make a quick Snapshot to give us a recovery point.

Cleaning up

While there are many things we need to clean up, there’s one thing I want to get out of the way quickly- removing some of the cruft we installed to get CPAN to work. Unlike Debian’s apt, yum doesn’t notify you when dependencies are no longer needed, so I browed /var/log/yum.log and reviewed all of the packages installed while we were doing this. Here’s the list I came up with:

yum remove libcom_err-devel libsepol-devel zlib-devel keyutils-libs-devel pcre-devel libselinux-devel libverto-devel krb5-devel openssl-devel mpfr libmpc cpp kernel-headers glibc-headers glibc-devel libdb-devel perl-local-lib perl-Digest perl-Digest-SHA gdbm-devel perl-Test-Harness pyparsing systemtap-sdt-devel perl-ExtUtils-Manifest perl-ExtUtils-Install perl-ExtUtils-MakeMaker perl-ExtUtils-ParseXS perl-devel perl-CPAN gcc perl-YAML libuuid-devel perl-Devel-CheckLib xz-devel libxml2-devel

After removing that, we

/opt/vmwarecli/bin/vmware-cmd --server vcenter.domain.com -l -h esxhost1 --username vcenteruser@domain.com --password 'somethingsecure'
/vmfs/volumes/54eaad0a-923ab37c-90b6-b82a72d4d796/hostname1/hostname1.vmx
/vmfs/volumes/54eaad24-7c233c62-970e-b82a72d4d796/hostname2/hostname2.vmx
<...>

Excellent- everything seems to be working.

Lets take one last snapshot of our perl modules for later comparison to pristine.list:

find /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 >/tmp/final.list

 

We now have a functioning vmware-cmd, but it STILL doesn’t meet our primary requirement- it must work via ansible.

 

We’ll pick up the rest in Part 2.

 

Go to Top