Greetings Programs!
I've been working on a command line tool named convey for quite some time now and it needs to return an exit code. In most programming languages this is pretty straight forward... You just return the exit code from your main function. But in golang it's not quite that simple.
In golang os.Exit returns immediately and doesn't call any deferred function calls. This makes it impossible to cleanup with a deferred function. As many gophers will tell you, deferred cleanup functions are amazing, so this is quite the bummer.
I've experimented with this for a while, but never got it fully sorted out until tonight. My previous attempts swallowed panics and just weren't very good. But today I built a proof of concept, tested it, and documented the crap out of it. And well, it works great! No longer will I find myself scratching my head on why I have an exit code of 0 but the program aborted too early.
This works by renaming your main function to gomain and making it return an int. Then we write a main function that does all of the magic including handling panics.
You can find the fully documented source code (released to the public domain) at bitbucket.org/rw_grim/gomain.
Happy Hacking!
Saturday, December 30, 2017
Friday, February 3, 2017
docker-machine and qnap container station
So earlier this week woot.com had a QNAP TS-453mini for an awesome price. I've been in the market for a new NAS to replace my self built one from more than half a decade ago. One of the selling points that caused me to purchase it was the container station. The container station lets your run Docker containers directly on the NAS. If you've talked to me in the past 3 years, I've probably told you how I've drank all of the container kool-aid. So of course this alone is reason enough for me to look into it.
The NAS came today and I put some old drives in it right now as I'm waiting on my secondary drive order (to try and make sure I hit different production runs). So I started tinkering with the container station when I remembered about docker machine.
Docker machine is used to control multiple docker engines. Typically it is used to create a virtual machine, or provision one on a cloud provider. However, there is also a poorly documented driver named "none". The none driver is just straight docker api over a tcp socket. The container station exposes this and provides the certificates for authentication.
To get the certificates, go to the Preferences page in the Container Station. From there select the Docker Certificate tab. This page has some instructions on how to install the certs, but that'll only work if you only plan on connecting to the NAS. So instead just hit the download button.
Now that we have the certs we can create the machine in docker-machine. Of course replacing %nas ip% with the IP address or hostname of the NAS and %name% with whatever you want to refer to it as in docker machine. In the following examples I've named the machine nas.
If we try to use this as is right now we'll get the following error.
To fix this we need to add and configure the certs that we downloaded earlier into the docker machine config. To do that we need to cd into the directory that holds the config. Once there, we need to extract cert.zip into that directory.
Now we just need to modify the AuthOptions section to point to the correct files. It should look like the following:
Now we can enable the host in docker machine and run docker ps on it:
On no!! What happened?!? Well docker is usually pretty strict about having the same version of the client talk to the same version of the server. Luckily we can work around this.
And it works! Now we can treat the nas as any old docker host and let docker-machine manage it for us.
The NAS came today and I put some old drives in it right now as I'm waiting on my secondary drive order (to try and make sure I hit different production runs). So I started tinkering with the container station when I remembered about docker machine.
Docker machine is used to control multiple docker engines. Typically it is used to create a virtual machine, or provision one on a cloud provider. However, there is also a poorly documented driver named "none". The none driver is just straight docker api over a tcp socket. The container station exposes this and provides the certificates for authentication.
To get the certificates, go to the Preferences page in the Container Station. From there select the Docker Certificate tab. This page has some instructions on how to install the certs, but that'll only work if you only plan on connecting to the NAS. So instead just hit the download button.
Now that we have the certs we can create the machine in docker-machine. Of course replacing %nas ip% with the IP address or hostname of the NAS and %name% with whatever you want to refer to it as in docker machine. In the following examples I've named the machine nas.
docker-machine create --driver=none --url=tcp://%nas ip%:2376 %name%
If we try to use this as is right now we'll get the following error.
$ docker-machine ls --filter name=nas
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
nas - none Running tcp://nas:2376 Unknown Unable to query docker version: Get https://nas:2376/v1.15/version: x509: certificate signed by unknown authority
To fix this we need to add and configure the certs that we downloaded earlier into the docker machine config. To do that we need to cd into the directory that holds the config. Once there, we need to extract cert.zip into that directory.
$ cd ~/.docker/machine/machines/nas
$ unzip ~/Downloads/cert.zip
Archive: /home/grim/Downloads/cert.zip
extracting: ca.pem
extracting: cert.pem
extracting: key.pem
Now we just need to modify the AuthOptions section to point to the correct files. It should look like the following:
"AuthOptions": {
"CertDir": "/home/grim/.docker/machine/machines/nas/",
"CaCertPath": "/home/grim/.docker/machine/machines/nas/ca.pem",
"CaPrivateKeyPath": "/home/grim/.docker/machine/machines/nas/key.pem",
"CaCertRemotePath": "",
"ServerCertPath": "/home/grim/.docker/machine/machines/nas/cert.pem",
"ServerKeyPath": "/home/grim/.docker/machine/machines/nas/key.pem",
"ClientKeyPath": "/home/grim/.docker/machine/machines/nas/key.pem",
"ServerCertRemotePath": "",
"ServerKeyRemotePath": "",
"ClientCertPath": "/home/grim/.docker/machine/machines/nas/cert.pem",
"ServerCertSANs": [],
"StorePath": "/home/grim/.docker/machine/machines/nas"
}
Now we can enable the host in docker machine and run docker ps on it:
$ eval $(docker-machine env nas)
$ docker ps
Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.23)
On no!! What happened?!? Well docker is usually pretty strict about having the same version of the client talk to the same version of the server. Luckily we can work around this.
$ export DOCKER_API_VERSION=1.23
$ eval $(docker-machine env nas)
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
And it works! Now we can treat the nas as any old docker host and let docker-machine manage it for us.
Subscribe to:
Posts (Atom)