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

Commitmas 2015 Is Coming!

Last year, Matt Brender created the 12 Days of Commitmas, a short series of goals and articles on how to get started with Git and make it part of your daily workflow. This year, with the help of the vBrownBag crew, we’re making it bigger and better and calling it the 30 Days of Commitmas! Every workday between 12/1 and 12/30, excepting the 24th and 25th, there will be a new lesson paired with a recorded webinar. The lessons will be focused on a small goal and in the webinar, the presenter will run through the lesson plan and answer any questions presented. I’ll be presenting Rebasing with Git on 12/11.

If you’re relatively new to Git, or know it but haven’t made it part of your daily routine, I encourage you to jump in! We’ll have a little something for people of all skill levels. If you can’t participate in real time, the lessons and recorded webinars will also be available afterward.

If you know Git well, or at least well enough to give a 30-60 minute presentation to others, we could use your help! We need 8 more presenters, as of hitting publish on this post. For those interested in presenting, find an opening on the schedule (webinars are scheduled for 9pm Eastern, we may be able to make some exceptions) and reach out to me, Matt Brender, Cody Bunch, or Jonathan Frappier – or create a fork and submit a PR!

I hope to “see” you all there!

Technical Debt Analogies

Everyone should know what technical debt is, and everyone loves analogies. What better way to explain technical debt, then?

  • Technical debt is not something you fall into, it’s a purposeful assumption of debt. You don’t fall into technical debt, just like you don’t trip and end up with a mortgage on a house – you make the decision to buy a property on credit and go through the effort of ending up with a lot of debt.
  • Technical debt often has a grace period, but it eventually needs to be paid off. It can be like a student loan, you get 6 months after you graduate before you start to owe money.
  • Technical debt’s interest payments increase if you put off paying them. When you don’t pay your minimum payment on your credit card, you get hit with a late fee and your APR skyrockets. Same thing.
  • Rewriting your application to avoid technical debt is like bundling your mortage in a mortgage-backed security and selling it to someone else in your company. The debt didn’t go away and you get to avoid it, but you hurt the economy a little bit. And in the end, you probably end up with another mortgage (technical debt) anyway.

Have I missed any other good ones?

Footloose: A modern day 2112

I blame Ryan McKern for this post, and his silly “head canon” ideas (such as Ronin being a prequel to Meet The Fockers). In that spirit, here’s an exercise in head canon.

While listening to Rush’s 2112 in the car this weekend, for some reason it suddenly struck me that the movie Footloose is really just 2112 set in the current day (don’t ask me how those dots were connected, I have no idea!). They are similar tales of artistic oppression and a revolt against the authorities upholding the suppression. The kids (Anonymous, 2112) want to dance (play guitar), but the town council and the Reverend (the Priests of the Temples of Syrinx) have outlawed it because they want to exert control over everyone’s way of life. When the kids challenge the town council, they are told it’s dangerous and not productive (“Yes, we know, it’s nothing new /It’s just a waste of time … Another toy that helped destroy / The elder race of man”). The ending is a bit different because it’s a Hollywood film, so Kevin Bacon doesn’t commit suicide and there’s no armed revolt against the government, but the kids do get into a fight at the end!

One significant difference: the music is MUCH better in 2112!