Enjoy the Holidays!

Just a reminder that you should enjoy the holidays and take care of yourself! Many of us are looking forward to anywhere from 1 to 4 weeks off in the next two months. We’ll spend that vacation/holiday time learning about new things, participating in the many events (vDM30in30, SysAdvent, Commitmas, who knows what else), and maybe even working. This might be the only time this year you have real downtime in which to learn and partake in events or to get certain things done at work, and you should certainly take advantage of that.

Don’t forget to reserve some time for yourself, though. Give your brain a break. Hang out with your family, watch some TV, have a snowball fight. Put the phones and computers and tablets down for a day or two to recharge those batteries and fend off burnout. If you stink at vacationing, let your friends know and I’m sure they’ll be happy to harrass you when you show up on Facebook and Twitter too much!

Take care of yourself, friends!

Getting a fresh start in a Git repository

Sometimes, the software in a git repository you work with starts to act wonky, especially when running tests, and for no particular reason that you can discern! I saw this recently when I was playing with bundler in some puppet module repos I was setting up to use Travis CI. My rspec tests started failing with nonsensical errors, such as saying it couldn’t find a class that was very much present on disk. What’s worse is that I did a fresh clone of the repo from GitHub into another directory and it worked flawlessly! What the hell? Thankfully, a little kvetching on twitter led to some help from David Schmitt:

//platform.twitter.com/widgets.js

David dropped some great wisdom here (thanks!). Let’s unpack it and understand it.

Continue reading

Troubleshooting Hiera from the CLI

Sometimes it’s very difficult to see how hiera works and what values it might return. To help with troubleshooting, you can use the hiera cli to do lookups yourself. You obviously need to do this on a puppet master, or a node that’s configured to have all the hiera data in the same place the masters do. Here’s the hiera.yaml configuration:

# managed by puppet
---
:backends:
  - yaml
:logger: console
:hierarchy:
  - "clientcert/%{clientcert}"
  - "puppet_role/%{puppet_role}"
  - global

:yaml:
   :datadir: /etc/puppet/environments/%{environment}/hiera

Tier 1: global

Let’s look up the ntp::servers key from the global tier. One thing to note here is that the datadir includes the variable environment, so we will need to provide that tuple to the cli, like so:

Continue reading

Update vSphere host with esxcli

I’ve seen a number of articles describing how to update a vSphere host from the CLI. The problem is that all the articles I found pointed to a particular profile (5.1U3, 6.0GA, etc), which quickly gets out of date. After some searching, I figured out how to list the available profiles from a depot so I could choose the one I want, then upgrade the host. I hope this helps you now and in the future!

First, make sure your host is in maintenance mode and all VMs are migrated off, otherwise you will have an interruption of service. If you only have a single host, this may be unavoidable, and you should let your users know about the upcoming interruption. You also need to have the ESXi shell enabled, and ssh if you don’t have console/out-of-band access.

Second, list the available profiles in the specified depot (in this case, VMware’s Online Depository). The results seem to be unordered, so use grep and sort to help out. For instance, I want the latest 6.0.0 version:

[root@esxi02:~] esxcli software sources profile list -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml | grep 6.0.0 | sort
ESXi-6.0.0-20150404001-no-tools   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150404001-standard   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150504001-no-tools   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150504001-standard   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150701001s-no-tools  VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150701001s-standard  VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150704001-no-tools   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150704001-standard   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150901001s-no-tools  VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150901001s-standard  VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150902001-no-tools   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20150902001-standard   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20151004001-no-tools   VMware, Inc.  PartnerSupported
ESXi-6.0.0-20151004001-standard   VMware, Inc.  PartnerSupported
ESXi-6.0.0-2494585-no-tools       VMware, Inc.  PartnerSupported
ESXi-6.0.0-2494585-standard       VMware, Inc.  PartnerSupported

Pick the version you want, then use esxcli to perform the upgrade. You won’t get any feedback during the upgrade, which can take 5+ minutes, then you get hit with the wall of text. Don’t get anxious until at least 15 minutes go by. The important feedback is at the top of the output and is emphasized in bold:

[root@esxi02:~] esxcli software profile update -d https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml -p ESXi-6.0.0-20151004001-standard
Update Result
   Message: The update completed successfully, but the system needs to be rebooted for the changes to be effective.
   Reboot Required: true
   VIBs Installed: VMware_bootbank_esx-base_6.0.0-1.20.3073146, VMware_bootbank_lsi-mr3_6.605.08.00-7vmw.600.1.17.3029758, VMware_
bootbank_lsi-msgpt3_06.255.12.00-8vmw.600.1.17.3029758, VMware_bootbank_lsu-lsi-lsi-mr3-plugin_1.0.0-2vmw.600.0.11.2809209, VMware
_bootbank_lsu-lsi-megaraid-sas-plugin_1.0.0-2vmw.600.0.11.2809209, VMware_bootbank_lsu-lsi-mpt2sas-plugin_1.0.0-4vmw.600.1.17.3029
758, VMware_bootbank_misc-drivers_6.0.0-1.17.3029758, VMware_bootbank_nvme_1.0e.0.35-1vmw.600.1.17.3029758, VMware_bootbank_sata-a
hci_3.0-22vmw.600.1.17.3029758, VMware_bootbank_scsi-bnx2i_2.78.76.v60.8-1vmw.600.0.11.2809209, VMware_bootbank_vsanhealth_6.0.0-3
000000.2.0.1.17.2972216, VMware_bootbank_xhci-xhci_1.0-2vmw.600.1.17.3029758, VMware_locker_tools-light_6.0.0-1.17.3029758
   VIBs Removed: VMware_bootbank_esx-base_6.0.0-0.6.2715440, VMware_bootbank_lsi-mr3_6.605.08.00-6vmw.600.0.0.2494585, VMware_boot
bank_lsi-msgpt3_06.255.12.00-7vmw.600.0.0.2494585, VMware_bootbank_lsu-lsi-lsi-mr3-plugin_1.0.0-1vmw.600.0.0.2494585, VMware_bootb
ank_lsu-lsi-megaraid-sas-plugin_1.0.0-1vmw.600.0.0.2494585, VMware_bootbank_lsu-lsi-mpt2sas-plugin_1.0.0-1vmw.600.0.0.2494585, VMw
are_bootbank_misc-drivers_6.0.0-0.0.2494585, VMware_bootbank_nvme_1.0e.0.35-1vmw.600.0.0.2494585, VMware_bootbank_sata-ahci_3.0-21
vmw.600.0.0.2494585, VMware_bootbank_scsi-bnx2i_2.78.76.v60.8-1vmw.600.0.0.2494585, VMware_bootbank_xhci-xhci_1.0-2vmw.600.0.0.249
4585, VMware_locker_tools-light_6.0.0-0.0.2494585
   VIBs Skipped: VMWARE_bootbank_mtip32xx-native_3.8.5-1vmw.600.0.0.2494585, VMware_bootbank_ata-pata-amd_0.3.10-3vmw.600.0.0.2494
585, VMware_bootbank_ata-pata-atiixp_0.4.6-4vmw.600.0.0.2494585, VMware_bootbank_ata-pata-cmd64x_0.2.5-3vmw.600.0.0.2494585, VMwar
e_bootbank_ata-pata-hpt3x2n_0.3.4-3vmw.600.0.0.2494585, VMware_bootbank_ata-pata-pdc2027x_1.0-3vmw.600.0.0.2494585, VMware_bootban
k_ata-pata-serverworks_0.4.3-3vmw.600.0.0.2494585, VMware_bootbank_ata-pata-sil680_0.4.8-3vmw.600.0.0.2494585, VMware_bootbank_ata
-pata-via_0.3.3-2vmw.600.0.0.2494585, VMware_bootbank_block-cciss_3.6.14-10vmw.600.0.0.2494585, VMware_bootbank_cpu-microcode_6.0.
0-0.0.2494585, VMware_bootbank_ehci-ehci-hcd_1.0-3vmw.600.0.0.2494585, VMware_bootbank_elxnet_10.2.309.6v-1vmw.600.0.0.2494585, VM
ware_bootbank_emulex-esx-elxnetcli_10.2.309.6v-0.0.2494585, VMware_bootbank_esx-dvfilter-generic-fastpath_6.0.0-0.0.2494585, VMwar
e_bootbank_esx-tboot_6.0.0-0.0.2494585, VMware_bootbank_esx-xserver_6.0.0-0.0.2494585, VMware_bootbank_ima-qla4xxx_2.02.18-1vmw.60
0.0.0.2494585, VMware_bootbank_ipmi-ipmi-devintf_39.1-4vmw.600.0.0.2494585, VMware_bootbank_ipmi-ipmi-msghandler_39.1-4vmw.600.0.0
.2494585, VMware_bootbank_ipmi-ipmi-si-drv_39.1-4vmw.600.0.0.2494585, VMware_bootbank_lpfc_10.2.309.8-2vmw.600.0.0.2494585, VMware
_bootbank_lsu-hp-hpsa-plugin_1.0.0-1vmw.600.0.0.2494585, VMware_bootbank_lsu-lsi-lsi-msgpt3-plugin_1.0.0-1vmw.600.0.0.2494585, VMw
are_bootbank_lsu-lsi-mptsas-plugin_1.0.0-1vmw.600.0.0.2494585, VMware_bootbank_misc-cnic-register_1.78.75.v60.7-1vmw.600.0.0.24945
85, VMware_bootbank_net-bnx2_2.2.4f.v60.10-1vmw.600.0.0.2494585, VMware_bootbank_net-bnx2x_1.78.80.v60.12-1vmw.600.0.0.2494585, VM
ware_bootbank_net-cnic_1.78.76.v60.13-2vmw.600.0.0.2494585, VMware_bootbank_net-e1000_8.0.3.1-5vmw.600.0.0.2494585, VMware_bootban
k_net-e1000e_2.5.4-6vmw.600.0.0.2494585, VMware_bootbank_net-enic_2.1.2.38-2vmw.600.0.0.2494585, VMware_bootbank_net-forcedeth_0.6
1-2vmw.600.0.0.2494585, VMware_bootbank_net-igb_5.0.5.1.1-5vmw.600.0.0.2494585, VMware_bootbank_net-ixgbe_3.7.13.7.14iov-20vmw.600
.0.0.2494585, VMware_bootbank_net-mlx4-core_1.9.7.0-1vmw.600.0.0.2494585, VMware_bootbank_net-mlx4-en_1.9.7.0-1vmw.600.0.0.2494585
, VMware_bootbank_net-nx-nic_5.0.621-5vmw.600.0.0.2494585, VMware_bootbank_net-tg3_3.131d.v60.4-1vmw.600.0.0.2494585, VMware_bootb
ank_net-vmxnet3_1.1.3.0-3vmw.600.0.0.2494585, VMware_bootbank_nmlx4-core_3.0.0.0-1vmw.600.0.0.2494585, VMware_bootbank_nmlx4-en_3.
0.0.0-1vmw.600.0.0.2494585, VMware_bootbank_nmlx4-rdma_3.0.0.0-1vmw.600.0.0.2494585, VMware_bootbank_ohci-usb-ohci_1.0-3vmw.600.0.
0.2494585, VMware_bootbank_qlnativefc_2.0.12.0-5vmw.600.0.0.2494585, VMware_bootbank_rste_2.0.2.0088-4vmw.600.0.0.2494585, VMware_
bootbank_sata-ata-piix_2.12-10vmw.600.0.0.2494585, VMware_bootbank_sata-sata-nv_3.5-4vmw.600.0.0.2494585, VMware_bootbank_sata-sat
a-promise_2.12-3vmw.600.0.0.2494585, VMware_bootbank_sata-sata-sil24_1.1-1vmw.600.0.0.2494585, VMware_bootbank_sata-sata-sil_2.3-4
vmw.600.0.0.2494585, VMware_bootbank_sata-sata-svw_2.3-3vmw.600.0.0.2494585, VMware_bootbank_scsi-aacraid_1.1.5.1-9vmw.600.0.0.249
4585, VMware_bootbank_scsi-adp94xx_1.0.8.12-6vmw.600.0.0.2494585, VMware_bootbank_scsi-aic79xx_3.1-5vmw.600.0.0.2494585, VMware_bo
otbank_scsi-bnx2fc_1.78.78.v60.8-1vmw.600.0.0.2494585, VMware_bootbank_scsi-fnic_1.5.0.45-3vmw.600.0.0.2494585, VMware_bootbank_sc
si-hpsa_6.0.0.44-4vmw.600.0.0.2494585, VMware_bootbank_scsi-ips_7.12.05-4vmw.600.0.0.2494585, VMware_bootbank_scsi-megaraid-mbox_2
.20.5.1-6vmw.600.0.0.2494585, VMware_bootbank_scsi-megaraid-sas_6.603.55.00-2vmw.600.0.0.2494585, VMware_bootbank_scsi-megaraid2_2
.00.4-9vmw.600.0.0.2494585, VMware_bootbank_scsi-mpt2sas_19.00.00.00-1vmw.600.0.0.2494585, VMware_bootbank_scsi-mptsas_4.23.01.00-
9vmw.600.0.0.2494585, VMware_bootbank_scsi-mptspi_4.23.01.00-9vmw.600.0.0.2494585, VMware_bootbank_scsi-qla4xxx_5.01.03.2-7vmw.600
.0.0.2494585, VMware_bootbank_uhci-usb-uhci_1.0-3vmw.600.0.0.2494585

Afterward, you’ll need to reboot the host and you can then take it out of maintenance mode. If you have a large number of hosts, you probably want to investigate VUM, Auto Deploy, or another technology to automate upgrades. On the other hand, this works great for my home lab where I have two hosts and don’t want to maintain a VM just for VUM.

Update your Puppet modules on the Forge quickly with Blacksmith

This weekend, I’ve been playing around with getting my puppet modules up to par with puppet v4. I’ve also recently covered a lot of ground with Rakefiles/Travis CI and excluding files from the build. Building on that, I learned about Blacksmith and how it can let you quickly push new versions of your modules to the forge. It’s really simple.

First, you need an auth file. This belongs to your user, not the module repo, so there’s no chance it will make it into your git repo. You should still be sure it’s not readable to anyone but you, though. The syntax is very simple, just drop this at ~/.puppetforge.yml and replace the defaults with your user/password:

---
url: https://forgeapi.puppetlabs.com
username: myuser
password: mypassword

Next, make sure your module’s Rakefile and Gemfile are set up properly.

$ cat Rakefile
# Relevant snippet
# These gems aren't always present, for instance
# on Travis with --without development
begin
  require 'puppet_blacksmith/rake_tasks'
rescue LoadError # rubocop:disable Lint/HandleExceptions
end

$ cat Gemfile
# Relevant snippet
group :development do
  gem "travis"
  gem "travis-lint"
  gem "puppet-blacksmith"
  gem "guard-rake"
end

Once you use bundler to install the gems locally, you will find some new rake tests available:

$ be rake -T | grep module
rake build                                   # Build puppet module package
rake clean                                   # Clean a built module package
rake module:bump                             # Bump module version to the next patch
rake module:bump:major                       # Bump module version to the next MAJOR version
rake module:bump:minor                       # Bump module version to the next MINOR version
rake module:bump:patch                       # Bump module version to the next PATCH version
rake module:bump_commit                      # Bump version and git commit
rake module:clean                            # Runs clean again
rake module:dependency[module_name,version]  # Set specific module dependency version
rake module:push                             # Push module to the Puppet Forge
rake module:release                          # Release the Puppet module, doing a clean, build, tag, push, bump_commit and git push
rake module:tag                              # Git tag with the current module versio

If your module is ready to go and your authentication works, you just need to do a rake module:release. This will run the following commands (useful if one errors out and you need to replay from there):

bundle exec rake module:clean
bundle exec rake build
bundle exec rake module:tag
bundle exec rake module:push
bundle exec rake module:bump_commit
git push origin

You can of course use the target module:release, or use the independent targets. For instance, I wanted to make sure my build wasn’t 21M again, so I did the bump_commit/clean/build steps first, then the tag/push/git push:

[rnelson0@build02 local_user:master]$ be rake module:bump_commit
Bumping version from 1.0.1 to 1.0.2
[rnelson0@build02 local_user:master]$ be rake build
[rnelson0@build02 local_user:master]$ ls -lh pkg
total 12K
drwxrwxr-x. 5 rnelson0 rnelson0 4.0K Nov 15 17:21 rnelson0-local_user-1.0.2
-rw-rw-r--. 1 rnelson0 rnelson0 7.1K Nov 15 17:21 rnelson0-local_user-1.0.2.tar.gz
[rnelson0@build02 local_user:master]$ be rake module:tag
[rnelson0@build02 local_user:master]$ be rake module:push
Uploading to Puppet Forge rnelson0/local_user
[rnelson0@build02 local_user:master]$ git push origin master
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 317 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@github.com:rnelson0/puppet-local_user
   87a1957..13a66bb  master -> master

For verification, I visit my module on the forge and the latest version now says 1.0.2. Perfect! I know how it works, in case something breaks in the future, and I’m confident that I can release the next version using the module:release target. Thank you to the people at maestrodev and the many  contributors for this awesome tool!

Exclude files from a puppet module release

I ran into a funny problem updating my rnelson0/certs puppet module today. I tried to use puppet-blacksmith to create and push a new build to the Forge. It continually failed with a strange error:

[rnelson0@build02 certs:master]$ be rake module:release
Cleaning for module build
Uploading to Puppet Forge rnelson0/certs
rake aborted!
Errno::ECONNRESET: Connection reset by peer

Well crap, that doesn’t make any sense! Let’s do a build manually and take a look at it:

[rnelson0@build02 certs:master]$ puppet module build
Notice: Building /home/rnelson0/modules/certs for release
Module built: /home/rnelson0/modules/certs/pkg/rnelson0-certs-0.7.0.tar.gz
[rnelson0@build02 certs:master]$ ls -lh pkg
total 21M
drwxrwxr-x. 6 rnelson0 rnelson0 4.0K Nov 15 04:16 rnelson0-certs-0.7.0
-rw-rw-r--. 1 rnelson0 rnelson0  21M Nov 15 04:16 rnelson0-certs-0.7.0.tar.gz
[rnelson0@build02 certs:master]$ tar tzvf pkg/rnelson0-certs-0.7.0.tar.gz | more
drwxrwxr-x rnelson0/rnelson0 0 2015-11-15 04:16 rnelson0-certs-0.7.0/
drwxrwxr-x rnelson0/rnelson0 0 2015-11-15 04:16 rnelson0-certs-0.7.0/tests/
-rw-rw-r-- rnelson0/rnelson0 509 2015-10-24 19:27 rnelson0-certs-0.7.0/tests/init.pp
-rw-rw-r-- rnelson0/rnelson0 911468 2015-11-15 04:16 rnelson0-certs-0.7.0/checksums.json
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/manifests/
-rw-rw-r-- rnelson0/rnelson0    310 2015-10-24 17:27 rnelson0-certs-0.7.0/manifests/init.pp
-rw-rw-r-- rnelson0/rnelson0   2208 2015-10-24 17:27 rnelson0-certs-0.7.0/manifests/vhost.pp
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/classes/
-rw-rw-r-- rnelson0/rnelson0    141 2015-10-24 19:27 rnelson0-certs-0.7.0/spec/classes/init_spec.rb
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/defines/
-rw-rw-r-- rnelson0/rnelson0   1433 2015-10-24 19:27 rnelson0-certs-0.7.0/spec/defines/vhost_spec.rb
-rw-rw-r-- rnelson0/rnelson0     52 2015-10-24 17:27 rnelson0-certs-0.7.0/spec/spec_helper.rb
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/fixtures/
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/fixtures/manifests/
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/spec/fixtures/modules/
-rw-rw-r-- rnelson0/rnelson0   1409 2015-10-24 19:27 rnelson0-certs-0.7.0/Rakefile
-rw-rw-r-- rnelson0/rnelson0   2208 2015-11-15 02:58 rnelson0-certs-0.7.0/README.md
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/vendor/
drwxrwxr-x rnelson0/rnelson0      0 2015-11-15 04:16 rnelson0-certs-0.7.0/vendor/ruby/

Can you see the problem? The vendor directory used by bundler is part of the package. That’s not right! It’s causing the forge connection to timeout because of the size or transmission time. Plus, no-one’s going to download a 21M module. Thankfully, there’s an easy way to fix this. In addition to the .gitignore that we use to prevent files from being made part of the git repository, we also need a .pmtignore, but we only need to exclude the vendors path:

[rnelson0@build02 certs:master]$ cat > .pmtignore
vendor/
[rnelson0@build02 certs:master±]$ puppet module build
Notice: Building /home/rnelson0/modules/certs for release
Module built: /home/rnelson0/modules/certs/pkg/rnelson0-certs-0.7.0.tar.gz
[rnelson0@build02 certs:master±]$ ls -lh pkg
total 12K
drwxrwxr-x. 5 rnelson0 rnelson0 4.0K Nov 15 04:23 rnelson0-certs-0.7.0
-rw-rw-r--. 1 rnelson0 rnelson0 7.0K Nov 15 04:23 rnelson0-certs-0.7.0.tar.gz
[rnelson0@build02 certs:master±]$ tar tzvf pkg/rnelson0-certs-0.7.0.tar.gz
drwxrwxr-x rnelson0/rnelson0 0 2015-11-15 04:23 rnelson0-certs-0.7.0/
drwxrwxr-x rnelson0/rnelson0 0 2015-11-15 04:23 rnelson0-certs-0.7.0/tests/
-rw-rw-r-- rnelson0/rnelson0 509 2015-10-24 19:27 rnelson0-certs-0.7.0/tests/init.pp
-rw-rw-r-- rnelson0/rnelson0 631 2015-11-15 04:23 rnelson0-certs-0.7.0/checksums.json
-rw-rw-r-- rnelson0/rnelson0 10143 2015-11-15 03:42 rnelson0-certs-0.7.0/Gemfile.lock
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/manifests/
-rw-rw-r-- rnelson0/rnelson0   310 2015-10-24 17:27 rnelson0-certs-0.7.0/manifests/init.pp
-rw-rw-r-- rnelson0/rnelson0  2208 2015-10-24 17:27 rnelson0-certs-0.7.0/manifests/vhost.pp
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/classes/
-rw-rw-r-- rnelson0/rnelson0   141 2015-10-24 19:27 rnelson0-certs-0.7.0/spec/classes/init_spec.rb
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/defines/
-rw-rw-r-- rnelson0/rnelson0  1433 2015-10-24 19:27 rnelson0-certs-0.7.0/spec/defines/vhost_spec.rb
-rw-rw-r-- rnelson0/rnelson0    52 2015-10-24 17:27 rnelson0-certs-0.7.0/spec/spec_helper.rb
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/fixtures/
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/fixtures/manifests/
drwxrwxr-x rnelson0/rnelson0     0 2015-11-15 04:23 rnelson0-certs-0.7.0/spec/fixtures/modules/
-rw-rw-r-- rnelson0/rnelson0  1409 2015-10-24 19:27 rnelson0-certs-0.7.0/Rakefile
-rw-rw-r-- rnelson0/rnelson0  2208 2015-11-15 02:58 rnelson0-certs-0.7.0/README.md
-rw-rw-r-- rnelson0/rnelson0   861 2015-10-24 19:27 rnelson0-certs-0.7.0/Gemfile
-rw-rw-r-- rnelson0/rnelson0   506 2015-11-15 04:23 rnelson0-certs-0.7.0/metadata.json
[rnelson0@build02 certs:master±]$

I’m going to submit a PR against puppet-module-skeleton to get that file added for the future (PR95).

Adding a gem to your project with bundler

Now that we know the basics of how to use bundler, let’s put our new knowledge to good use by adding a gem to a project. We’ll look at how to add generate-puppetfile to a puppet Controlrepo, but you can add any gem to any project you’d like. It’s very simple.

Start by cloning your project and checking out a new branch:

[rnelson0@build02 controlrepo:production]$ git checkout -b generate-puppetfile
Switched to a new branch 'generate-puppetfile'

Open up the existing Gemfile. If you don’t have one, you just need the source statement followed by one or more gems.

[rnelson0@build02 controlrepo:generate-puppetfile]$ cat Gemfile
source 'https://rubygems.org'

group :development, :test do
  gem 'json', :require => false
  gem 'metadata-json-lint', :require => false
  gem 'puppetlabs_spec_helper', :require => false
  gem 'puppet-lint', :require => false
  gem 'rake', :require => false
  gem 'rspec-puppet', :require => false
end

if puppetversion = ENV['PUPPET_GEM_VERSION']
  gem 'puppet', puppetversion, :require => false
else
  gem 'puppet', :require => false
end

# vim:ft=ruby

Add the gem (generate-puppetfile) to the file:

[rnelson0@build02 controlrepo:generate-puppetfile]$ cat Gemfile
source 'https://rubygems.org'

group :development, :test do
  gem 'json', :require => false
  gem 'metadata-json-lint', :require => false
  gem 'puppetlabs_spec_helper', :require => false
  gem 'puppet-lint', :require => false
  gem 'rake', :require => false
  gem 'rspec-puppet', :require => false
  gem 'generate-puppetfile'
end

if puppetversion = ENV['PUPPET_GEM_VERSION']
  gem 'puppet', puppetversion, :require => false
else
  gem 'puppet', :require => false
end

# vim:ft=ruby

Now run bundle install:

[rnelson0@build02 controlrepo:generate-puppetfile]$ bundle install --path vendor --without system_tests
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/..
Installing rake 10.4.2
Installing diff-lcs 1.2.5
Installing facter 2.4.4
Installing generate-puppetfile 0.9.6
Installing json_pure 1.8.2
Installing hiera 1.3.4
Installing json 1.8.3 with native extensions
Installing metaclass 0.0.4
Installing spdx-licenses 1.0.0
Installing metadata-json-lint 0.0.11
Installing mocha 1.1.0
Installing puppet 3.7.3
Installing puppet-lint 1.1.0
Installing puppet-syntax 2.0.0
Installing rspec-core 2.99.2
Installing rspec-expectations 2.99.2
Installing rspec-mocks 2.99.4
Installing rspec 2.99.0
Installing rspec-puppet 2.2.0
Installing puppetlabs_spec_helper 0.10.3
Using bundler 1.10.6
Bundle complete! 8 Gemfile dependencies, 21 gems now installed.
Gems in the group system_tests were not installed.
Bundled gems are installed into ./vendor.

And now you can use the gem in your project with bundle exec, without installing it globally:

[rnelson0@build02 controlrepo:generate-puppetfile]$ bundle exec generate-puppetfile -v
generate-puppetfile v0.9.6

At this point, it may be worth adding an alias to our shell:

[rnelson0@build02 controlrepo:generate-puppetfile]$ alias be
alias be='bundle exec'

Enjoy!

Getting started with Bundler

Not too long ago, I learned about bundler. It’s a solution that allows you to have multiple versions of ruby gems installed, specific to the project you’re working on, without affecting the globally installed ruby gems. I’m far from an expert but I hope I can help explain it a bit. To get started, install the bundler gem – it’s the one and only global gem we’ll need to install. You’ll see the dependencies installed as well if you do not have them:

[root@build02 ~]# gem install bundler
Fetching: bundler-1.10.6.gem (100%)
Successfully installed bundler-1.10.6
Installing ri documentation for bundler-1.10.6
1 gem installed

Now, clone a ruby project with a Gemfile. I’ve chosen puppet-retrospec:

[rnelson0@build02 git]$ git clone git@github.com:nwops/puppet-retrospec.git
Initialized empty Git repository in /home/rnelson0/git/puppet-retrospec/.git/
remote: Counting objects: 3246, done.
remote: Compressing objects: 100% (100/100), done.
remote: Total 3246 (delta 45), reused 0 (delta 0), pack-reused 3127
Receiving objects: 100% (3246/3246), 2.32 MiB | 2.67 MiB/s, done.
Resolving deltas: 100% (829/829), done.
[rnelson0@build02 git]$ cd puppet-retrospec/
[rnelson0@build02 puppet-retrospec:master]$

Try and run rake and you’ll notice it’s missing a dependency:

[rnelson0@build02 puppet-retrospec:master]$ rake -T
Could not find addressable-2.3.8 in any of the sources
Run `bundle install` to install missing gems

Continue reading

Addressing vDM30in30 Blog Post Quality

As you surely know by now, I’m participating in the vDM30in30 blogging challenge. Create 30 blog posts in the 30 days of November, of whatever length and topic you desire, in an effort to facilitate the practice and improvement of writing skills. I have seen some complaints that the quality is not up to par and I’d like to address that briefly.

Participants: The 30 in 30 challenge has two goals. The first is to get you in the practice or habit of writing blog posts. If you write one a day for a whole month, you’re more likely to write some more next month instead of waiting a year in between posts. Second, it’s to help you improve your writing skills. If the blog post on November 30th is of the same quality as the one on November 1st, you may not have benefited as much as you could have. Write with improvement in mind. If you find yourself struggling in an area that you can’t fix on your own, reach out for help. If you need to take your post and copy and paste it into Word or Google Docs for a spelling or grammar check, do it. You owe it to yourself to make sure you use this time wisely to better yourself.

Readers: The participants are taking part in this challenge because they want to improve. Understand that some of the posts aren’t going to be of great quality – perhaps the author is early in their journey of improvement, or perhaps it became difficult to find the time in the heavy pace of 1 post a day. Also understand that the participants DO want to improve and constructive criticism is vital. Let the author know, in a constructive manner, about what areas they are struggling with. Drop a comment in their blog or hit them up on twitter. If you think your public criticism would be harsh or take away from the post itself, send a DM or ask the author for another way to contact them. Providing constructive criticism will help the participants, which will improve their posts, hopefully improving your enjoyment of the challenge.

Together, we can make all those November 30th articles really great! 🙂

Lessons Learned from Migrating a DVS

Recently, I “fortunate” enough to experience some issues with a vCenter Server or VCS, the version of vCenter that you install on Windows. It had been upgraded 5.1->5.5->6.0->6.0U1 and apparently something broke along the way. I much prefer the VCSA, so this wasn’t the end of the world, but the issues we encountered forced our hand as to timing. Therefore, some of the migration steps were a bit ad hoc. This was also a small installation (<25 hosts) and a one-time event, so the question Is It Worth The Time? to automate the migration was judged to be a no. I still think that was the right evaluation, but we did find one thing that added some time to the effort: migrating a Distributed vSwitch (DVS).

The process we followed at first was:

  1. Export the DVS from the VCS
  2. Import the DVS to the VCSA with the Preserve box checked
  3. Disconnect/Remove From Inventory a host from the VCS
  4. Add A Host to the VCSA
  5. Attach the host to the DVS
  6. Repeat steps 3-5 for all hosts

Continue reading