Saturday, January 6, 2018

Marlin Firmware and Jenkins

I have a 3d printer that uses the Marlin firmware. It’s an Alunar M508 (Prusa I3 Clone) and I maintain a build of Marlin for it that is tailored for that printer. Recently, I thought it would be fun to set up a Jenkins build agent that can build Arduino code. The agent is a docker image that is based off a base sshd image. Currently these are not available publicly, but I may change that in the future.

The base image is just a standard sshd server so so Jenkins can communicate to the agent.

The arduino agent installs arduino 1.8.5, and a few things like pip, gcc, etc. I also have some scripts that I put together that allow the build pipeline install Arduino Boards and Libraries. Like the board and library managers in the UI.

board-manager --name='Arduino AVR Boards' --version='latest' --packager='arduino'

That command will install the latest AVR boards and all the required dependencies. Additionally, to install a libarary, it would look like this:

library-manager --name='LiquidCrystal' --version='latest';

After I got all that setup and able to output the hex binaries from the arduino-builder, I thought it would be fun if I could trust that the build that came out flashes to a device successfully. I pulled out the extra Mega2560 board I have that I use for testing my builds of the firmware anyhow before I would flash it to the printer, and I plugged it in to my Docker Host. The Jenkins Arduino agent mounts that device so it can access it.

After the binaries are built, I run:

avrdude -p m2560 -c avrispmkII -P /dev/ttyACM0 -C /usr/local/etc/avrdude.conf -D -U flash:w:/path/to/build.hex:i

Which will write the binary to the device. After that is successful, I run some serial commands to actually read from the Firmware to validate that it is announcing / working as Marlin.

After that is successful, it will zip up the hex files, and it creates a Github release and uploads the file to the release.

You can find most of the “work” in the github repo in either the Jenkinsfile, or the .deploy scripts folder. I still have some issues to iron out, like making sure the serial port is available again after the push to the device. After I get that stuff wrapped up, I will see what I have to adjust to make the container images publicly available.

Friday, December 29, 2017

Setting up Artifactory as Docker Registry

I was setting up artifactory as a docker registry on-premises with a self-signed certificate. This was not as simple as some of the docs suggested. It took me a bit to put together the process for this as it wasn’t really laid out in any single place. Here is what I did to get it working.

Distro: Ubuntu 16.04

I decided to do the subdomain method for setup. my FQDN that I will be subdomaining off of is artifactory.contoso.com. Each subdomain will be a different registry within artifactory. This will assume you already have an NGINX  instance setup to do the reverse proxy with the configuration defined by the Artifactory Reverse Proxy Generator.

Create self-signed certificate. I store mine in /mnt/data/ssl

$ openssl req -newkey rsa:2048 -nodes –keyout /mnt/data/ssl/wildcard.artifactory.contoso.com.key -x509 -days 365 –out /mnt/data/ssl/wildcard.artifactory.contoso.com.cert

Need to make this certificate available for docker

# mkdir –p /etc/docker/certs.d/wildcard.artifactory.contoso.com;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.key /etc/docker/certs.d/wildcard.artifactory.contoso.com/domain.key;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.cert /etc/docker/certs.d/wildcard.artifactory.contoso.com/domain.cert;
# ln –s /etc/docker/certs.d/wildcard.artifactory.contoso.com /etc/docker/certs.d/docker.artifactory.contoso.com;
# ln –s /etc/docker/certs.d/wildcard.artifactory.contoso.com /etc/docker/certs.d/docker-local.artifactory.contoso.com;

Now we have a folder setup for each subdomain for each docker registry in Artifactory. Next we need to add the certificates so the CA is known by the system.

# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.key /usr/local/share/ca-certificates/wildcard.artifactory.contoso.com.key;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.cert /usr/local/share/ca-certificates/wildcard.artifactory.contoso.com.crt;
# update-ca-certificates;

Next we need to add the domains to the docker options to allow them to be insecure.

# nano /etc/init.d/docker
### EDIT ###
DOCKER_OPTS="$DOCKER_OPTS --insecure-registry docker.artifactory.contoso.com --insecure-registry docker-local.artifactory.contoso.com

Finally, we just need to restart docker.

# systemctl restart docker

YMMV, but these are the steps that I needed to do to get things working for me.

Wednesday, December 13, 2017

No Matching Cipher Found

Today I tried to pull latest from the develop branch in a git repository in TFS 2015. I use SSH for authentication to tfs git repositories, and when I ran the git pull command, I was presented with the following error:

no matching cipher found. their offer: aes256-cbc,aes192-cbc,aes128-cbc

There were some other lines about making sure the repository existed, and that I had permission, etc. But this line was the one that sort of stood out to me. It is not an error that I have come across before. It took me a little while to track down the issue, which is why I am writing this.

The error is not a TFS issue, nor is it a git issue. The error is coming from SSH. I think it started after I updated my version of openSSH on my mac to version 7.6p1.

To fix the issue, I opened up /etc/ssh/ssh_config and added the lines:

Match Host my-tfs-server.company-domain.com
    Ciphers +aes128-cbc,aes192-cbc,aes256-cbc

You could make it less restrictive and omit Match Host line altogether, but I would rather add the exception for the specific servers that require it. After adding those lines, I was able to pull latest again.

Sunday, November 26, 2017

ROLLS HA43 PRO Monitor Post Mount

I have a ROLLS HA43 PRO 4 Channel Headphone amplifier and I have hated how it sits on my desk. It never stays where I want it, and is a pain to see what the volume is set to.

This weekend, I took some time in Autodesk Fusion 360 to design a tray to mount the HA43 to my monitor post. After a couple of test prints, and filament spool changes, it is finally printed.

If you have this amp, and a 2" (51mm) monitor post, you can download the files from Thingiverse.

2017-11-26 17.59.462017-11-26 18.41.072017-11-26 18.41.262017-11-26 18.42.03

Friday, October 20, 2017

PAGE FAULT IN UNPAGED AREA Windows 10 Insider Build 17017 GSOD/BSOD

After updating to Windows Insider 17017, I rebooted. Once I did, I got stuck in a GSOD/BSOD boot loop. See the loop in this video:

After some time looking around and such, I found that I needed to copy the volsnap.sys file from the Windows.old folder to the current Windows folder.

Here are the steps I took:

  • Downloaded the Windows Media Creation Tool.
  • Booted off the USB created above.
  • Went into the Recovery tools for the system and opened the command console
  • move c:\Windows\System32\drivers\volsnap.sys c:\Windows\System32\drivers\volsnap.bkp
  • copy c:\Windows.old\Windows\System32\drivers\volsnap.sys c:\Windows\System32\drivers\volsnap.sys
  • reboot

System then booted up with no problem.

Marlin Firmware and Jenkins

I have a 3d printer that uses the Marlin firmware. It’s an Alunar M508 (Prusa I3 Clone) and I maintain a build of Marlin for it that is tailored for that printer. Recently, I thought it would be fun to set up a Jenkins build agent that can build Arduino code. The agent is a docker image that is based off a base sshd image. Currently these are not available publicly, but I may change that in the future.

The base image is just a standard sshd server so so Jenkins can communicate to the agent.

The arduino agent installs arduino 1.8.5, and a few things like pip, gcc, etc. I also have some scripts that I put together that allow the build pipeline install Arduino Boards and Libraries. Like the board and library managers in the UI.

board-manager --name='Arduino AVR Boards' --version='latest' --packager='arduino'

That command will install the latest AVR boards and all the required dependencies. Additionally, to install a libarary, it would look like this:

library-manager --name='LiquidCrystal' --version='latest';

After I got all that setup and able to output the hex binaries from the arduino-builder, I thought it would be fun if I could trust that the build that came out flashes to a device successfully. I pulled out the extra Mega2560 board I have that I use for testing my builds of the firmware anyhow before I would flash it to the printer, and I plugged it in to my Docker Host. The Jenkins Arduino agent mounts that device so it can access it.

After the binaries are built, I run:

avrdude -p m2560 -c avrispmkII -P /dev/ttyACM0 -C /usr/local/etc/avrdude.conf -D -U flash:w:/path/to/build.hex:i

Which will write the binary to the device. After that is successful, I run some serial commands to actually read from the Firmware to validate that it is announcing / working as Marlin.

After that is successful, it will zip up the hex files, and it creates a Github release and uploads the file to the release.

You can find most of the “work” in the github repo in either the Jenkinsfile, or the .deploy scripts folder. I still have some issues to iron out, like making sure the serial port is available again after the push to the device. After I get that stuff wrapped up, I will see what I have to adjust to make the container images publicly available.

Setting up Artifactory as Docker Registry

I was setting up artifactory as a docker registry on-premises with a self-signed certificate. This was not as simple as some of the docs suggested. It took me a bit to put together the process for this as it wasn’t really laid out in any single place. Here is what I did to get it working.

Distro: Ubuntu 16.04

I decided to do the subdomain method for setup. my FQDN that I will be subdomaining off of is artifactory.contoso.com. Each subdomain will be a different registry within artifactory. This will assume you already have an NGINX  instance setup to do the reverse proxy with the configuration defined by the Artifactory Reverse Proxy Generator.

Create self-signed certificate. I store mine in /mnt/data/ssl

$ openssl req -newkey rsa:2048 -nodes –keyout /mnt/data/ssl/wildcard.artifactory.contoso.com.key -x509 -days 365 –out /mnt/data/ssl/wildcard.artifactory.contoso.com.cert

Need to make this certificate available for docker

# mkdir –p /etc/docker/certs.d/wildcard.artifactory.contoso.com;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.key /etc/docker/certs.d/wildcard.artifactory.contoso.com/domain.key;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.cert /etc/docker/certs.d/wildcard.artifactory.contoso.com/domain.cert;
# ln –s /etc/docker/certs.d/wildcard.artifactory.contoso.com /etc/docker/certs.d/docker.artifactory.contoso.com;
# ln –s /etc/docker/certs.d/wildcard.artifactory.contoso.com /etc/docker/certs.d/docker-local.artifactory.contoso.com;

Now we have a folder setup for each subdomain for each docker registry in Artifactory. Next we need to add the certificates so the CA is known by the system.

# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.key /usr/local/share/ca-certificates/wildcard.artifactory.contoso.com.key;
# cp /mnt/data/ssl/wildcard.artifactory.contoso.com.cert /usr/local/share/ca-certificates/wildcard.artifactory.contoso.com.crt;
# update-ca-certificates;

Next we need to add the domains to the docker options to allow them to be insecure.

# nano /etc/init.d/docker
### EDIT ###
DOCKER_OPTS="$DOCKER_OPTS --insecure-registry docker.artifactory.contoso.com --insecure-registry docker-local.artifactory.contoso.com

Finally, we just need to restart docker.

# systemctl restart docker

YMMV, but these are the steps that I needed to do to get things working for me.

No Matching Cipher Found

Today I tried to pull latest from the develop branch in a git repository in TFS 2015. I use SSH for authentication to tfs git repositories, and when I ran the git pull command, I was presented with the following error:

no matching cipher found. their offer: aes256-cbc,aes192-cbc,aes128-cbc

There were some other lines about making sure the repository existed, and that I had permission, etc. But this line was the one that sort of stood out to me. It is not an error that I have come across before. It took me a little while to track down the issue, which is why I am writing this.

The error is not a TFS issue, nor is it a git issue. The error is coming from SSH. I think it started after I updated my version of openSSH on my mac to version 7.6p1.

To fix the issue, I opened up /etc/ssh/ssh_config and added the lines:

Match Host my-tfs-server.company-domain.com
    Ciphers +aes128-cbc,aes192-cbc,aes256-cbc

You could make it less restrictive and omit Match Host line altogether, but I would rather add the exception for the specific servers that require it. After adding those lines, I was able to pull latest again.

ROLLS HA43 PRO Monitor Post Mount

I have a ROLLS HA43 PRO 4 Channel Headphone amplifier and I have hated how it sits on my desk. It never stays where I want it, and is a pain to see what the volume is set to.

This weekend, I took some time in Autodesk Fusion 360 to design a tray to mount the HA43 to my monitor post. After a couple of test prints, and filament spool changes, it is finally printed.

If you have this amp, and a 2" (51mm) monitor post, you can download the files from Thingiverse.

2017-11-26 17.59.462017-11-26 18.41.072017-11-26 18.41.262017-11-26 18.42.03

PAGE FAULT IN UNPAGED AREA Windows 10 Insider Build 17017 GSOD/BSOD

After updating to Windows Insider 17017, I rebooted. Once I did, I got stuck in a GSOD/BSOD boot loop. See the loop in this video:

After some time looking around and such, I found that I needed to copy the volsnap.sys file from the Windows.old folder to the current Windows folder.

Here are the steps I took:

  • Downloaded the Windows Media Creation Tool.
  • Booted off the USB created above.
  • Went into the Recovery tools for the system and opened the command console
  • move c:\Windows\System32\drivers\volsnap.sys c:\Windows\System32\drivers\volsnap.bkp
  • copy c:\Windows.old\Windows\System32\drivers\volsnap.sys c:\Windows\System32\drivers\volsnap.sys
  • reboot

System then booted up with no problem.