Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Portable Go module with bundled files that must be read

I’m trying to create a portable Go module that will be re-used in many different projects. This module, in order to function, needs to be able to read non-Go files that are bundled as part of the module. In this case, they’re some certificate bundles. The selection of which file to load is dynamic and based on input arguments.

What is the best way to specify the path to these files when loading them? I can’t seem to find any Go functions to get a path relative to the module (vs. relative to the executable that is using this module). For example, if my module structure looks like this:

mymodule/
  go.mod
  go.sum
  loadcerts.go
  certs/
    cert_A.pem
    cert_B.pem

And I need to do something like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// loadcerts.go

package mymodule

func LoadCerts(useB bool) error {
    newCertPool := x509.NewCertPool()

    // This is just to show that the selection is dynamic, and since
    // there are many different potential files to load, we can't 
    // embed them all
    bundleName := "cert_A.pem"
    if useB {
        bundleName = "cert_B.pem"
    }
    pem, err := ioutil.ReadFile(fmt.Sprintf("./certs/%s", bundleName))
    if err != nil {
        return err
    }
    if ok := newCertPool.AppendCertsFromPEM(pem); !ok {
        return err
    }
    ...
}

Referencing this file with a relative path (./certs/cert1.pem) doesn’t work, since Go uses the executable’s working directory for relative paths, and this imported module is somewhere entirely different.

How can I load this .pem file that is bundled with the portable module, regardless of where this module is being imported to?

>Solution :

Embed the files in the executable as a file system:

//go:embed certs
var f embed.FS

Read the files from the file system:

pem, err := f.ReadFile(fmt.Sprintf("certs/%s", bundleName))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading