https://horrell.ca/https://horrell.ca/favicon.pngHorrell.cahttps://horrell.ca/Ghost 2.18Tue, 19 Mar 2019 13:42:33 GMT60MSBuild has a lot of command line options that are relevant when building in a Jenkins pipeline.

A useful command argument to set is /nodeReuse:false. This ensures that MSBuild.exe exits after being called. The default is true and is meant to reduce the startup time for subsequent builds.

A useful command argument to set is /nodeReuse:false. This ensures that MSBuild.exe exits after being called. The default is true and is meant to reduce the startup time for subsequent builds. In a Jenkins pipeline, this isn't really useful since all processes are killed off at the end of a build. In fact, the default true option can be problematic in cases where you have later stages in your pipeline that might do a cleanup or a git clean -fdx but can't because a MSBuild.exe process is holding a file open (like a DLL from a Nuget package).

At work we use declarative pipelines for everything and based on our experience building Visual Studio projects, a simple pipeline would look something like this:

It's pretty bare bones, and doesn't include tests, but you get the idea.

]]>If you run Jenkins in the cloud or locally, chances are good that you have it behind a reverse proxy, typicaly Nginx. Nginx is the goto for this sort of thing and the Jenkins docs have decent recommendation for setting it up.

If you run Jenkins in the cloud or locally, chances are good that you have it behind a reverse proxy, typicaly Nginx. Nginx is the goto for this sort of thing and the Jenkins docs have decent recommendation for setting it up.

If you want to connect to Jenkins remotely via the Jenkins CLI there are two settings you need to disable in your Nginx config:

]]>]]>https://horrell.ca/2017/01/21/denise-horrell-1937-2017/5bea3b220aad436310f3d25fSat, 21 Jan 2017 14:30:12 GMT
]]>Last month I was working on a FreeBSD 10.1 KVM image for SmartOS, SmartDataCenter and the Joyent Public Cloud. The first version of the image was released a few weeks ago and I'd like to share how I went about building the image. More specifically, I'd like to provide]]>https://horrell.ca/2014/12/03/creating-a-custom-freebsd-10-iso-with-automated-installation/5bea3b220aad436310f3d25eThu, 04 Dec 2014 03:11:04 GMT

Last month I was working on a FreeBSD 10.1 KVM image for SmartOS, SmartDataCenter and the Joyent Public Cloud. The first version of the image was released a few weeks ago and I'd like to share how I went about building the image. More specifically, I'd like to provide an overview of how I built a custom FreeBSD 10.1 ISO that I use as part of my build process.

A Little Background

If you're not familiar with how KVM images are created for SmartOS/SmartDataCenter the general workflow goes like this:

For this post, I'm going to focus on steps 3 to 5 which are all handled via a custom ISO I built and helps to speed up the whole process tremendously.

Building a Custom FreeBSD 10.1 ISO

Before I begin, you can find all my scripts and files I used to build a custom FreeBSD ISO on GitHub here: mi-freebsd-10 . Pretty much everything I'm going to talk about can be found in the build_freebsd_iso script, so if you want take a look at that first, got for it.

Building a custom FreeBSD ISO is fairly easy but there are a few catches (more on that later). Once you have the source ISO (e.g., FreeBSD-10.1-RELEASE-amd64-disc1.iso) you mount it, make the modifications you need, then create a new custom ISO. If you're doing this under FreeBSD, it would look something like this:

One thing you'll notice about the above code is that I'm getting the ISO label using isoinfo. Starting with the FreeBSD 10.1 release, each ISO label (or "Volume ID") is unique and is based on the release information (version, architecture, that kind if thing). If you don't use the correct label in your custom ISO, the FreeBSD installation will fail spectacularly! I learned this the hard way...

As for actually customizing the ISO itself, there are a couple of tricks to that. First, modifications you make to the ISO won't actually be included in your FreeBSD installation. So for example, if you make changes to /mnt/custom-freebsd-iso/etc/rc.conf it won't be included in the installation when you start the install process. Typically you'd want to do things like add networking info to the rc.conf file so the installer has network access (ifconfig_vtnet0="DHCP") or shorten the boot delay by adding autoboot_delay="5" to /mnt/custom-freebsd-iso/boot/loader.conf (the default is 10 seconds). So what if you want to have an installation that has modifications to the rc.conf file? And how do you add new files to the installation? Well, it turns out that FreeBSD allows you to script the installation process!

Automating the Installation

FreeBSD 9.0 introduced a new installer called bsdinstall. When you boot a FreeBSD 9.0 or newer ISO the installer is automatically started once the boot timer runs out, which kicks off the bsdinstall process.

You can automate the installation by including a file called installerconfig in the /etc/ folder of the ISO. When the FreeBSD installation starts it looks for that file. The file allows you to set some configuration defaults in a "preamble" section using environment variables. It's similar to a Kickstart file you'd use in Fedora or CentOS. If you take a look at the installerconfig file in the mi-freebsd-10 repos you'll see that I have it partition vtbd0 using the typical defaults:

PARTITIONS=vtbd0

You'll also notice I'm telling the installer to include the following distributions:

DISTRIBUTIONS="kernel.txz base.txz joyent.txz"

If you want a minimal FreeBSD install, you'd typically just have kernel.txz base.txz here. So what's the joyent.txz distribution file and where did it come from? Glad you asked! That's how I install the various guest tools I need for our KVM image to run under SmartOS and SmartDataCenter. I'll get back to that in a bit, but there's more stuff in the installerconfig script I want to cover.

After the preamble section theres the "Setup Script" which starts with a shebang:

#!/bin/sh

Here is where you do all your customization occurs. This section is run after the FreeBSD installation completes. Looking at the installerconfig file on GitHub you can see this is where I do things like modify the rc.conf file for the installation, create a custom /etc/motd file and install packages via pkg install -y. But what about adding new files?

Adding a Custom Distribution File

The installerconfig file lets you do a lot of useful things. One thing that you can't do is copy files into the installation. This is because at this point the installation is all happening within a chroot. By default that's the /mnt directory (which you can change via the BSDINSTALL_CHROOT environment variable, so the installation is run in that directory with no visibility to anything outside of it. That means you can't copy files over using the scripted part of installerconfig. This is where the joyent.txz distribution comes in.

To install files to the installation, you just save them all as a distribution file, the add that file to DISTRIBUTIONS= in the preamble of installerconfig. The bsdinstall process will take you distribution file and unpack it to where it needs to go.

Here's the basic steps for creating the distribution file called custom. Let's say you have a custom rc.conf file that you want to include. Create a directory called custom_files.

mkdir custom_files

The rc.conf file likes in /etc, so you need to create an /custom_files/etc folder to match:

mkdir custom_files/etc

Now, add your file to custom_files/etc and create the distribution using the tar command:

And that's it, you're custom rc.conf file is now in a distribution file called "custom.txz". If you include in in the preamble part of your installerconfig file (e.g., DISTRIBUTIONS="kernel.txz base.txz custom.txz"), bsdinstall will unpack and copy everything in your custom distribution over to their respective directories.

One final thing to note about the installerconfig: at the end of the file I'm issuing the poweroff command. Normally the bsdinstall process will run what's after the shebang and then automatically reboot. Since I'm creating a SmartOS/SmartDataCenter image, I don't want that to happen because I need to do a snapshot. Issuing a full shutdown at the end prevents the automatic reboot from happening.

So that's pretty much it. The above information should hopefully be useful to anyone who wants to create a custom FreeBSD ISO with an automated/unattended installation.

And special thanks to Daniel Malon who provide a lot of help and introduced me to the bsdinstall man page :)

]]>I recently switched Horrell.ca from Textpattern to Ghost. Chances are there are a bunch of broken links to files and such. I'm still tweaking and fixing things and reworking the site design, so expect more changes in the coming months :)

For anyone else who wants to attempt this, a

]]>https://horrell.ca/2014/03/23/switching-over-from-textpattern-to-ghost/5bea3b220aad436310f3d255Sun, 23 Mar 2014 21:05:31 GMTI recently switched Horrell.ca from Textpattern to Ghost. Chances are there are a bunch of broken links to files and such. I'm still tweaking and fixing things and reworking the site design, so expect more changes in the coming months :)

For anyone else who wants to attempt this, a word of warning: there's no easy way to export content from Textpattern to import into Ghost. Ideally, a Textpattern plugin for this would help tremendously, but I wasn't able to find one. I was going to attempt to create one myself, but it's been so long since I've worked in PHP or created a Textpattern plugin that it didn't seem to be worth my time. Instead I (mostly) followed the instructions I found here. The short version of what you have to do: you need to temporarily setup a WordPress blog, import your Textpattern posts into that, then export your posts via a Ghost WordPress plugin, then import into Ghost. Yeah. If you use Textpattern and are thinking about moving to Ghost, it might be best to wait for a bit until bettor options come up.

Despite all that, at least for me, the switch has been worthwhile. It's a great platform for writting and since it runs on Node.js, it's very light on resources. I was able to resize my current Joyent SmartOS instance down significantly since removing Apache and MySQL from the equation.

Speaking of SmartOS instances, I created a handy script for getting Ghost up and running on Joyent called smarty-ghost . It works fairly well and takes care of setting up the SMF manifest for you. I'll be improving that script over time and the install process should become much simpler when Ghost becomes an published npm package.

Oh, and while I was moving things around on my site I put all the Textpattern plugins I created over the years on GitHub. I probably won't be using Textpattern much or contributiing to the ecosystem anymore, but my old code is out there for anyone who might find it usefull. Here's a list of links to each plugin repo:

]]>]]>https://horrell.ca/2012/03/14/i-could-watch-this-all-day/5bea3b220aad436310f3d24aWed, 14 Mar 2012 17:18:18 GMT
]]>CloudFlare is a great service and I’ve been using for my horrell.ca site for some time. It speeds everything up, acts as a firewall protecting your site from bots and jerks, and also provides IPv6 support. One side affect of using CloudFlare is the Apache logs for]]>https://horrell.ca/2012/02/12/installing-mod_cloudflare-on-a-joyent-smartmachine/5bea3b220aad436310f3d24bSun, 12 Feb 2012 17:17:00 GMTCloudFlare is a great service and I’ve been using for my horrell.ca site for some time. It speeds everything up, acts as a firewall protecting your site from bots and jerks, and also provides IPv6 support. One side affect of using CloudFlare is the Apache logs for your site will show IP addresses from the CloudFlare network for any site visitors rather than the true visitors IP address. You can fix that by installing the mod_cloudflare Apache module.

And that’s it! If you check your Apache logs (/var/log/httpd/access.log or /home/NAMEOFSITE/logs/access.log) you should start seeing accurate IP addresses.

You can check if the installation went smoothly with:

svcs -vx apache

If Apache is in maintenance, chances are something went wrong with loading the module. The /var/svc/log/network-apache:default.log service log file will give an idea of what you need to fix.

Periodically, CloudFlare adds new IP addresses to their network, so you’ll need to reinstall the module. You don’t need to do anything special for that, just repeat the above steps using the updated mod_cloudflare.c. source file. I follow the git repos for changes (which doesn’t happen that often).

]]>The introduction of folders to iOS was a welcome addition to keeping your home screen tidy. Folders allows you to sensible group like applications and then give the folder a given name, like "Games" for all your game apps etc. In iOS 5, Emoji support was added which]]>https://horrell.ca/2011/10/28/adding-icons-to-folder-names-in-ios/5bea3b220aad436310f3d252Fri, 28 Oct 2011 19:10:48 GMT

The introduction of folders to iOS was a welcome addition to keeping your home screen tidy. Folders allows you to sensible group like applications and then give the folder a given name, like "Games" for all your game apps etc. In iOS 5, Emoji support was added which means you can also use Emoji as icons in your folder names for added bit of flare, like this:

Cool huh?

So here's what you need to do to enable Emoji and then use it in a folder name.

All done? Good! Now, touch and hold a folder you want to add an Emoji icon to and then touch it again and you'll see something like this:

Cool, now touch the folder name (in this example Games) and you'll see something like this:

You may have noticed the new globe icon on the keyboard. Touch it and you'll see something like this:

Tada, an Emoji keyboard!

From here, pick the Emoji you'd like to use, insert it into the folder name (I like to put them at the beginning), touch the globe icon again and then touch Done. The keyboard will then disappear and you can press the Home button to save you changes.

You may have noticed that I had an  icon for the folder in the top right, but that icon is not actually available via the Emoji keyboard. I used Neven Mrgan’s cool Glyphboard (Glyphboard iPhone web app) to add it. From Glyphboard, I just copied the  icon and then pasted it in the folder name.

]]>Here are some updated instructions for installing the latest stable version of node (v0.4.12), as well as npm, on a Joyent SmartMachine.

These instructions install node in the ~/local directory avoiding the need for root privileges when installing things with npm, which is bad.

First, create a ~src/

]]>https://horrell.ca/2011/01/30/installing-node-and-npm-on-a-joyent-smartmachine/5bea3b220aad436310f3d249Sun, 30 Jan 2011 06:19:12 GMTHere are some updated instructions for installing the latest stable version of node (v0.4.12), as well as npm, on a Joyent SmartMachine.

These instructions install node in the ~/local directory avoiding the need for root privileges when installing things with npm, which is bad.

First, create a ~src/ directory — this is where we’ll download the latest version of node.

The gmake part will probably take the longest. And you’ve probably noticed I’m using gtar instead of tar and gmake instead of make. There are some difference between the Solaris versions and the GNU versions.

]]>I hate the caps lock key. Hate. I'm always, always pressing it by accident. I don't do it that often on my iMac, but boy howdy, I click it all the time on my MacBook Pro. At my old gig, when I did the nine to five thing in a]]>https://horrell.ca/2011/01/29/disabling-the-caps-lock-key-on-a-mac/5bea3b220aad436310f3d248Sat, 29 Jan 2011 05:51:52 GMT

I hate the caps lock key. Hate. I'm always, always pressing it by accident. I don't do it that often on my iMac, but boy howdy, I click it all the time on my MacBook Pro. At my old gig, when I did the nine to five thing in a beige cubicle (it might have been a dirty white, actually) I removed it from the keyboard and put it in a drawer (see blurry photo here. Now that's just not something I want to do with my Mac hardware. The IBM keyboard at work was easy enough, but I don't even know if it's possible on the newer Mac keyboards. Plus it looks bad and isn';t the most elegant solution so I've had to put up with it. Until now!

If you own a Mac and have the same stewing hate for the caps lock key that I do, here's how you can disable it.

Open System Preferences

Select Keyboard

Click the Modifier Keys... button. You should now see something like this:

Change the Caps Lock key value to No Action so that it looks like this:

Click OK.

And thats it, no more caps lock key madness!

]]>So you use a Mac and you notice that you see lots of errors like this in the Console.app application:

]]>https://horrell.ca/2010/12/20/comakamaiclientplist-errors/5bea3b220aad436310f3d247Mon, 20 Dec 2010 20:39:48 GMTSo you use a Mac and you notice that you see lots of errors like this in the Console.app application:

This happens every ten seconds and you may even notice some performance issues with your Mac because of this. Thanks to this post from Ignored By Dinosaurs, I was able to finally figure out the cause. This error shows up after you've deleted the Akamai download manager that Adobe forces you to use to download one of their products.

I have a different solution to getting rid of this error though, one that does not involve downloading the Akamai download manager again.

First, start the Terminal.app application (located in the /Applications/Utilities folder).

Next, in Terminal.app run this:

launchctl unload ~/Library/LaunchAgents/com.akamai.client.plist

That will stop the annoying com.akamai.client.plist job and unload it's launchd config.

Now let's remove the com.akamai.client.plist config completely so it doesn't start up again. From Terminal.app, run this:

rm -rf ~/Library/LaunchAgents/com.akamai.client.plist

Now, log out and back in again. You can verify the com.akamai.client.plist entry is not loaded by running this from Terminal.app:

launchctl list com.akamai.client.plist

If it produces the launchctl list returned unknown response error, then you know it's gone.

Here's a little tip for installing node.js (latest) on a Joyent SmartMachine (formerly called an Accelerator).

First, you'll need to be root, so lets get that out of the

]]>https://horrell.ca/2010/05/28/installing-nodejs-on-a-joyent-smartmachine/5bea3b220aad436310f3d245Fri, 28 May 2010 22:33:44 GMTUPDATE These instructions have been replaced by the much better instructions here: Installing node and npm on a Joyent SmartMachine

Here's a little tip for installing node.js (latest) on a Joyent SmartMachine (formerly called an Accelerator).

First, you'll need to be root, so lets get that out of the way:

su -

Next, create a ~src/ directory in the home directory of root and download node.js:

mkdir src
cd src
curl -O http://nodejs.org/dist/node-latest.tar.gz

untar it:

gtar -xpf node-latest.tar.gz

Now, configure, build, and install:

cd node-v*
./configure
gmake
gmake install

The gmake part will probably take the longest. And you've probably noticed I'm using gtar instead of tar and gmake instead of make. There are some difference between the Solaris versions and the GNU versions.

And that's it!

]]>cnn.com: Remove Comments is a Greasemonkey user script for the Firefox or Safari web browser. This script removes comments from the CNN website.

To use this script you first need to make sure you have Greasemonkey installed and enabled for Firefox or GreaseKit installed and enabled for Safari. With

You should now see an Greasemonkey or GreaseKit installation dialogue.

Click Install

And that's it, cnn.com: Remove Comments script is installed! Enjoy!

File downloads will be back soon!

]]>Here's a recent discovery I'd like to share: you can actually run Greasemonkey scripts in Safari. The solution is simple: install GreaseKit. You can find some good instructions on installing GreaseKit here.

Once installed, you can use any of my Greasemonkey scripts in Safari on a mac just like in

]]>https://horrell.ca/2009/11/30/installing-greasemonkey-scripts-in-safari/5bea3b220aad436310f3d243Mon, 30 Nov 2009 14:42:35 GMTHere's a recent discovery I'd like to share: you can actually run Greasemonkey scripts in Safari. The solution is simple: install GreaseKit. You can find some good instructions on installing GreaseKit here.

Once installed, you can use any of my Greasemonkey scripts in Safari on a mac just like in Firefox. I'll update the pages for each of my scripts to include this information as well as instructions for installing the scripts in the next few days. Installation should be easy enough though. In fact, you should just be able to click the download link for each file and you'll see an installer prompt. This should also work in Firefox and is a much quicker way to install scripts — another recent discovery of mine, ahem.

]]>youtube.com: Remove Comments is a Greasemonkey user script for the Firefox or Safari web browser. This script removes comments from YouTube.

To use this script you first need to make sure you have Greasemonkey installed and enabled for Firefox or GreaseKit installed and enabled for Safari. With that out