• Instagram

    I’ve always liked Instagram for taking and sharing photos with quite a few now up on my profile. A couple of weeks back I got to wondering how I could get them into this blog. With Hugo this is pretty simple, it has an inbuilt shortcode which does all the work for you if you pass it in a photo ID.

      {{< instagram BuTYsdHAx_W >}}
    

    Is all you need in a post and the shortcode will do the rest (see an example here).

    Old Posts

    That all seems pretty simple, so its just a job of pulling all my old posts from Instagram and making new posts for them in the right places in my timeline of blog posts. I turned to Python for this and the InstagramAPI package, that made it pretty trivial to pull out the caption, date and photo id for each of my old posts, then I used pystash to render a little template of each post with all the fields and save it into the tree of posts.

    The code is pretty hacky, but if anybody wants a copy please drop me a line (my email is in the footer).

    New posts

    While that took care of the old posts, I wondered about how to handle new posts. I’m still now 100% on this, but I’ve rigged up a ifttt ‘app’ which posts to a web hook on my server whenever a new instagram post is made. That then tries to render the same template I used for the old posts and git commit and publish the site. We’ll see how that goes, there are too many moving parts in that for my liking, but we’ll see :)

    Archive

    For now, you can see all my old Instagram posts by checking out the category.


  • Broke the Reedy Esc

    I’ve not written about the Team Associated B64s we now own yet, which I’ll get round to at some point but suffice to say the kids have one and I have my own. When I received mine, the ESC case was broken with signs of it being cyno’ed back together at least once. I did the same again hoping it would last for a good while. I’ve since heard anecdotal evidence that these Reedy ESC’s are known to have weak cases.

    Well… Last weekend we went racing with the guys from my flying club. Who it turns out mostly run 18 scale cars and, unlike the car club we also race with, were mostly bashing around the track. I got a few good laps in, the Ballistic Buggy Spike tyres giving good grip on our astro turf runway.

    And then the inevitable happened, I flipped the car, there was no marshalling so the car sat stranded upside down, then 💥 I got hit hard in the left hand side by a big truggy going at speed. Immediately I noticed that applying throttle had no effect so I feared the wost.

    Back at home it was clear the ESC case had broken again but this time when I lifed the PCB out of the case one of the little yellow transistors (maybe? I’m no electronics expert) was sitting in the bottom of the case. Oh well ¯\(ツ)/¯ you live and learn.

     

    Asking some of the members of our car racing club, the suggestion was a Hobbywing Quicrun 10BL120 Sensored ESC would be a good replacement, so I placed an order with Modelsport and got one sent.

    Last night I got it installed and soldered to the motor, it all seems fine we are back and ready for the next outing.


  • New Compressor

    For various reasons, I’ve been contemplating a new compressor for a while now. The current one is very small, mainly designed for small airbrushes and the like, while fine for its intended purpose, painting larger areas with a small airbrush was becoming a bit of a chore. What I really wanted was a larger paint gun, which meant a bigger compressor. Of course once a decent sized compressor was installed it would find other uses, like cleaning the cars or driving small tools around the workshop.

    I’ve seen the Lidl one a few times now, but have never quite felt up to taking the plunge, it is quite big and my shed isn’t, but this weekend while having a general tidy up and moving a few things into the loft, it dawned on me that a space had opened up where I thought it would fit. Hmm, thats one less reason to not do it then!

    One impromtu trip to Lidl later and I had one in the boot, along with a cleaning gun set (including a handy tyre inflator) and a nice wall mountable reel hose. The plan is to mount the reel on the inside of the shed near the door which means its easily long enough to reach outside for cleaning things, or the bench for spraying.

    I need to get a moisture/oil trap at some point and wire a few more sockets in the shed but its all looking good. Long term I have a vague plan of moving it into the second shed and running a air hose through the small gap between them into the main shed, that’ll certainly move the source of noise away from where I’ll be working. But for now I can put up with the noise. Running some structured air hose around the shed presenting a quick release socket near the bench might also be a nice idea, something to ponder later :)


  • Updates

    I’ve made a few changes to the models page, specifically breaking Aircraft, Boats, Cars and Helicopters out into their own pages.

    Also made a post and a page about the VMC Tiger Moth.

    Made a few old posts (so they fit in correctly with the timeline) about the Desert Fox here and here.

    Made a few holding pages about some recent cars here, here, here and here.

    And finally, I’ve updated the Dominus page with the recent news about the car.


  • Vmc Tiger Moth

    I’ve made a page for the VMC Tiger Moth here, its a lovely little kit, we are hoping it will fly as well as it went together!


  • Edit Links in Hugo

    While going through some old posts, tidying things up a bit, I have missed the Wordpress Edit link on pages and posts. This got me to thinking, could I emulate this in Hugo?

    Turn out, yes you can and fairly easily.

    First off, I edited my themes’ layout for a single post, which for me was single-content.html, I then figured out where I’d like the edit link and added this bit of template code:

        {{ if .Site.IsServer }}
            {{ partial "edit" . }}
        {{ end }}
    

    The if around the partial means only include this if we are running hugo in development mode.

    The next task was to make the edit.html partial:

    {{ if .Site.Params.baseDir }}
    <a href="vscode://file{{ .Site.Params.baseDir }}/content/{{.File.Path}}">Edit</a>
    {{ end }}
    

    I defined Params.baseDir in my sites’ config.yaml, which means I won’t have to alter the theme if I alter where I’ve got the git repo checked out. This needs to be the full path to the root of your site (i.e. the path to the dir with config.yaml in it.).

    The vscode://file is specific to Microsoft Visual Studio Code, which is my preferred editor, that will likely need adjusting if you use something else.

    Footnote

    I tried to make the template read the editor specific bit of the url from the config.yaml, but whenever I did that the dev mode got in the way and mangled the url from:

    vscode://file

    to

    http://localhost:1313/.....

    Which isn’t helpful. I’ve not figured out a way of fixing this as yet, so that portion of the edit link is hardcoded into the template.


  • Moved Away From Wordpress

    After many years of using Wordpress to host this site I have grown tired of its resource consumption and the constant need to keep it updated. When it came to put my CV online (here) I tried out Jekyll which worked out pretty well, I write a lot of Markdown for work, and while it has its faults I’m pretty happy with it over the alternatives.

    False Starts

    This lead to thoughts of moving this site to Jekyll. After a bit of faffing around I ended up with a fairly complete export from wordpress - although weirdly and for no reason I could find about 10 pages failed to export. I found a nice enough theme (Centrarium) which suited my needs and it all looked ok, sure there was plenty of tidying up to go, but on the whole it was ok.

    The biggest annoyance were the build times, on my 2015 MacBook Pro they ran to anywhere between 5 and 7 minutes! :(

    The other annoyance was I couldn’t find any nice photo gallery plugin, I’ve got a whole bunch of photos (mostly of models) on this site and I wanted to keep them. I toyed with the idea of moving them all to Flickr however with the recent SmugMug aquisition I didn’t want to sink a whole bunch of time into moving everything over, only for SmugMug to change the terms, or make it paid for only. I should point out I think SmugMug is a great home for Flickr, and I hope they reinvigorate it after many years of neglect under the hands of Yahoo. I’ll keep an eye on how things are panning out over there and maybe move my imagery over at some point in the future.

    While searching for a gallery plugin, I found this plugin for Hugo, it looked pretty good and did what I wanted really simply. The problem was I was using Jekyll and this was for the fairly new competitor on the static content scene, namely Hugo.

    Second attempt

    So, maybe I should look into Hugo. After a bit of fooling around I managed to get the Jekyll export from Wordpress up in Hugo. The first thing I noticed was rebuild times were quick, like really quick. It was down from the 5+ minutes with Jekyll, to between 5 and 10 seconds:

    % hugo
    
                       |  EN
    +------------------+------+
      Pages            | 1347
      Paginator pages  |  277
      Non-page files   |    0
      Static files     | 1991
      Processed images |    0
      Aliases          |  346
      Sitemaps         |    1
      Cleaned          |    0
    
    Total in 5587 ms
    

    So that sort of made up my mind, it was far quicker, there was a nice gallery plugin and being in Go it made things easier from a dependancy point of view. The only problem was I liked Centrarium and couldn’t find a Hugo theme similar. Reading into theme development a bit I started to realise I could probably port the theme to Hugo in a couple of hours. Turns out that was about how long it took. I didn’t port 100% of the functionality in the original, just the bits I use. If anybody wants a copy I’d be more than happy to put it on Github and attempt to port the rest of the features.

    So this is the first post on the new blog, its all in git (apart from the photos) and I’m much happier with it.

    At the same time as migrating I also took the oportunity to move it all to an S3 bucket, fronted by CloudFront so I can have SSL and my own domain. I’m not sure how the cost of that will work out, but I’ll keep an eye on it. If it isn’t too much it’ll stay like that, otherwise it’ll be back to Nginx on my virtual server.

    Comments

    The only thing feature wise, missing from my Hugo rig is comments, I never got many comments anyway so I’ve deprioritised them somewhat, maybe one day I’ll get round to plugging in Disqus or something.

    Until then, my email address is in the footer, please feel free to email me if you have any questions or want to chat about something.

    Work in Progress

    The biggest breaking change from the migration was the photos. I’m working my way through fixing them, starting with the top 50 posts, I’m about a quarter of the way through by now.


  • Custom LUA HAProxy HealthCheck

    I’ve recently been tasked with using HAProxy to front a LDAP server in AWS to allow SSL access to the LDAP backend. This was essentially following this guide from AWS. It is a great shame that AWS don’t offer SSL termination in the Directory Service itself, but the HAProxy/ELB solution isn’t too complex and does work well.

    While testing out some failure scenarios I did however spot an issue which I didn’t like.

    There exists a situation whereby if (for whatever unlikely reason) an HAProxy instance cannot reach any of its downstream LDAP backends the ELB health check of the HAProxy instance will still pass and thus the instance will still be considered healthy. The ELB will still send traffic to the instance, but then things go south because the instance cannot see any LDAP backends and the request fails.

    I spent a bit of time googling for a solution and didn’t find anything which solved this, what we really want is for HAProxy to stop listening on the TCP port of the front end when all the backends are unavailable, however that isn’t an option.

    The solution I came up with was to use a custom HTTP health check endpoint, which runs a simple LUA script inside HAProxy. This uses the new LUA support, added around to HAProxy around version 1.6.1. Not all the binaries I found had it compiled in as an option so we ended up using the official Docker container.

    The way this works is you define a custom HTTP front end in your haproxy.cfg like this:

    global
        # Lots removed for brevity!
        lua-load /usr/local/etc/haproxy/haproxy-smart-tcp-healthcheck.lua

    Custom HTTP Health check endpoint

    frontend status-lua bind *:8000 mode http http-request use-service lua.status_service

    LDAP frontend

    frontend ldap_front bind *:1389 description LDAP Service option socket-stats option tcpka timeout client 5s default_backend aws-ldap

    Downstream AWS LDAP backends

    backend aws-ldap balance roundrobin server directory1 10.0.0.1:8081 check port 8081 server directory2 10.0.0.2:8081 check port 8081 option tcp-check

    
    This now runs the LUA service `tcp_healthcheck` defined in the file `haproxy-smart-tcp-healthcheck.lua` whenever a request is made for `/` on port `8000`.
    
    The script itself turned out to be pretty simple, once I got my head around some LUA quirks!
    
    All it does, is query the HAProxy state for all the servers associated with a given backend (named `aws-ldap` on line 15). Then we loop that list of backends, and if _any_ of them are `UP` we return a 200 status with the message `Found some servers up`, if they are all down we return a 500 status with the message `Found NO servers up`. 
    
    <pre class="wp-block-code"><code>-- This service checks all the servers in the named backend (see the 
    -- backend_name var). If _any_ of them are up, it returns 200 OK. If 
    -- they are all down it returns a 500 FAILED.
    -- 
    -- This is intended to be used as a HTTP health check from an upstream
    -- load balancer, without this check the most intelligent health check 
    -- that could be performed is a simple TCP check on the HAProxy frontend.
    -- This would not fail in the event that HAProxy cannot see *any* of its
    -- downstream servers
    
    core.register_service("tcp_healthcheck", "http", function (applet)
    
        -- Harcoded backend here, if anybody knows how to pass vars into Lua
        -- from the haproxy.cfg please shout!
        local backend_name = "aws-ldap"
        local r = ""
    
        backend = core.proxies[backend_name]
        servers = backend["servers"]
    
        local any_up = false
    
        for k, v in pairs(servers) do
    
            status = v.get_stats(v)["status"]
    
            -- If _any_ of the servers are up, we will return OK
            if (status == "UP") then
                any_up = true
            end
    
        end
    
        if ( any_up ) then
            core.log(core.debug, "Found some servers up")
            applet:set_status(200)
            r = "OK"
        else
            core.log(core.debug, "Found NO servers up")
            applet:set_status(500)
            r = "FAILED"
        end
    
        applet:start_response()
        applet:send(r)
    end)</code>
    

    With this all installed in the HAProxy instance it was a simple matter of configuring the ELB in AWS to use a HTTP health check for the path / on port 8000.

    The AWS Console config for the ELB Health check looks like this:

    And you can see the Listeners configuration is still in TCP passthrough mode, with TLS termination performed at the ELB.

    The one optimisation I’d like to make to this but have not yet found a solution for, is to pass the name of the backend to query through to the script as an argument. Currently it is hardcoded into the script which would mean duplicating the script if you need more than one of these custom health checks, that would be a pain. However in our use-case the HAProxy is only fronting a single LDAP directory so we can live with this single hardcoded piece fo configuration!


  • Importing non GoPro videos into GoPro Quik

    I’ve been using our GoPro quite a bit this summer which the kids have really enjoyed. I also recently got myself a DJI Spark, which is also great fun.

    However I really wanted to be able to import the Spark videos into the new GoPro Quik desktop app because it makes short work of turning a load of clips into short snappy videos.  Sadly it only offers to import videos originating from the GoPro.

    I figured there are only so many ways the software can check to determine if a given file was made by a GoPro or not, so I got to poking around and after about half an hour I found a solution which works on all my current DJI video files.

    If you run this ffmpeg command on any a DJI video (although it probably works for iPhone or other videos), it adds the magic field that Quik looks for, and then it happily imports the video.

    ffmpeg -i dji-video.mp4 
    -map_metadata
    -1
    -codec copy
    -metadata:s handler=“GoPro AVC encoder”
    gopro-video.mp4
    ```

    I know almost nothing about the millions of options ffmpeg accepts, so this is mostly copy and paste from various google searches, but it works fine from what I can tell!


  • Still alive!

    I’m still here, and so is a very much neglected blog. I will try and make amends in the near future!