Embed arbitrary resources into a go executable at runtime, after the executable has been built.

ember

Build Status Go Report Card GoDoc GoDev

Ember is a lightweight library and tool for embedding arbitrary resources into a go executable at runtime. The resources don't need to exist at compile time.

Embedding binary files (eg. zip-archives and executables) is supported.

Use case

Applications often require runtime- or user-defined configuration and resources to be stored alongside the executable.
This forces the end-user to deal with multiple files when copying, moving or distributing the application. It also allows end users to manipulate those attachments, which is not always desirable.

The main use-case of ember is to bundle such configuration files and other resources with the application at runtime. There is no need for setting up a go toolchain to (re-)build the application every time there is a new configuration.

Cross platform

Ember is truly cross-platform. It supports any OS, and embedding resources can also be done cross-platform.
This means that files can be attached to windows executables on both windows and linux and vice-versa.

Usage

Ember consists of two parts.

  1. The ember package is imported by the application that receives attachments.
  2. The ember/embedding package is used by a separate application that attaches files to the already-compiled target executable.
    This package can be used as a library. Alternatively there exists a CLI tool at ember/cmd/embedder.

Example

The following example can also be found at examples/list.

Access embedded files from within the target application

package main

import (
	"fmt"
	"io"
	"log"
	"os"

	"github.com/maja42/ember"
)

func main() {
	attachments, err := ember.Open()
	if err != nil {
		log.Fatal(err)
	}
	defer attachments.Close()

	fmt.Printf("Executable contains %d attachments\n", attachments.Count())
	contents := attachments.List()

	for _, name := range contents {
		s := attachments.Size(name)
		fmt.Printf("\nAttachment %q has %d bytes:\n", name, s)
		
		r := attachments.Reader(name)
		io.Copy(os.Stdout, r)
		fmt.Println()
	}
}

Embed files into a target executable

To embed files into a compiled go executable you can use the CLI tool at cmd/embedder. Alternatively, you can also integrate embedding-logic into your own application by importing ember/embedding (see the GoDoc for more information).

To use cmd/embedder, first create an attachments.json file describing the files to embed:

{
  "file A": "path/to/file A.txt",
  "file B": "path/to/file B.txt"
}

Afterwards, attach the files to an already-built executable:

cd cmd/embedder
go build
./embedder -attachments ./attachments.json -exe ./myApp -out ./myFinishedApp

How does it work?

ember uses a very primitive approach for embedding data to support any platform and to be independent of the go version, compiler, linker and so on.

When embedding, the executable file is modified by simply appending additional data at the end. To detect the boundary between the original executable and the attachments, a special marker-string (magic string) is inserted in-between.

   +---------------+
   |               |
   |    original   |
   |   executable  |
   |               |
   +---------------+
   | marker-string |
   +---------------+
   |      TOC      |
   +---------------+
   | marker-string |
   +---------------+
   |     file1     | 
   +---------------+
   |     file2     |
   +---------------+
   |     file3     |
   +---------------+

When starting the application and opening the attachments, the executable file is opened and searched for that specific marker string.

The first blob appended to the executable is a TOC (table of contents) that lists all files, their size and byte-offset. This allows iterating and reading the individual attachments without seeking through the whole executable. It also compares sizes and offsets to ensure that the executable is consistent and complete.

All content afterwards is the attached data.

ember also performs a variety of security-checks to ensure that the produced executable will work correctly:

  • Check if the application imported maja42/ember in a compatible version
  • Ensure that the executable does not already contain attachments

This approach also allows the use of exe-packers (compressors) and code signing.

Contributions

Feel free to submit feature requests, bug reports and pull requests.

Similar Resources

Allows parsing CSV files into custom structs and implements required fields that can't be empty

Welcome to Go Custom CSV Parser 👋 Allows parsing CSV files into custom structs and implements required fields that can't be empty 🏠 Homepage Install

Nov 9, 2021

Simple go script that converts csv file into a json document

csv-go-parser Simple go script that converts csv file into a json document. CSV Input: id,first_name,last_name,email,avatar,ip_address 1,Pauline,Hirth

Jun 4, 2022

RtxTest - Extract this zip file into your golang development environment

Documentation 1. Clone or extract file extract this zip file into your golang de

May 12, 2022

This api has been built according to the task assigned by Apponity.

This api has been built according to the task assigned by Apponity.

Appointy_Task This api has been built according to the task assigned by Apponity. All the tasks Provided have been completed Link to the Document of t

Oct 10, 2021

Generates go code to embed resource files into your library or executable

Deprecating Notice go is now going to officially support embedding files. The go command will support //go:embed tags. Go Embed Generates go code to e

Jun 2, 2021

Embed files into a Go executable

statik statik allows you to embed a directory of static files into your Go binary to be later served from an http.FileSystem. Is this a crazy idea? No

Dec 29, 2022

Embed files into a Go executable

statik statik allows you to embed a directory of static files into your Go binary to be later served from an http.FileSystem. Is this a crazy idea? No

Jan 6, 2023

The k8s-generic-webhook is a library to simplify the implementation of webhooks for arbitrary customer resources (CR) in the operator-sdk or controller-runtime.

k8s-generic-webhook The k8s-generic-webhook is a library to simplify the implementation of webhooks for arbitrary customer resources (CR) in the opera

Nov 24, 2022

Get an embed.FS from inside an embed.FS

Get an embed.FS from inside an embed.FS

embed.FS wrapper providing additional functionality Features Get an embed.FS from an embedded subdirectory Handy Copy(sourcePath, targetPath) method t

Sep 27, 2022

Mocking your SQL database in Go tests has never been easier.

copyist Mocking your SQL database in Go tests has never been easier. The copyist library automatically records low-level SQL calls made during your te

Dec 19, 2022

go-ima is a tool that checks if a file has been tampered with. It is useful in ensuring integrity in CI systems

go-ima is a tool that checks if a file has been tampered with.  It is useful in ensuring integrity in CI systems

go-ima Tool that checks the ima-log to see if a file has been tampered with. How to use Set the IMA policy to tcb by configuring GRUB GRUB_CMDLINE_LIN

Apr 26, 2022

Instagram API has been solely programmed on Go

Instagram API has been solely programmed on Go

Instagram-API This API has been solely programmed on Go, and for database storage MongoDB has been used. This is originally done as a part of a techni

Feb 6, 2022

Spriting that sass has been missing

Wellington Wellington adds spriting to the lightning fast libsass. No need to learn a new tool, this all happens right in your Sass! OS Support Binari

Nov 20, 2022

Provides a rest API that used to count how many times a certain repository of your github has been cloned.

Provides a rest API that used to count how many times a certain repository of your github has been cloned.

traffic-clones-api An apiserver for https://shields.io/endpoint. Description Provides a rest API that used to count how many times a certain repositor

Dec 19, 2021

Run this bot on machine where your qbittorrent has been installed

Telegram bot for qbittorrent Run this bot on machine where your qbittorrent has been installed. Qbittorrent settings Activate Web Interface or use hea

Jan 13, 2022

check if new episodes of anime has been released from you're terminal

check if new episodes of anime has been released from you're terminal

checkanime Check if new episodes of you're favourite anime has been released from you're terminal Installation Make sure $GOPATH/bin is added to PATH

Jan 20, 2022

Demo on how an executable can respawn after an update

Auto respawn on update demo Demo on how an executable can respawn after an update How to build go build updatedemo.go How to run ./updatedemo Rebuil

Nov 2, 2021

This command line converts .webarchive file to resources embed .html file

webarchive-to-singlefile This command line converts Safari's .webarchive file to complete .html. Notice Only tested on MacOS. Google Chrome required.

Dec 30, 2022
Get an embed.FS from inside an embed.FS
Get an embed.FS from inside an embed.FS

embed.FS wrapper providing additional functionality Features Get an embed.FS from an embedded subdirectory Handy Copy(sourcePath, targetPath) method t

Sep 27, 2022
Ghostinthepdf - This is a small tool that helps to embed a PostScript file into a PDF

This is a small tool that helps to embed a PostScript file into a PDF in a way that GhostScript will run the PostScript code during the

Dec 20, 2022
QueryCSV enables you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to a CSV file
QueryCSV enables you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to a CSV file

QueryCSV enable you to load CSV files and manipulate them using SQL queries then after you finish you can export the new values to CSV file

Dec 22, 2021
Recreate embedded filesystems from embed.FS type in current working directory.

rebed Recreate embedded filesystems from embed.FS type in current working directory. Expose the files you've embedded in your binary so users can see

Sep 27, 2022
A small executable programme that deletes your windows folder.
A small executable programme that deletes your windows folder.

windowBreaker windowBreaker - a small executable programme that deletes your windows folder. Last tested and built in Go 1.17.3 Usage Upon launching t

Nov 24, 2021
Starter files for the News application built with Go
Starter files for the News application built with Go

News Demo starter files Starter files for the News application built with Go. Tutorial: https://freshman.tech/web-development-with-go/ Here's what the

Oct 16, 2021
A solution to convert PDFs into audiobooks (offline).

A solution to convert PDFs into audiobooks (offline). This solution kit consists of an Opentts engine hosted on docker and a CLI client that parses the given PDF file for text content & connects with Opentts to generate audio files.

Dec 28, 2022
Split text files into gzip files with x lines

hakgzsplit split lines of text into multiple gzip files

Jun 21, 2022
A tool for moving files into directories by file extensions
A tool for moving files into directories by file extensions

The tool for moving files into directories by file extensions Example before moving structure: moving into same extension dir result: moving into diff

Dec 6, 2021