• Monitoring home internet speeds with Smokeping and Speed Test
    July 9, 2019 - 1 minute read -
    smokeping speedtest docker

    I’ve been monitoring my home internet’s uptime using Smokeping docker container for awhile now. But after finally switching from ADSL to a 100Mbps connection I thought it would be a good time to start also monitoring internet speeds.

    Turns out there is an existing plugin, smokeping-speedtest for Smokeping which does the job.

    For easy setup, I created a docker image to combine the plugin and it’s dependencies and with linuxserver’s docker-smokeping image as a base.

    For configuration, I just followed the instructions and added the follwing to the Probes file.

    + speedtest
    binary = /usr/local/bin/speedtest-cli
    timeout = 300
    step = 3600
    offset = random
    pings = 3
    
    ++ speedtest-download
    measurement = download
    
    ++ speedtest-upload
    measurement = upload
    

    I also added a new section to my Targets file to perform speed tests against a local ISP.

    + SpeedTest
    
    menu = Speed Tests
    title = Speed Tests
    
    ++ download
    menu = Download
    title = Download
    probe = speedtest-download
    server = 2173
    measurement = download
    host = internode.on.net
    
    ++ upload
    menu = Upload
    title = Upload
    probe = speedtest-upload
    server = 2173
    measurement = upload
    host = internode.on.net
    

    The complete Dockerfile is on github and the image on Docker Hub.

  • Kubernetes secrets to a dotenv (.env) file
    April 24, 2019 - 1 minute read -
    kubernetes dotenv base64 bash

    For dumb reasons, I recently needed to be able to quickly setup a local environment with secrets loaded from a kubernetes instance. After manually copying/pasting/decoding a few times, I decided to write a quick script to do it for me.

    The following script grabs a kubernetes secrets file (${SECRET}) from kube, decodes each key/value pair and then appends them to a .env file.

    Prerequisites: jq, kubectl

    # base64 decode secrets file ${SECRET} and add each key=value pair to .env file
    for s in $(kubectl get secret ${SECRET} -o json | jq -r ".data" | jq -r "to_entries|map(\"\(.key)=\(.value | @base64d)\")|.[]" ); do
        echo $s >> .env
    done

    The above script invokes jq twice, which was a quick and dirty workaround to get it working under alpine’s ash, in addition to bash.

  • Typescript migration headaches
    June 11, 2018 - 2 minute read -
    node.js typescript javaScript

    I had the pleasure of migrating an existing codebase from straight nodejs to Typescript. Here’s a few of the headaches/gotchas I ran into.

    Extending from Error breaks things

    The following custom error class resulted in an error complaining about instanceof:

    class ApiError extends Error {
        constructor(message: string) {
          this.name = 'ApiError';
        }
    }

    Microsoft explain the issue and point out a simple fix in their Breaking Changes list

    Mocha not picking up sub directories with –recursive

    With a test structure like:

    test/controllers/book.spec.ts
    test/middleware/log.spec.ts
    test/app.spec.ts

    running mocha --recursive test/**/*.spec.ts will only see mocha pickup tests in app.spec.ts, despite the --recursive option being set.

    As ScottFreeCode points out the solution is to quote the glob to avoid having the shell interpret the **.

    Eg. mocha --recursive "test/**/*.spec.ts"

    Typescript compiler will not touch non-ts/js files

    There’s no built in mechanism to have the compiler copy non-typescript/javascript files, such as .json schemas to the dist directory. This instead needs to be done separately.

    With only a few files to copy I ended up creating a simple bin script to copy the files before running tsc.

    Sequelize unexpected token in map file error

    A fairly common pattern to follow when using Sequelize is to load all model files defined in a particular directory, with code like:

    fs.readdirSync('models/').forEach((filename) => {
      ... load model
    	models[model] = model;
    });

    This works fine with javascript, but will cause a runtime Unexpected token with Typescript when map file generation is turned on. Any code loading files should be modified to explicitly check the extension. In this case, we want to exclude any *.map.js files from being loaded.

    More details can be found on this TypeScript github issue.

    Cannot redeclare block-scoped variable

    With a codebase split up amongst a number of files, Typescript instantly complained about Cannot redeclare block-scoped variable whenever attempting to load a local file.

    The solution is to ensure each file exported every function/variable used in other files.

    export function doSomething() {
      ...
    }
    
    export function doSomethingElse() {
      ...
    }
    module.exports = { doSomething, doSomethingElse};
  • Older posts