Hi all,

We have an unusual issue owing somewhat to Jenkins' rather odd (but 
understandable) method of running things in containers.  Jenkins, when it runs 
things in Docker containers through its pipeline plugin, volume-mounts the 
workspace directory at the same location as it is in the host system (problem 
#1), and then it runs from that directory using (by default) Jenkins' UID/GID 
(problem #2).

The reasoning for some of this makes sense, after a fashion: if you force the 
UID to be either root or the UID used by your container by default, any 
artifacts you store in the bind-mounted area for later consumption by Jenkins 
have those permissions (if it's even possible), which then often can't even be 
removed by the cleanup process, leaving you with a royal mess.  Ask me how I 
know.

Our build process, for a multi-application set of containers built from a 
single repo, is as follows:

- Build "gobuild" images with Go compiler tools and needed distro packages 
(based off of golang:alpine for Alpine, and base Centos with a directory 
structure roughly mirroring golang:alpine)
- From the "gobuild" images, for each distro, build a "gobase" image by copying 
in the repo source, downloading the dependencies with "go mod download" (and 
"go get" for required Go tooling, like mockgen), generate the generated files, 
and build/install the binaries in a known location using "go install"
- Based on that image (for each distro), copy the application images and 
required assets into separate, fresh minimal-runtime container images per app 
to minimize image size

This generally works pretty well when we're building locally, and we can run 
the "go test" run off of the "gobase" image (which is part of why we build 
everything in a single image in the first place).  However, when building with 
Jenkins, we run into a problem: the parts of $GOPATH created by the "go" user 
used for the build (including $GOPATH/pkg) are effectively read-only to 
everyone but the "go" user, including Jenkins.  So is the original build 
directory, though that's a secondary concern because the volume-mounted 
workspace area at least has the same contents, except for what's been generated.

The problem here is that there doesn't seem to be any way to tell the go 
command to not even try to update the modules, and when it does, at the very 
least it is extremely noisy about not being able to update the mod cache.  In 
Go 1.11, we're still able to run the tests after that, it just jams up our log 
files.  But in Go 1.12, it fails when trying to write to go.sum in the local 
directory regardless of whether anything has changed.

Is there anything I've missed that can make Go just trust that the modules are 
good to go, so to speak?  We've tried "-mod=readonly", and it does... basically 
nothing to change this situation.  In theory, we could go to the extent of also 
building the test executables in the build phase and running them that way, but 
it seems like we should be able to build from a read-only tree and tell Go to 
just fail if something doesn't match up.  So far, there doesn't seem to be any 
way to inhibit the writes to go.sum (and I did spend about half a day looking 
at the source that drives that section without much luck, though I'm not sure 
if it's possible to redirect go.sum to a different directory).

I recognize that this is a sort of weird use case, but it does seem strange 
that there's no way to run the build that guarantees Go won't try to modify a 
source file (go.sum included, but also the packages).  Building from read-only 
storage isn't *that* out there.


- Dave

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to