This commit is contained in:
James McDonald
2018-01-09 20:39:32 +01:00
parent d86f2129f0
commit 96eedb5095
64 changed files with 682 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
date: {{ .Date }}
draft: true
---
+5
View File
@@ -0,0 +1,5 @@
url: https://jamesmcdonald.com
name: James McDonald
description: Stuff I wrote about things
theme: bootstrap4
disqusShortname: jamesmcdonald
+10
View File
@@ -0,0 +1,10 @@
---
title: About this Site
author: james
type: page
date: 2010-08-22T15:06:56+00:00
dsq_thread_id:
- 438232275
---
A place where I occasionally write about things if I have the time or inclination.
@@ -0,0 +1,17 @@
---
title: Gah, not another bloody blog
author: james
type: post
date: 2010-08-22T16:08:20+00:00
url: /2010/08/gah-not-another-bloody-blog/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 438228149
categories:
- Meta
---
I felt the need for a place to put the occasional rant that’s longer than 140 characters. This may not happen very often, but it’ll happen here if you’re interested in that sort of thing.
+18
View File
@@ -0,0 +1,18 @@
---
title: Norskups
author: james
type: post
date: 2011-04-11T19:06:39+00:00
url: /2011/04/norskups/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 469641387
categories:
- Language
- Meta
---
I would appear to have accidentally stirred up the norsktwitterredet. I’d better write something here in case they look.
@@ -0,0 +1,39 @@
---
title: Invert mouse scroll wheel in Debian
author: james
type: post
date: 2011-07-21T11:49:01+00:00
url: /2011/07/invert-mouse-scroll-wheel-in-debian/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 440701348
categories:
- Hacks
---
I’ve been using the beta of MacOS X Lion for a few weeks now, and after a few days of initial annoyance I’ve grown to really like the inverted sense of the scroll wheel. I recall when I first got one, in fact, and found the direction downright confusing. This seems to have been an easy behaviour to unlearn.
My desktop box at work runs Debian, and I wanted the same behaviour there to stop me getting split-brain and dribbling a lot. There was a time when a quick change in xorg.conf to `ZAxisMapping "5 4"` would do this, but it’s not so the modern age of HIDs and evdevs. After a bit of messing about I figured out how to flip the scroll wheel. This will probably work for Ubuntu too.
* Open the file `/usr/share/X11/xorg.conf.d/10-evdev.conf`
* Look for the section with `MatchIsPointer "on"`. It’s at the top by default.
* Add this line:
`Option "ButtonMapping" "1 2 3 5 4 6 7 8"</li>
<p>` </ul>
Add more buttons if you need them for your mouse. The section should look like:
`<br />
Section "InputClass"<br />
Identifier "evdev pointer catchall"<br />
MatchIsPointer "on"<br />
MatchDevicePath "/dev/input/event*"<br />
Driver "evdev"<br />
Option "ButtonMapping" "1 2 3 5 4 6 7 8"<br />
EndSection<br />
`
That&#8217;s it! Just restart X.
@@ -0,0 +1,42 @@
---
title: Linux locale problems over ssh from a Mac
author: james
type: post
date: 2011-10-06T08:07:16+00:00
url: /2011/10/linux-locale-problems-over-ssh-from-a-mac/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 438230874
categories:
- Debian
- Hacks
- Ubuntu
---
Most users of Debian/Ubuntu have at some time seen these annoying messages:
`<br />
perl: warning: Setting locale failed.<br />
perl: warning: Please check that your locale settings:<br />
LANGUAGE = (unset),<br />
LC_ALL = (unset),<br />
LC_CTYPE = "UTF-8",<br />
LANG = "en_GB.UTF-8"<br />
are supported and installed on your system.<br />
perl: warning: Falling back to the standard locale ("C").<br />
`
There are a variety of causes &#8211; usually locales not being generated properly or incorrect environment variables.
Lately I&#8217;ve been getting these a lot of these, but only some of the time. After some messing around I eventually discovered the problem wasn&#8217;t on the server itself. The problem only occurs when I&#8217;m logged in over SSH from a Mac. The default sshd on Debian **copies LANG and LC_* variables** from the client. The LC_CTYPE variable was set on my Mac, apparently by default, to &#8220;UTF-8&#8221;. While this seems to work on MacOS X, it&#8217;s not a valid value for Linux.
The easiest solution was just to add the following to my ~/.profile on the Mac:
`<br />
export LC_CTYPE=en_GB.UTF-8<br />
`
That fixes it, and doesn&#8217;t appear to cause harm on the Mac.
@@ -0,0 +1,28 @@
---
title: Get off of my iCloud
author: james
type: post
date: 2011-10-09T10:06:30+00:00
url: /2011/10/get-off-of-my-icloud/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 438212576
categories:
- Apple
- Tech
---
Like several people I know, I have two AppleID accounts for personal use. I have one that I set up back when an iPod was my only Apple gadget and they first opened the iTunes Store. This has all my (large number of) iTunes purchases associated with it. I also have a MobileMe account that I set up a while later when I first bought a Mac, which I now largely use for the me.com email address associated with it. So far this has worked nicely. I log in to the iTunes account for iTunes and to the MobileMe account for email, sync etc.
The age of iCloud is rapidly approaching. We MobileMe users have an easy migration path, and until next summer to migrate. The idea with iCloud is that you need log in to only one service for everything. This makes sense: the idea is that you have everything bound to a single identity. You log in to that and you get all your email, calendar, backups, media, apps etc. Shiny. Except&#8230;
The MobileMe-iCloud migration FAQ makes it clear that accounts can&#8217;t be merged. This is Apple&#8217;s historical policy &#8211; whatever opinion one has about it, it&#8217;s not unexpected. Generally the opinion one has about it is that it&#8217;s somewhat lame, especially when the merging of iTunes and MobileMe is the entire \*point\* of iCloud (other than gaining distance from the now-embarrassing MobileMe brand and using the word &#8216;cloud&#8217; in something).
The trick is that they also don&#8217;t make it clear whether you can do a &#8216;manual&#8217; merge. If I close my MobileMe account, I don&#8217;t know whether that will make my email address available to attach to my iCloud account. I&#8217;ve just spoken to Apple&#8217;s MobileMe support and they don&#8217;t know either, though iCloud is still in developer beta so it&#8217;s likely they just haven&#8217;t been given details at the consumer support level yet. I have previously investigated the possibility of moving my iTunes purchases&#8217; &#8220;association&#8221; to the MobileMe account. Apparently that can&#8217;t be done either.
So now it seems that MobileMe users in this situation might end up having to manually switch between accounts depending on whether they want to send email or watch a movie right now, or sacrifice their existing MobileMe address and pick a new one for iCloud. This is really my main concern: I&#8217;ve used that address on so many sites I have lost track, so it&#8217;s really not feasible to chase them all down and change them. More to the point, I don&#8217;t want to and I shouldn&#8217;t have to.
My hope is that there&#8217;s a gap in my knowledge and some path will be open to merging or migration. It seems a little unfortunate that when Apple are finally starting up an online service that is free and, hopefully, reliable, they are causing more headaches for the people who paid to support its overpriced, unreliable predecessor.
@@ -0,0 +1,67 @@
---
title: How to find our flat
author: james
type: post
date: 2012-01-23T19:36:01+00:00
url: /2012/01/how-to-find-our-flat/
aktt_notify_twitter:
- no
dsq_thread_id:
- 550031315
categories:
- Flat
---
As our building is a bit of a maze, we thought it would be useful to tell you how to find the flat. There are two exciting ways to get here, but this is the easiest to follow.
First, go to Øvre Storgate 1B. You can find it <a style="color: #0000ff; text-align: left;" href="http://maps.google.no/maps?f=q&source=embed&hl=no&geocode=&q=%C3%98vre+Storgate+1B&aq=&sll=61.143235,9.09668&sspn=19.475471,35.244141&vpsrc=0&ie=UTF8&hq=&hnear=%C3%98vre+Storgate+1B,+3018+Drammen,+Buskerud&t=m&z=14&ll=59.743467,10.203002">with Google Maps.</a> Press buzzer 4A. Wait for the nice people to let you in.
[<img class="size-medium wp-image-55 alignleft" title="IMG_0045" src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0045-224x300.jpg" alt="" width="224" height="300" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0045-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0045-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][1]
You find yourself in a hallway. There is a welcoming door here. Go through the door and turn right.
<div style="clear: both;" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/bilde-224x300.jpg" alt="" title="bilde" width="224" height="300" class="alignleft size-medium wp-image-57" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/bilde-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/bilde-764x1024.jpg 764w, https://jamesmcdonald.com/wp-content/uploads/2012/01/bilde.jpg 1434w" sizes="(max-width: 224px) 100vw, 224px" />][2]
There&#8217;s a door on the right to the garage. Go through it and turn left.</p>
<div style="clear: both" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0047-224x300.jpg" alt="" title="IMG_0047" width="224" height="300" class="alignleft size-medium wp-image-56" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0047-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0047-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][3]
Cross the garage. There&#8217;s a raised area at the back with a door on the left.</p>
<div style="clear: both" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_00481-224x300.jpg" alt="" title="IMG_0048" width="224" height="300" class="alignleft size-medium wp-image-73" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_00481-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_00481-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][4]
Go through the door which leads to the bottom of the back stairwell. The complicated bit is now over!</p>
<div style="clear: both" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0049-224x300.jpg" alt="" title="IMG_0049" width="224" height="300" class="alignleft size-medium wp-image-60" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0049-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0049-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][5]
Climb up 2 flights of stairs.</p>
<div style="clear: both" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0050-224x300.jpg" alt="" title="IMG_0050" width="224" height="300" class="alignleft size-medium wp-image-61" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0050-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0050-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][6]
Oh no! Another flight of stairs. Nearly there though.</p>
<div style="clear: both" />
[<img src="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0051-224x300.jpg" alt="" title="IMG_0051" width="224" height="300" class="alignleft size-medium wp-image-62" srcset="https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0051-224x300.jpg 224w, https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0051-764x1024.jpg 764w" sizes="(max-width: 224px) 100vw, 224px" />][7]
Woo, you made it! Go through this door 😀</p>
If you&#8217;re feeling adventurous, you can try to find the other way on your own. Hint: it starts with the front stairwell. There are bad instructions on the welcoming door!
[1]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0045.jpg
[2]: https://jamesmcdonald.com/wp-content/uploads/2012/01/bilde.jpg
[3]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0047.jpg
[4]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_00481.jpg
[5]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0049.jpg
[6]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0050.jpg
[7]: https://jamesmcdonald.com/wp-content/uploads/2012/01/IMG_0051.jpg
@@ -0,0 +1,21 @@
---
title: Diablo III EU “Error 33” Fix
author: james
type: post
date: 2012-05-15T06:09:22+00:00
url: /2012/05/diablo-iii-eu-error-33-fix/
aktt_notify_twitter:
- yes
aktt_tweeted:
- 1
dsq_thread_id:
- 689917799
categories:
- Gaming
---
If you had the Diablo III beta installed, you might come across error 33 &#8220;battle.net is down for maintenance&#8221; while trying to log in. This is because there is an old registry setting pointing at the US rather than EU login server.
Take a look in HKEY\_CURRENT\_USER\Software\Blizzard Entertainment\Battle.net\D3.
I solved this by deleting the entire &#8216;Blizzard Entertainment&#8217; key. From orbit, just to be sure. Works like a charm.
@@ -0,0 +1,39 @@
---
title: Hardcoded GNOMEish composition
author: james
type: post
date: 2012-06-11T16:42:20+00:00
url: /2012/06/hardcoded-gnomeish-composition/
aktt_notify_twitter:
- yes
al2fb_facebook_link_id:
- 658281334_10151014685521335
al2fb_facebook_link_time:
- 2012-06-11T16:42:24+00:00
al2fb_facebook_link_picture:
- post=https://jamesmcdonald.com/?al2fb_image=1
aktt_tweeted:
- 1
dsq_thread_id:
- 3804739886
categories:
- Tech
---
From Ubuntu docs about the Compose key at https://help.ubuntu.com/community/ComposeKey:
> The compose key sequences used by Gnome are derived from the X compose tables of XFree86 version 4.0 with further modifications to provide a Gnome standard for all locales. They are hard coded into the program in source file gtk+-2.10.7/gtk/gtkimcontextsimple.c
Digging into the current Debian gtk+ source verifies this:
`<br />
/* This file contains the table of the compose sequences,<br />
* static const guint16 gtk_compose_seqs_compact[] = {}<br />
* IT is generated from the compose-parse.py script.<br />
*/<br />
#include "gtkimcontextsimpleseqs.h"<br />
`
So they start with the X Input Method layer which has nice unixy text config files (check out /usr/share/X11/locale) and they want to extend it with some extra sequences. What&#8217;s the best way to do that? Clearly snarf what&#8217;s already there, bolt on your own bits and hardcode the lot into your binary.
Well done, chaps.
+100
View File
@@ -0,0 +1,100 @@
---
title: Vag klokke
author: james
type: post
date: 2012-11-13T22:02:16+00:00
url: /2012/11/vag-klokke/
dsq_thread_id:
- 926740377
categories:
- Hacks
- Norsk
---
I localised my awesome fuzzyclock.py script to Norwegian language and, uh, regional time-reading standards. Behold the glory of vagklokke.py! A little terminal in the top right of my screen now proudly proclaims:
`<br />
Datoen er 2012-11-13<br />
Klokka er fem på elleve<br />
`
It was fun to work out how to handle &#8220;x på/over halv&#8221; without too many horrible range conditions. I haven&#8217;t bothered to remove stale things like &#8216;tjuefem&#8217; from the minute list, because it ain&#8217;t broke. Now you, too, can have the power of a clock that isn&#8217;t very accurate. Now with added date!
<pre class="font:droid-sans-mono lang:python decode:true " title="vagklokke.py" >#!/usr/bin/env python
# vim: set fileencoding=utf8 :
# Norwegian port of fuzzyclock
from datetime import datetime, time
from time import sleep
import sys
hours = [
'tolv',
'ett',
'to',
'tre',
'fire',
'fem',
'seks',
'sju',
'åtte',
'ni',
'ti',
'elleve',
]
minutes = [
'null',
'fem',
'ti',
'kvart',
'tjue',
'tjuefem',
'halv'
]
def fuzzyclock(time=None):
if time is None:
time = datetime.now()
hour = time.hour
minute = int(round(time.minute/5.0))
if (minute &gt;= 4 and minute &lt; 6) or minute &gt;= 9:
past='på'
else:
past='over'
if minute &gt;= 4:
hour += 1
if minute &lt; 9:
past = '%s halv' % (past)
# Adjust the minute to be in the first half of the hour
if minute &gt; 6:
minute = 12 - minute
# Handle på/over halv in the same way
if minute &gt; 3 and minute &lt; 6:
minute = 6-minute
minute = minutes[minute]
hour = hours[hour%12]
if minute=='null':
return "%s" % (hour)
if minute=='halv':
return "halv %s" % (hour)
return "%s %s %s" % (minute, past, hour)
if __name__=='__main__':
if len(sys.argv) &gt; 1 and sys.argv[1] == '-t':
for x in xrange(0,60,5):
print "Klokka er %s" % fuzzyclock(datetime(2012,01,01,9,x,0))
else:
# By default, print the time every 10 seconds
while True:
print "Datoen er %s" % datetime.now().date()
print "Klokka er %-23s" % (fuzzyclock()),
sys.stdout.flush()
sleep(10)
# Go up a line and CR, if the terminal lets you
print "\x1b[1F\r",
</pre>
@@ -0,0 +1,67 @@
---
title: Import Things tasks into Apples Reminders
author: james
type: post
date: 2012-12-08T13:36:46+00:00
url: /2012/12/import-things-tasks-into-apples-reminders/
dsq_thread_id:
- 964365161
categories:
- Apple
- Hacks
---
OK, so I was making a list of things to do today, but then I decided that having created them in Things, I wanted to move them to Apple&#8217;s Reminders. Don&#8217;t ask &#8211; I&#8217;m a task list fetishist.
A neat trick you can do with Cultured Code&#8217;s <a href="http://culturedcode.com/things/" target="_blank">Things</a> is to select a bunch of tasks and drag them to a text editor, which will create one line per task with any note appended in brackets. Looks sort of like this:
<pre class="lang:default highlight:0 decode:true " title="Things export" >- Make lists of things
- Procrastinate (Try making scripts to manage lists of things)
</pre>
This is all very well, but there&#8217;s no simple way to get that list into Reminders without copying and pasting the relevant bits individually. That sounded boring, so instead I learned enough AppleScript to do it automatically. It probably took more time, but it was definitely more amusing. Anyway, it was that or complete the bunch of tasks I&#8217;d just written down.
Here&#8217;s the AppleScript code to accomplish this feat.
<pre class="lang:applescript decode:true " title="Reminders Importer" >-- Reminders Importer
-- James McDonald &lt;james@jamesmcdonald.com&gt;
-- Imports a text file into Reminders as one task per line.
-- Creates a task list called "Import". Strips off " -" at the start and puts bracketed text into the body (note) of the task. This is the format you get by dragging from Things to a text editor.
tell application "Reminders"
if not (list "Import" exists) then
make list with properties {name:"Import"}
else
tell list "Import" to delete reminders
end if
end tell
tell application "Reminders"
repeat with l in paragraphs of (read file "Users:james:Documents:tasks.txt")
if length of l is not 0 then
if l starts with "- " then
set l to characters 3 through end of l as text
end if
if l contains "(" then
set AppleScript's text item delimiters to "("
set b to text item 2 of l
set l to text item 1 of l
set AppleScript's text item delimiters to ")"
set b to text item 1 of b
set AppleScript's text item delimiters to ""
else
set b to "" as text
end if
tell list "Import"
make reminder with properties {name:l, body:b}
end tell
end if
end repeat
end tell
</pre>
Yes, I know. AppleScript is weird.
So, now that I&#8217;ve written the blog post about the script to migrate to one task manager from another the list of tasks I made of things to do this morning, it&#8217;s this afternoon. Yay!
@@ -0,0 +1,18 @@
---
title: Useful Haskell Learnings
author: james
type: post
date: 2013-08-03T07:59:36+00:00
url: /2013/08/useful-haskell-learnings/
dsq_thread_id:
- 3784870289
categories:
- Hacks
- Uncategorized
---
<pre class="lang:haskell decode:true " >isSexyPerson x = if x == "Oda"
then x ++ " is indeed sexy!"
else "The sexiness of " ++ x ++ " is unknown."</pre>
Most useful.
@@ -0,0 +1,52 @@
---
title: Function for bash or zsh to generate SSL requests and certificates
author: james
type: post
date: 2015-07-03T14:19:10+00:00
url: /2015/07/function-for-bash-or-zsh-to-generate-ssl-requests/
categories:
- Uncategorized
---
Rather than memorising annoying OpenSSL options, stick this in your profile, edit the &#8216;SUBJ&#8217; bit, and you&#8217;ll be generating keys with ease.
<pre class="lang:zsh decode:true " title="SSL certificate generator" ># Generate an SSL key and a signing request or self-signed certificate
sslcert() {
cn=$1
# The prefix for the certificate's subject, eg
# SUBJ="/C=GB/ST=Edinburgh/L=Edinburgh/O=Widget Co"
SUBJ="&lt;&lt;&lt; SET THIS BIT &gt;&gt;&gt;"
if [ -z "$cn" -o "$cn" = "-h" ]; then
echo "usage: $0 &lt;common name&gt; [csr|crt]" &gt;&2
echo " csr - generate a certificate signing request (default)" &gt;&2
echo " crt - generate a self-signed certificate" &gt;&2
return 1
fi
type=${2:-csr}
name=$(echo $cn | sed -e 's/^\*\./star./')
if [ -r $name ]; then
echo "$0: $name already exists"
return 1
fi
mkdir $name
if [ $? -ne 0 ]; then
echo "$0: can't mkdir $name" &gt;&2
return 1
fi
cd $name
openssl genrsa -out ${name}.key 4096
case $type in
csr)
openssl req -new -key ${name}.key -out ${name}.csr -sha256 -subj "${SUBJ}/CN=${cn}"
;;
crt)
openssl req -new -x509 -days 3650 -key ${name}.key -out ${name}.crt -sha256 -subj "${SUBJ}/CN=${cn}"
;;
esac
cd ..
}
</pre>
@@ -0,0 +1,106 @@
---
title: Git post-receive hook for Puppet control repo updates
author: james
type: post
date: 2017-04-05T19:24:28+00:00
url: /2017/04/git-post-receive-hook-for-puppet-control-repo-updates/
snapFB:
- 's:203:"a:1:{i:0;a:4:{s:8:"isPosted";s:1:"1";s:4:"pgID";s:27:"658281334_10154963966061335";s:7:"postURL";s:57:"http://www.facebook.com/658281334/posts/10154963966061335";s:5:"pDate";s:19:"2017-04-05 19:34:18";}}";'
snapTW:
- 's:189:"a:1:{i:0;a:4:{s:8:"isPosted";s:1:"1";s:4:"pgID";s:18:"849709206836056068";s:7:"postURL";s:52:"https://twitter.com/0xfce2/status/849709206836056068";s:5:"pDate";s:19:"2017-04-05 19:43:56";}}";'
categories:
- Hacks
- Tech
---
I made a fairly simple post-receive hook setup to automatically update my [Puppet][1] master when I push changes to my control repo. I keep the repo in gitolite, so I wanted to use a regular git hook rather than web hook magic (or even magicer Puppet Enterprise Code Manager magic).
My control repo itself is based on [the puppetlabs control-repo on github][2]. Essentially the idea is that every branch in the repo becomes a Puppet environment on your master, complete with automatically updated modules based on a Puppetfile. The [r10k][3] tool takes care of the heavy lifting here, and its documentation explains how it works in some detail.
But we don&#8217;t have the patience for that! First, install r10k on your Puppet master and configure it to be able to yank your control repo in `/etc/puppetlabs/r10k/r10k.yaml`, something like this:
<pre class="lang:yaml decode:true " title="/etc/puppetlabs/r10k/r10k.yaml" >:cachedir: '/var/cache/r10k'
:sources:
:myrepo:
remote: 'gitolite3@git.example.com:puppet'
basedir: '/etc/puppetlabs/code/environments'</pre>
Make sure you have SSH keys relationships set up so that you can pull the repo. Running `r10k deploy environment --verbose info` should let you see what&#8217;s going on. Once it works, continue on.
Create an SSH key on your git server as the user that runs git. In my case on Debian, that user is `gitolite3`, but just wherever you have your repo running.
Copy the public key and install it in your puppet master&#8217;s `/root/.ssh/authorized_keys`:
<pre class="lang:default decode:true " title="authorized_keys" >command="/usr/local/sbin/puppet-update.sh" ssh-ed25519 AAASOMEKEYMATERIAL gitolite3@git.example.com</pre>
What&#8217;s this `puppet-update.sh`, I hear you cry? I&#8217;m glad you asked:
<pre class="lang:sh decode:true " title="/usr/local/sbin/puppet-update.sh" >#!/bin/bash
/usr/local/bin/r10k deploy environment $SSH_ORIGINAL_COMMAND</pre>
Pretty straightforward. Obviously you&#8217;ll want to point to wherever you have r10k installed, and make sure the script is executable. This setup takes whatever command you try to run over ssh with this key and appends it to `/usr/local/bin/r10k deploy environment`. The security conscious may want to do some other sanity checks too. I did say it was simple!
The meat of the matter is the post-receive hook itself. This should go on your git server, inside the puppet control repo&#8217;s hooks directory. In my case this is `~gitolite3/repositories/puppet.git/hooks/post-receive`. It, too, should be executable.
<pre class="lang:sh decode:true " title="post-receive hook" >#!/bin/bash
# post-receive hook to trigger r10k over ssh on updates to puppet control repo
# Set SSHTARGET in ~/.config/puppet-update to eg:
# root@puppet.example.com
# Caveat: If you push a branch deletion and an updated Puppetfile in the same
# push command, the updates to the Puppetfile will not be deployed. You'll have
# to run manually or make another change to the Puppetfile.
CONFIGFILE=~/.config/puppet-update
if [ ! -r $CONFIGFILE ]; then
echo "$CONFIGFILE doesn't exist, not updating" &gt;&2
exit 1
fi
source $CONFIGFILE
update() {
ssh $SSHTARGET -- --verbose info $@
if [ $? -ne 0 ]; then
echo "WARNING: Update had errors: puppet may not be completely updated" &gt;&2
exit 1
fi
}
while read oldref newref refname
do
refname=$(basename $refname)
updateargs=
if echo ${newref} | egrep -vq '[^0]'
then
echo "Branch $refname is being deleted, updating all to trigger cleanup"
update
break
fi
# If this isn't a new branch and the Puppetfile has been changed, add --puppetfile
# The new branch check is needed because diff won't work in that case; new
# environments get Puppetfile deployed by r10k automatically (could also use ||)
if echo ${oldref} | egrep -q '[^0]' && \
git diff --name-only ${oldref}..${newref} | grep -q Puppetfile
then
updateargs="--puppetfile"
fi
update ${refname} ${updateargs}
done</pre>
Like the comment says, you&#8217;ll want to make a `~/.config/puppet-update` to tell it where your Puppet master lives.
<pre class="lang:sh decode:true " title="post-receive hook" >SSHTARGET=root@puppet.example.com</pre>
Now, make a commit to one of your branches and push it. You should see r10k working away in the `git push` output. Yay! Pushing any changes to any branches will update those environments. If you add or delete branches, it will deploy new environments or clean up. In a handy bit of time saving, it will only deploy the modules from the Puppetfile if the Puppetfile has actually been changed.
This works rather nicely for me, but I&#8217;d be interested to hear how it works for other people, or what changes you made.
[1]: https://puppet.com/
[2]: https://github.com/puppetlabs/control-repo
[3]: https://github.com/puppetlabs/r10k
@@ -0,0 +1,33 @@
---
title: Docker swarm monitoring
author: james
type: post
date: 2017-10-03T08:09:04+00:00
url: /2017/10/swarm-monitoring/
snap_isAutoPosted:
- 1
snapEdIT:
- 1
snapFB:
- 's:382:"a:1:{i:0;a:11:{s:2:"do";s:1:"1";s:9:"msgFormat";s:22:"New blog post: %TITLE%";s:8:"postType";s:1:"A";s:9:"isAutoImg";s:1:"A";s:8:"imgToUse";s:0:"";s:9:"isAutoURL";s:1:"A";s:8:"urlToUse";s:0:"";s:8:"isPosted";s:1:"1";s:4:"pgID";s:27:"658281334_10155506578631335";s:7:"postURL";s:57:"http://www.facebook.com/658281334/posts/10155506578631335";s:5:"pDate";s:19:"2017-10-03 08:15:31";}}";'
snapTW:
- 's:376:"a:1:{i:0;a:11:{s:2:"do";s:1:"1";s:9:"msgFormat";s:30:"New blog post: %TITLE% - %URL%";s:8:"attchImg";s:1:"0";s:9:"isAutoImg";s:1:"A";s:8:"imgToUse";s:0:"";s:9:"isAutoURL";s:1:"A";s:8:"urlToUse";s:0:"";s:8:"isPosted";s:1:"1";s:4:"pgID";s:18:"915126845124816897";s:7:"postURL";s:52:"https://twitter.com/0xfce2/status/915126845124816897";s:5:"pDate";s:19:"2017-10-03 08:10:16";}}";'
categories:
- Tech
---
I&#8217;ve seen a bunch of posts lately about how to set up Docker swarm monitoring with tools like cAdvisor and node_exporter which advise running them like this:
`docker service create --mode global -p 9100:9100 ...`
That will indeed run one container on each swarm node, but it has a subtle problem. When you connect to host:9100, the ingress network routing will connect you to a _random_ instance each connection (for swarm routing values of random). You will indeed get some metrics returned, but they will be for whichever host you happened to be routed to this time.
You can demonstrate this problem quite simply with something like:
`docker service create --name hello --mode global -p 8080:80 dockercloud/hello-world`
Then just reload the page and you&#8217;ll see that the hostname (container ID) changes sometimes. You might see it more readily with curl than a browser.
A simple solution is to just run these containers on each node as normal docker containers outside swarm management. In the setup I&#8217;m working on just now, we used the same Puppet automation that provisions the swarm to start the containers.
`docker run -d -p 9100:9100 ...`
+14
View File
@@ -0,0 +1,14 @@
---
title: Stuff
author: james
type: page
date: 2010-08-22T15:31:32+00:00
dsq_thread_id:
- 438231807
---
Things you can grab.
My [current CV][1], or at least the most recently updated version thereof.
[1]: https://jamesmcdonald.com/wp-content/uploads/2010/08/Curriculum-Vitae-James-McDonald.pdf
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 KiB