Easy way to check go.mod replace via Linux namespaces
The common problem for monorepo and go modules is that the following
It is really easy to miss the go.mod replace directive
In a following text we will learn more about Linux, namespaces and container technologies like Docker or Podman.
go build is awesome tool, doing a lot of things in the background has
sometimes consequences. And the typical consequences is when we build the
software from an environment without network access. It should be every
Both https://opensuse and [https://getfedora.org][Fedora] disallow network access from their build workers. So that every build dependency must be correctly packaged and installed as a part of build process. And I am sure others Linux distributions have the same policy.
Similar case is a build of Docker image, where we don’t (and don’t want to) deploy SSH keys to access private git instance.
Step 4/9 : RUN go build go: firstname.lastname@example.org requires email@example.com: reading https://api.example.org/2.0/repositories/projects/foo?fields=scm: 403 Forbidden
There are a few ways for developer to solve it
Turn off networking
It is harsh method and I won’t be happy to have my audiostreams interrupted. Sadly it is truly multiplatform way.
Linux kernel has a concept of namespaces. They simply allow to virtualize several kernel resources and to pretend to userspace they are running on their own computer. Namespaces are key concept of all container technologies like Docker, Podman, LXC and others.
System allows you to manipulate with namespaces is via https://github.com/karelzak/util-linux/blob/master/sys-utils/unshare.1 command and system call. This way one can create private network namespace, which is not configured by default and can’t connect to anything.
curl --silent example.com | wc -l 46 unshare -r -n curl example.com curl: (7) Couldn't connect to server
Command does following
-r, --map-root-usermaps current user and group id to root. Not that this is fully secure, because from non-namespaced point of view is this still the same user.
-n, --netcreate own empty network namespace
unshare -r -n go build will ensure that
go build does not have
access to network at all.
$ docker run alpine:latest ping -c 1 184.108.40.206 PING 220.127.116.11 (18.104.22.168): 56 data bytes 64 bytes from 22.214.171.124: seq=0 ttl=54 time=1.426 ms --- 126.96.36.199 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 1.426/1.426/1.426 ms
With network none
$ docker run --network=none alpine:latest ping -c1 188.8.131.52 PING 184.108.40.206 (220.127.116.11): 56 data bytes ping: sendto: Network unreachable
Logo by Clker-Free-Vector-Images-3736@Pixbay: [https://pixabay.com/vectors/chain-broken-link-freedom-297842/]