• Stars
    star
    390
  • Rank 110,242 (Top 3 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Packer plugin for ARM images

Packer plugin for ARM images

This plugin lets you take an existing ARM image and modify it on your x86 machine. It is optimized for raspberry pi use case - MBR partition table, with the file system partition being the last partition.

With this plugin, you can:

  • Provision new ARM images from existing ones
  • Use ARM binaries for provisioning (apt-get install for example)
  • Resize the last partition (the filesystem partition in the raspberry pi) in case you need more space than the default.

Tested for Raspbian images built on Ubuntu 19.10. It is based partly on the chroot AWS provisioner, though the code was copied to prevent AWS dependencies.

How it works

The plugin runs the provisioners in a chroot environment. Binary execution is done using qemu-arm-static, via binfmt_misc.

Dependencies

This builder uses the following shell commands:

  • qemu-user-static - Executing arm binaries. This is optional as the released binary can use embedded versions of qemu-aarch64-static and qemu-arm-static. If you have one installed, it will be used instead of the embedded ones.
  • losetup - To mount the image. This command is pre-installed in most distributions.

To install the needed binaries on derivatives of the Debian Linux variant:

sudo apt install qemu-user-static

Fedora:

sudo dnf install qemu-user-static

Archlinux:

pacman -S qemu-arm-static

Other commands that are used are (that should already be installed) : mount, umount, cp, ls, chroot.

To resize the filesystem, the following commands are used:

  • e2fsck
  • resize2fs

To provide custom arguments to qemu-arm-static using the qemu_args config, gcc is required (to compile a C wrapper).

Note: resizing is only supported for the last active partition in an MBR partition table (as there is no need to move things).

This plugin uses the following kernel feature:

  • support for /proc/sys/fs/binfmt_misc so that ARM binaries are automatically executed with qemu

Operation

This provisioner allows you to run packer provisioners on your ARM image locally. It does so by mounting the image on to the local file system, and then using chroot combined with binfmt_misc to the provisioners in a simulated ARM environment.

Configuration

To use, you need to provide an existing image that we will then modify. We re-use packer's support for downloading ISOs (though the image should not be an ISO file). Supporting also zipped images (enabling you downloading official raspbian images directly).

See raspbian_golang.json and config.go for details. For configuration reference, see the builder doc.

Note if your image is arm64, set qemu_binary to qemu-aarch64-static in your configuration json file.

Compiling and Testing

Building

As this tool performs low-level OS manipulations - consider using a VM to run this code for isolation. While this is recommended, it is not mandatory.

This project uses go modules for dependencies introduced in Go 1.11. To build:

git clone https://github.com/solo-io/packer-plugin-arm-image
cd packer-plugin-arm-image
go mod download
go build

Running with Vagrant

This project includes a Vagrant file and helper script that build a VM run time environment. The run time environment has custom provisions to build an image in an iterative fashion (thanks to @tommie-lie for adding this feature).

To use the Vagrant environment, run the following commands:

git clone https://github.com/solo-io/packer-plugin-arm-image
cd packer-plugin-arm-image
vagrant up

To build an image edit samples/raspbian_golang.json (or set PACKERFILE to point to your json config), and use vagrant provision like so:

vagrant provision --provision-with build-image

The example config produces an image with go installed and extends the filesystem by 1GB.

That's it! Flash it and run!

Running locally

This builder requires root permissions as it performs low level machine operations. To run it locally, you can set PACKER_CONFIG_DIR back to your local home before sudo-ing to packer. For example:

PACKER_CONFIG_DIR=$HOME sudo -E $(which packer) build .

Running with Docker

Prerequisites

Docker needs capability of creating new devices on host machine, so it can create /dev/loop* and mount image into it. While it may be possible to accomplish with multiple --device-cgroup-rule and --add-cap, it's much easier to use --privileged flag to accomplish that. Even so, it is considered bad practice to do so, do it with extra precautions. Also because of those requirements rootless will not work for this container.

Option 1: Clone this repo and build the Docker image locally

Build the Docker image locally

docker build -t packer-builder-arm .

Build the samples/raspbian_golang.json Packer image

docker run \
  --rm \
  --privileged \
  -v /dev:/dev \
  -v ${PWD}:/build:ro \
  -v ${PWD}/packer_cache:/build/packer_cache \
  -v ${PWD}/output-arm-image:/build/output-arm-image \
  -e PACKER_CACHE_DIR=/build/packer_cache \
  packer-builder-arm build samples/raspbian_golang.json

Option 2: Run the published Docker image

Alternatively, you can use the ghcr.io/solo-io/packer-plugin-arm-image that's built off latest master without needing to clone this repository.

docker run \
  --rm \
  --privileged \
  -v /dev:/dev \
  -v ${PWD}:/build:ro \
  -v ${PWD}/packer_cache:/build/packer_cache \
  -v ${PWD}/output-arm-image:/build/output-arm-image \
  ghcr.io/solo-io/packer-plugin-arm-image build samples/raspbian_golang.json

That's it, flash it and run!

Running Standalone

packer build samples/raspbian_golang.json

Flashing

We have a post-processor stage for flashing.

Golang flasher

go build cmd/flasher/main.go

It will auto-detect most things and guides you with questions.

dd

(Tested on MacOS)

# find the identifier of the device you want to flash
diskutil list

# un-mount the disk
diskutil unmountDisk /dev/disk2

# flash the image, go for a coffee
sudo dd bs=4m if=output-arm-image/image of=/dev/disk2

# eject the disk
diskutil eject /dev/disk2

Cookbook

Raspberry Pi Provisioners

Enable ssh

{
  "type": "shell",
  "inline": ["touch /boot/ssh"]
}

Set WiFi password

set the user variables name wifi_name and wifi_password, then:

{
  "type": "shell",
  "inline": [
    "echo 'network={' >> /etc/wpa_supplicant/wpa_supplicant.conf",
    "echo '    ssid=\"{{user `wifi_name`}}\"' >> /etc/wpa_supplicant/wpa_supplicant.conf",
    "echo '    psk=\"{{user `wifi_password`}}\"' >> /etc/wpa_supplicant/wpa_supplicant.conf",
    "echo '}' >> /etc/wpa_supplicant/wpa_supplicant.conf"
    ]
}

Add ssh key to authorized keys, enable ssh, disable password login

This example locks down the image to only use your current ssh key. Disabling password login makes it extra secure for networked environments.

Note: this example requires you to run the plugin without a VM, as it copies your local ssh key.

{
  "variables": {
    "ssh_key_src": "{{env `HOME`}}/.ssh/id_rsa.pub",
    "image_home_dir": "/home/pi"
  },
  "builders": [
    {
      "type": "arm-image",
      "iso_url": "https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-12-01/2017-11-29-raspbian-stretch-lite.zip",
      "iso_checksum": "sha256:e942b70072f2e83c446b9de6f202eb8f9692c06e7d92c343361340cc016e0c9f"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "mkdir {{user `image_home_dir`}}/.ssh"
      ]
    },
    {
      "type": "file",
      "source": "{{user `ssh_key_src`}}",
      "destination": "{{user `image_home_dir`}}/.ssh/authorized_keys"
    },
    {
      "type": "shell",
      "inline": [
        "touch /boot/ssh"
      ]
    },
    {
      "type": "shell",
      "inline": [
        "sed '/PasswordAuthentication/d' -i /etc/ssh/sshd_config",
        "echo >> /etc/ssh/sshd_config",
        "echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config"
      ]
    }
  ]
}

A complete example

See everything included in here: samples/pi-secure-wifi-ssh.json. Build like so:

sudo packer build  -var wifi_name=SSID -var wifi_password=PASSWORD samples/pi-secure-wifi-ssh.json
# or  if running from vagrant ssh:
sudo packer build  -var wifi_name=SSID -var wifi_password=PASSWORD /vagrant/samples/pi-secure-wifi-ssh.json

More Repositories

1

gloo

The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy
Go
3,822
star
2

unik

The Unikernel & MicroVM Compilation and Deployment Platform
Go
2,678
star
3

squash

The debugger for microservices
Go
1,716
star
4

bumblebee

Get eBPF programs running from the cloud to the kernel in 1 line of bash
C
1,256
star
5

sqoop

The GraphQL Engine powered by Gloo
Go
529
star
6

wasm

Web Assembly tools and SDKs for extending cloud-native infrastructure
Go
305
star
7

kubesquash

A debugger for Kubernetes applications.
Go
229
star
8

envoy-operator

Envoy Operator creates/configures/manages Envoy clusters atop Kubernetes
Go
154
star
9

workshops

Shell
126
star
10

go-utils

golang utilities
Go
112
star
11

autopilot

The Service Mesh SDK
Go
104
star
12

hoot

code from hoot episodes
Go
104
star
13

proxy-runtime

TypeScript
86
star
14

protoc-gen-openapi

Compile Google protobufs to openAPI v3 specs
Go
71
star
15

solo-kit

Toolkit for developing stateless, event-driven, declarative API systems
Go
69
star
16

gloo-connect

The Consul-Native Service Mesh
Go
64
star
17

glooshot

Chaos engineering framework to help you Immunize your service mesh
Go
52
star
18

gitops-library

gitops examples using argocd, helm, and yaml
Smarty
31
star
19

envoy-nats-streaming

C++
29
star
20

wasm-image-spec

wasm oci image specification
25
star
21

envoy-gloo

C++
25
star
22

squash-vscode

Debug your microservices application from VS Code
TypeScript
23
star
23

thetool

The tool to build the Gloo universe
Go
20
star
24

skv2

Solo-Kit V2 - Solo.io Operator Framework
Go
20
star
25

glooctl

glooctl - CLI for gloo
Go
18
star
26

solo-cop

Solo Communities of Practice
Shell
16
star
27

mesh-week

A week of Istio goodness (with focus for the exam).
16
star
28

service-mesh-extensions

A public registry of all service mesh extensions and other content for the Service Mesh Hub.
Go
14
star
29

squash-intellij

Debug your microservices application from IntelliJ IDEA
Java
14
star
30

envoy-workshop-basics

Envoy basics workshop
Python
12
star
31

kdiag

Go
11
star
32

aoa-catalog

A collection of Solo.io demo environments driven by GitOps using the ArgoCD app-of-apps pattern.
Shell
11
star
33

envoy-cves

Go
11
star
34

envoy-wasm-filters

repo containing solo.io envoy wasm filters
C++
10
star
35

unik-hub

code for UniK Hub backend
Go
10
star
36

envoy-consul-connect

Envoy Filter for Consul Connect
C++
9
star
37

cf-unik-buildpack

CloudFoundry Buildpack for Building & Running Unikernels
Go
9
star
38

ext-auth-plugin-examples

Contains example Ext Auth plugin implementations.
Go
8
star
39

ambient-performance

Shell
8
star
40

gloo-ref-arch

Reference architectures, examples, and demos for Gloo
Go
8
star
41

envoy-lambda

Envoy with AWS lambda support
C++
8
star
42

capstan

Go
7
star
43

anyvendor

An all purpose tool to make working with protoc easier
Go
6
star
44

protoc-gen-ext

protc-gen tools for solo-io
Go
6
star
45

solo-apis

Read-only mirror for solo.io API definitions.
6
star
46

gloo-plugins

Repository of Translator Plugins for Gloo
Go
6
star
47

gloo-mesh-use-cases

Community of Practice dedicated to creating collateral on Gloo Mesh use cases
Shell
5
star
48

dev-portal-starter

This is a demo project, to be used with Gloo Platform API Portals. It may be used as a standalone API dev portal interface, or as a template.
TypeScript
4
star
49

k8s-utils

Go
4
star
50

gloo-ingress-controller

Gloo's Kubernetes Ingress Controller
Go
4
star
51

solo-docs

Repo containing consolidated docs for Gloo community and enterprise editions
Go
4
star
52

demo-petclinic-vet

Go version of vets page of pet clinic demo
Go
4
star
53

kubecontroller

Provides a convenience method for creating Kubernetes resource controllers
Go
4
star
54

envoy-google-function

envoy plugin to integrate with Google cloud functions
C++
4
star
55

gloo-gitops

3
star
56

valet

Valet helps automate kubernetes workflows in golang tests, command line scripts, and documentation
Go
3
star
57

envoy-transformation

C++
3
star
58

service-mesh-for-less-blog

Shell
3
star
59

envoy-azure-functions

C++
2
star
60

cake

i love cake
Go
2
star
61

grpc-example-app

Sample Apps for testing/demoing gRPC
Go
2
star
62

envoy-common

C++
2
star
63

training

Shell
2
star
64

external-apis

generated code for interacting with external APIs (kubernetes, Istio, etc). shared across solo.io projects
Go
2
star
65

vscode-gloo

The developer tools for Gloo
TypeScript
2
star
66

backstage-plugins-overview

This includes the documentation for the Backstage plugin: Gloo Portal.
2
star
67

gloo-k8s-service-discovery

Discovers Upstreams from Kubernetes Services
Go
2
star
68

bumblebee-website

TypeScript
2
star
69

demos-gloo

Shell
2
star
70

homebrew-tap

This is the homebrew tap for installing the command line clients for Solo.io
Ruby
1
star
71

supergloo-helm

Helm Charts for use with SuperGloo
Smarty
1
star
72

sample-gateway-manager

An example Gateway API implementation
Go
1
star
73

platform-portal-backstage-plugin-frontend

A Backstage frontend plugin for Gloo Platform Portal. View APIs and manage usage plans from the Backstage UI.
TypeScript
1
star
74

gloo-sdk-go

gloo SDK written in Go
Go
1
star
75

asdf-istio

asdf-vm plugin for istio
Shell
1
star
76

gloo-secret

Client library to abstract secret storage
Go
1
star
77

envoy-squash

plugin for squash inside envoy
C++
1
star
78

graphql-gloo-gateway-demo

Shell
1
star
79

k8s-code-generator

A fork of https://github.com/kubernetes/code-generator compatible with Solo-Kit
Go
1
star
80

solo-blog

solo.io/blog resources
Shell
1
star
81

solo-blog-knative-istio

1
star
82

demo-echo-server

Go
1
star
83

gloo-install

Scripts and Resources for installing gloo
Smarty
1
star
84

ext-auth-plugins

Public interfaces for external auth services and plugins
Go
1
star
85

gloo-function-discovery

Function Discovery for Gloo
Go
1
star
86

gloo-edge-use-cases

Shell
1
star
87

gloo-portal-issues

Public tracker for issues related to Gloo Portal
1
star
88

glooctl-plugin-index

Index for glooctl plugins
1
star
89

community

Community contents related to Solo open source community projects
1
star
90

doing-more-for-less

Scripts and data for performance testing.
Shell
1
star
91

smerf

Tools for testing the performance of service mesh implementations
Shell
1
star
92

qcon-ambient

Shell
1
star