gpg: keyserver receive failed: No dirmngr

As part of verifying the signature for a downloaded file using GnuPG running on Ubuntu 18.04 on WSL on Windows 10 1809, I tried to import the publisher’s signing key…

gpg --receive-keys 0x22C07BA534178CD02EFE22AAB88B2FD43DBDC284

… for which I received the following error message:

gpg: connecting dirmngr at '/home/foo/.gnupg/S.dirmngr' failed: IPC connect call failed
 gpg: keyserver receive failed: No dirmngr

According to Ben Hillis, a developer on the Windows Subsystem for Linux team, there was a bug in the version of GPG packaged into Ubuntu 18.04 that only manifests itself when running over WSL:

… this is a timing-related issue that is exposed because of a difference in how Windows and Linux handles connection attempts to localhost sockets. On Linux an attempt to connect to a localhost tcp socket on a port that is not active will return a failure immediately. On Windows there appears to be a 1 second timeout. This causes the following sequence to occur.
1. gpg spawns dirmngr
2. dirmngr attempt to connect to localhost port 9050 (this is attempted twice).
3. gpg attempts to connect to a unix socket that dirmngr creates after the localhost socket connection fails.
This one second timeout in step 2 is enough to cause gpg to think that dirmngr is not responding. There appears to be a retry loop in gpg, but it is not waiting long enough to account for the 1 second connect timeout (the connect is actually attempted twice).

His series of comments for the issue over at GitHub really seems to be an accurate description of the problem as I was able import the GPG key in Ubuntu 18.04 running in a Hyper-V VM without any problems whatsoever.

Back to WSL, note that although the command failed due to the timing issue described above, dirmngr is now running, so if you issue the command once again, it should work.

foo@bar:~$ gpg --receive-keys 0x22C07BA534178CD02EFE22AAB88B2FD43DBDC284
 gpg: connecting dirmngr at '/home/foo/.gnupg/S.dirmngr' failed: IPC connect call failed
 gpg: keyserver receive failed: No dirmngr

 foo@bar:~$ !!
 gpg --receive-keys 0x22C07BA534178CD02EFE22AAB88B2FD43DBDC284
 gpg: key B88B2FD43DBDC284: 22 signatures not checked due to missing keys
 gpg: key B88B2FD43DBDC284: public key "openSUSE Project Signing Key opensuse@opensuse.org" imported
 gpg: marginals needed: 3  completes needed: 1  trust model: pgp
 gpg: depth: 0  valid:   1  signed:   3  trust: 0-, 0q, 0n, 0m, 0f, 1u
 gpg: depth: 1  valid:   3  signed:   0  trust: 3-, 0q, 0n, 0m, 0f, 0u
 gpg: Total number processed: 1
 gpg:               imported: 1

Since I’m banging commands interactively against the shell, I’m OK with this workaround. On the other hand, if these commands were part of a script, I’d make sure dirmngr is running before issuing any commands that depend on it. In that case, you may want to take a look at the man pages.

How to copy Visual Code extensions to another machine

Earlier this month I was setting up an Ubuntu VM on Windows 10 for development and after installing Visual Studio Code it was time to install the extensions I’m used to having around.

There were 30 of them installed on my main development box. I probably don’t use most these of extensions, but I wasn’t in the mood to sort them out, so I searched for a way to export the settings so I could import them into Code running in the VM.

I wasn’t able to find what I was hoping for, the closest thing being the answers to “How can you export VS Code extension list” on StackOverflow.

# Based on the code snippet found at https://stackoverflow.com/a/49398449/151249
code --list-extensions | xargs -L 1 echo code --install-extension

The answers were a step in the right direction but not quite where I ultimately wanted the solution to be:

  1. Having the list of extensions checked into source control with the rest of the project. For instance, if the team agreed on using ESLint as a build step, having a script to automate installing the corresponding extension (possibly one of many) could help in ramping up new project members.
  2. Having a way to sync extensions between machines or a way to export a list of extensions (not tied to any specific project) I could easily import to anywhere needed, such as disposable VMs, a new machine provided by an employer, etc.

I didn’t have time to figure out how to implement any of those ideas to the full extent of how I think they should work, but in the spirit of “Always Be Automating” I did the next best thing which was hacking a couple of one-liners, a step closer to the solution I want it to eventually be.

First I created a file containing the list of extensions:

code --list-extensions > vscode-extensions.txt
view raw export hosted with ❤ by GitHub

I think for most people the easiest way to access the list from other machines is putting the file somewhere online. I’m of the opinion that the best place to store anything development related is on GitHub, so I uploaded the list to a gist over there:

DavidAnson.vscode-markdownlint
docsmsft.docs-article-templates
docsmsft.docs-markdown
docsmsft.docs-preview
EditorConfig.EditorConfig
GitHub.vscode-pull-request-github
ms-azuretools.vscode-azureappservice
ms-azuretools.vscode-azurefunctions
ms-azuretools.vscode-azurestorage
ms-azuretools.vscode-cosmosdb
ms-mssql.mssql
ms-vscode.azure-account
ms-vscode.azurecli
ms-vscode.cpptools
ms-vscode.csharp
ms-vscode.mono-debug
ms-vscode.powershell
ms-vscode.vscode-node-azure-pack
ms-vsts.team
msazurermtools.azurerm-vscode-tools
msjsdiag.debugger-for-chrome
PeterJausovec.vscode-docker
redhat.java
VisualStudioExptTeam.vscodeintellicode
vsciot-vscode.azure-iot-toolkit
vscjava.vscode-java-debug
vscjava.vscode-java-dependency
vscjava.vscode-java-pack
vscjava.vscode-java-test
vscjava.vscode-maven

Then all I had to do to install those extensions was to CURL that file and pipe it into code:

#!/bin/bash
curl https://gist.githubusercontent.com/alfredmyers/336ed20410acee6688f7ba7c85b5826f/raw/84afcdbb919e9a9912c73914c7859746e862259a/vscode-extensions.txt | xargs -L 1 code --install-extension

That did the trick and I was able to continue working on whatever I was working on, although I wasn’t quite happy with the gist’s URL. See, I don’t know of anyway of getting rid of that automatically generated GUID which would make the URL more memorable.

Earlier today after watching Amanda Sliver and John Papa on Five Things, where she mentioned how to list Visual Studio Code extensions from the command-line, I decided to fix that URL problem putting the list on a GitHub repo with GitHub Pages turned on so instead of a cryptic URL I have something more memorable.

#!/bin/bash
curl https://alfredmyers.github.io/codex/all.txt | xargs -L 1 code --install-extension

I decided to call the repo Codex, for Code Extensions. That gives me an easy to remember base URL: https://alfredmyers.github.io/codex/

For now, I only have a single list in “all.txt”, but there’s nothing stopping me from creating other lists containing extensions for specific purposes or projects. For instance:

  • https://alfredmyers.github.io/codex/dotnet.txt
  • https://alfredmyers.github.io/codex/nojejs.txt

Oh… And by the way, once you CURL that list, you can pipe it into any command you’d like. For instance, to uninstall all those extensions we got from all.txt:

#!/bin/bash
curl https://alfredmyers.github.io/codex/all.txt | xargs -L 1 code --uninstall-extension

Just make sure you have a list of the extensions you really need hanging around so you can use it to reset everything to a desired state.

I you find the idea interesting, feel free to fork the project (https://github.com/alfredmyers/codex) and hack it to your needs. And don’t forget to turn on GitHub pages so you can access the lists using an easy to remember base URL such as https://{your-user-name}.github.io/codex/.

error: gpg failed to sign the data

A couple of months ago I noticed that commits I’ve done through the GitHub web interface were receiving a “Verified” badge while commits done through the Git command line in WSL (Windows Subsystem for Linux) at my local dev machine weren’t.

I’m all for badges so I followed the steps found at About commit signature verification to setup GPG signing. The thing is, there was something still missing and as a result, when trying to commit I was getting an error message as follows:

error: gpg failed to sign the data
fatal: failed to write commit object

Fortunately, the solution is simple. Export a variable named GPG_TTY as follows:

export GPG_TTY=$(tty)

I ended appending it to ~/.bashrc so as to persist it between terminal sessions.

Cannot find runtime ‘node’ on PATH. Is ‘node’ installed?

On my current Windows box, I have Node.js installed only in WSL – not on Windows itself.

When debugging a Node.js application from within a Visual Studio Code instance started from WSL, you may receive the following message:

Cannot find runtime 'node' on PATH. Is 'node' installed?
Cannot find runtime ‘node’ on PATH. Is ‘node’ installed?

While the dev experience certainly could be better, the solution is quite simple: Click on the “Open launch.json” button and add a configuration for “useWSL” with the value set to “true”.

{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\entry-point.js",
"useWSL": true
}
]
}
view raw launch.json hosted with ❤ by GitHub