Skip to content

Commit

Permalink
embedbin: implement fallback for missing memfd
Browse files Browse the repository at this point in the history
Some Linux platforms (notably WSL1) do not implement memfd.
This adds a fallback at runtime.

(cherry picked from commit 5a9a055)
  • Loading branch information
malt3 authored and katexochen committed Apr 30, 2024
1 parent 4cd4bc1 commit fe984b9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
8 changes: 8 additions & 0 deletions internal/embedbin/embedbin.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@
//
// The Install function creates a temporary file and writes the contents to it.
package embedbin

// Installed is a handle to an installed binary.
// Users must call Uninstall to clean it up.
type Installed interface {
Path() string
IsRegular() bool
Uninstall() error
}
23 changes: 20 additions & 3 deletions internal/embedbin/install_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,37 @@ package embedbin
import (
"fmt"

"github.com/spf13/afero"
"golang.org/x/sys/unix"
)

// MemfdInstaller installs embedded binaries.
type MemfdInstaller struct{}
type MemfdInstaller struct {
fallback *RegularInstaller
}

// New returns a new installer.
func New() *MemfdInstaller {
return &MemfdInstaller{}
return &MemfdInstaller{
fallback: &RegularInstaller{fs: afero.NewOsFs()},
}
}

// Install creates a memfd and writes the contents to it.
// the first argument is ignored on Linux (would be the prefix on other implementations).
func (*MemfdInstaller) Install(_ string, contents []byte) (*MemfdInstall, error) {
func (i *MemfdInstaller) Install(_ string, contents []byte) (Installed, error) {
// Try to install using memfd.
install, err := New().installMemfd(contents)
if err == nil {
return install, nil
}

// Fallback to regular installer.
return i.fallback.Install("", contents)
}

// installMemfd creates a memfd and writes the contents to it.
func (*MemfdInstaller) installMemfd(contents []byte) (*MemfdInstall, error) {
// Create a memfd.
fd, err := unix.MemfdCreate("embedded-binary", 0)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/embedbin/regular.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type RegularInstaller struct {
// Install creates a regular file and writes the contents to it.
// prefix is an optional prefix for the temporary file.
// If prefix is empty, a temporary directory will be used.
func (r *RegularInstaller) Install(prefix string, contents []byte) (*RegularInstall, error) {
func (r *RegularInstaller) Install(prefix string, contents []byte) (Installed, error) {
if prefix != "" {
if err := r.fs.MkdirAll(prefix, os.ModePerm); err != nil {
return nil, err
Expand Down

0 comments on commit fe984b9

Please sign in to comment.