Can't build Golang project as snap

Snapcraft YAML:

base: core20
grade: devel
confinement: devmode

apps:
  cli:
    command: diode

architectures:
  - arm64
  - amd64

parts:
  cli:
    plugin: go
    source: https://github.com/.../...
    override-build: |
      make openssl
      go mod download
      make test
      make

build-packages:
  - pkg-config
  - libreadline-dev
  - libncurses5-dev
  - libssl-dev
  - openssl
  - wget

Error snippet:

+ go mod download
+ make test
File /snap/go/10008/src/runtime/runtime.go is read-only; trying to patch anyway
patch: **** Can't create temporary file /snap/go/10008/src/runtime/runtime.go.ovdYw22 : Read-only file system
make: *** [Makefile:37: runtime] Error 2
Failed to run 'override-build': Exit code was 2.
bash: cannot set terminal process group (45154): Inappropriate ioctl for device
bash: no job control in this shell

It seems that the build process needs to create temporary files, but it’s a read-only system. Is there a workaround for this?

Thanks in advance!

I can’t check that locally because the yaml file is incomplete, but what is the test target in the Makefile trying to do? Does it work if you build it by hand without using snapcraft?

Hi @cmatsuoka, I can’t get it to work by hand either (I’m building with snapcraft --debug).

The test target is trying to apply a patch to a go source file, but is getting rejected because it’s being built on a read-only filesystem (afaict).

I think I know what is going on now (I am not a seasoned golang dev and I am new to snapcraft). Since the go plugin is in /snap/go/1008 and my project is trying to patch /snap/go/1008/src/runtime/runtime.go, it is failing to build because /snap is a read-only mount.

So I guess my real question is, can I modify the go plugin or copy it over to /root/go and change the GOROOT to that?

What you can do here if you really need to patch the go runtime is to change the plugin to “nil” (since you’re overriding the build commands anyway) and add golang-go to build-packages. Changing the base to core22 could be interesting too since some go modules could require a go version newer than the one available in focal. You would end up with something like:

base: core22

...

parts:
  cli:
    plugin: nil
    source: https://github.com/.../...
    build-packages:
      - golang-go
    override-build: |
      ...

Also is the order of make/make test correct there? It’s more usual to build the project and only test it afterwards.

1 Like

This was the correct approach. Thank you! As far as the order of make / test, I eventually moved it off to another stage in the build pipeline anyway :+1:

1 Like