{"id":13821621,"url":"https://github.com/rgl/tinkerbell-vagrant","last_synced_at":"2025-10-25T23:09:02.461Z","repository":{"id":139753513,"uuid":"266116661","full_name":"rgl/tinkerbell-vagrant","owner":"rgl","description":"Vagrant Environment for playing with Tinkerbell for provisioning AMD64 and ARM64 machines","archived":false,"fork":false,"pushed_at":"2021-12-10T09:01:55.000Z","size":601,"stargazers_count":19,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T00:41:13.155Z","etag":null,"topics":["amd64","arm64","bare-metal","pxe","raspberry-pi","tinkerbell"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rgl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-05-22T13:25:26.000Z","updated_at":"2023-08-06T14:55:50.000Z","dependencies_parsed_at":"2023-04-22T11:05:13.498Z","dependency_job_id":null,"html_url":"https://github.com/rgl/tinkerbell-vagrant","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Ftinkerbell-vagrant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Ftinkerbell-vagrant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Ftinkerbell-vagrant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgl%2Ftinkerbell-vagrant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rgl","download_url":"https://codeload.github.com/rgl/tinkerbell-vagrant/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252591046,"owners_count":21773013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amd64","arm64","bare-metal","pxe","raspberry-pi","tinkerbell"],"created_at":"2024-08-04T08:01:24.875Z","updated_at":"2025-10-25T23:08:57.439Z","avatar_url":"https://github.com/rgl.png","language":"Shell","funding_links":[],"categories":["raspberry-pi"],"sub_categories":[],"readme":"This is a [Vagrant](https://www.vagrantup.com/) Environment for playing with [Tinkerbell](https://tinkerbell.org/) for provisioning AMD64 and ARM64 (e.g. Raspberry Pi) machines.\n\n# Usage\n\nThis `provisioner` environment is essentially running all the Tinkerbell [components](https://tinkerbell.org/components/) inside a single virtual machine.\n\nIn order for it to work you need to connect the `provisioner` virtual network to a physical network that reaches the physical machines.\n\nI'm using Ubuntu 20.04 as the host, qemu/kvm/libvirt has the hypervisor, and a [tp-link tl-sg108e](https://www.tp-link.com/en/business-networking/easy-smart-switch/tl-sg108e/) switch.\n\n**NB** You can also use this vagrant environment without the switch (see the [Vagrantfile](Vagrantfile)).\n\nThe network is connected as:\n\n![](network.png)\n\nThe tp-link tl-sg108e switch is configured with [rgl/ansible-collection-tp-link-easy-smart-switch](https://github.com/rgl/ansible-collection-tp-link-easy-smart-switch) as:\n\n![](tp-link-sg108e-802-1q-vlan-configuration.png)\n![](tp-link-sg108e-802-1q-vlan-pvid-configuration.png)\n\n**NB** this line of switches is somewhat insecure as, at least, its configuration protocol (UDP port 29808 and TCP port 80) uses clear text messages. For more information see [How I can gain control of your TP-LINK home switch](https://www.pentestpartners.com/security-blog/how-i-can-gain-control-of-your-tp-link-home-switch/) and [Information disclosure vulnerability in TP-Link Easy Smart switches](https://www.chrisdcmoore.co.uk/post/tplink-easy-smart-switch-vulnerabilities/).\n\nThe host network is configured by netplan with `/etc/netplan/config.yaml` as:\n\n```yaml\nnetwork:\n  version: 2\n  renderer: networkd\n  ethernets:\n    enp3s0:\n      link-local: []\n      addresses:\n        - 10.1.0.1/24\n        - 192.168.0.254/24\n  bridges:\n    # NB this is equivalent of executing:\n    #       ip link add name br-rpi type bridge\n    #       ip addr flush dev br-rpi\n    #       ip addr add dev br-rpi 10.3.0.1/24\n    #       ip link set dev br-rpi up\n    #       ip addr ls dev br-rpi\n    #       ip -d link show dev br-rpi\n    #       ip route\n    # NB later, you can remove with:\n    #       ip link set dev br-rpi down\n    #       ip link delete dev br-rpi\n    br-rpi:\n      link-local: []\n      addresses:\n        - 10.3.0.1/24\n      interfaces:\n        - vlan.rpi\n  vlans:\n    vlan.wan:\n      id: 2\n      link: enp3s0\n      link-local: []\n      addresses:\n        - 192.168.1.1/24\n      gateway4: 192.168.1.254\n      nameservers:\n        addresses:\n          # cloudflare+apnic public dns resolvers.\n          # see https://en.wikipedia.org/wiki/1.1.1.1\n          - \"1.1.1.1\"\n          - \"1.0.0.1\"\n          # google public dns resolvers.\n          # see https://en.wikipedia.org/wiki/8.8.8.8\n          #- \"8.8.8.8\"\n          #- \"8.8.4.4\"\n    # NB this is equivalent of executing:\n    #       ip link add link enp3s0 vlan.rpi type vlan proto 802.1q id 2\n    #       ip link set dev vlan.rpi up\n    #       ip -d link show dev vlan.rpi\n    # NB later, you can remove with:\n    #       ip link set dev vlan.rpi down\n    #       ip link delete dev vlan.rpi\n    vlan.rpi:\n      id: 3\n      link: enp3s0\n      link-local: []\n```\n\n**NB** For more information about VLANs see the [IEEE 802.1Q VLAN Tutorial](http://www.microhowto.info/tutorials/802.1q.html).\n\nBuild and install the [Ubuntu Linux vagrant box](https://github.com/rgl/ubuntu-vagrant).\n\nBuild [Debian OSIE](https://github.com/rgl/tinkerbell-debian-osie) in `../tinkerbell-debian-osie`.\n\nOptionally, build and install the following vagrant boxes (which must be using\nthe UEFI variant):\n\n* [Debian](https://github.com/rgl/debian-vagrant)\n* [Proxmox VE](https://github.com/rgl/proxmox-ve)\n* [Ubuntu](https://github.com/rgl/ubuntu-vagrant)\n* [Windows 2022](https://github.com/rgl/windows-vagrant)\n\nLogin into docker hub to have a [higher rate limits](https://www.docker.com/increase-rate-limits).\n\nLaunch the `provisioner` with:\n\n```bash\n# NB this takes about 30m in my machine. YMMV.\nvagrant up --no-destroy-on-error --no-tty provisioner\n```\n\nEnter the `provisioner` machine, and tail the relevant logs with:\n\n```bash\nvagrant ssh provisioner\nsudo -i\ncd ~/tinkerbell-sandbox/deploy/compose\ndocker compose logs --follow tink-server boots nginx\n```\n\nIn another terminal, launch the `uefi` worker machine with:\n\n```bash\nvagrant up --no-destroy-on-error --no-tty uefi\n```\n\nIn another terminal, watch the workflow progress with:\n\n```bash\nvagrant ssh provisioner\nsudo -i\nwatch-hardware-workflows uefi\n```\n\nYou should eventually see something alike:\n\n```\n+----------------------+--------------------------------------+\n| FIELD NAME           | VALUES                               |\n+----------------------+--------------------------------------+\n| Workflow ID          | dc2ff4c3-13b1-11ec-a4c5-0242ac1a0004 |\n| Workflow Progress    | 100%                                 |\n| Current Task         | hello-world                          |\n| Current Action       | info                                 |\n| Current Worker       | 00000000-0000-4000-8000-080027000001 |\n| Current Action State | STATE_SUCCESS                        |\n+----------------------+--------------------------------------+\n+--------------------------------------+-------------+-------------+----------------+---------------------------------+---------------+\n| WORKER ID                            | TASK NAME   | ACTION NAME | EXECUTION TIME | MESSAGE                         | ACTION STATUS |\n+--------------------------------------+-------------+-------------+----------------+---------------------------------+---------------+\n| 00000000-0000-4000-8000-080027000001 | hello-world | hello-world |              0 | Started execution               | STATE_RUNNING |\n| 00000000-0000-4000-8000-080027000001 | hello-world | hello-world |              3 | finished execution successfully | STATE_SUCCESS |\n| 00000000-0000-4000-8000-080027000001 | hello-world | info        |              0 | Started execution               | STATE_RUNNING |\n| 00000000-0000-4000-8000-080027000001 | hello-world | info        |              0 | finished execution successfully | STATE_SUCCESS |\n+--------------------------------------+-------------+-------------+----------------+---------------------------------+---------------+\n```\n\n**NB** After a workflow action is executed, `tink-worker` will not re-execute it, even if you reboot the worker. You must create a new workflow, e.g. `provision-workflow hello-world uefi \u0026\u0026 watch-hardware-workflows uefi`.\n\nYou can see the worker and action logs from Grafana Explore (its address is displayed at the end of the provisioning).\n\nFrom within the worker machine, you can query the metadata endpoint:\n\n**NB** this endpoint returns the data set in the `TODO` field of the particular worker `hardware` document.\n\n```bash\nmetadata_url=\"$(cat /proc/cmdline | tr ' ' '\\n' | awk '/^tinkerbell=(.+)/{print \"$1:50061/metadata\"}')\"\nwget -qO- \"$metadata_url\"\n```\n\nThen repeat the process with the `uefi` worker machine.\n\nTo execute a more realistic workflow, you can install one of the following:\n\n```bash\nprovision-workflow debian        uefi \u0026\u0026 watch-hardware-workflows uefi\nprovision-workflow flatcar-linux uefi \u0026\u0026 watch-hardware-workflows uefi\nprovision-workflow proxmox-ve    uefi \u0026\u0026 watch-hardware-workflows uefi\nprovision-workflow ubuntu        uefi \u0026\u0026 watch-hardware-workflows uefi\nprovision-workflow windows-2022  uefi \u0026\u0026 watch-hardware-workflows uefi\n```\n\nSee which containers are running in the `provisioner` machine:\n\n```bash\nvagrant ssh provisioner\nsudo -i\n# see https://docs.docker.com/engine/reference/commandline/ps/#formatting\npython3 \u003c\u003c'EOF'\nimport io\nimport json\nimport subprocess\nfrom tabulate import tabulate\n\ndef info():\n  p = subprocess.Popen(\n    ('docker', 'ps', '-a', '--no-trunc', '--format', '{{.ID}}'),\n    stdout=subprocess.PIPE,\n    stderr=subprocess.STDOUT)\n  for id in (l.rstrip(\"\\r\\n\") for l in io.TextIOWrapper(p.stdout)):\n    p = subprocess.Popen(\n      ('docker', 'inspect', id),\n      stdout=subprocess.PIPE,\n      stderr=subprocess.STDOUT)\n    for c in json.load(p.stdout):\n      yield (c['Name'], c['Config']['Image'], c['Image'])\n\nprint(tabulate(sorted(info()), headers=('ContainerName', 'ImageName', 'ImageId')))\nEOF\n```\n\nAt the time of writing these were the containers running by default:\n\n```plain\nContainerName                        ImageName                                 ImageId\n-----------------------------------  ----------------------------------------  -----------------------------------------------------------------------\n/compose-boots-1                     10.3.0.2/debian-boots                     sha256:397e3206222130ada624953220e8cb38c66365a4e31df7ce808f639c9a141599\n/compose-db-1                        postgres:14-alpine                        sha256:eb82a397daaf176f244e990aa6f550422a764a88759f43e641c3a1323953deb7\n/compose-hegel-1                     quay.io/tinkerbell/hegel:sha-89cb9dc8     sha256:23c22f0bb8779fb4b0fdab8384937c54afbbed6b45aefb3554f2d54cb2c7cffa\n/compose-images-to-local-registry-1  quay.io/containers/skopeo:latest          sha256:9f5c670462ec0dc756fe52ec6c4d080f62c01a0003b982d48bb8218f877a456a\n/compose-osie-bootloader-1           nginx:alpine                              sha256:b46db85084b80a87b94cc930a74105b74763d0175e14f5913ea5b07c312870f8\n/compose-osie-work-1                 bash:4.4                                  sha256:bc8b0716d7386a05b5b3d04276cc7d8d608138be723fbefd834b5e75db6a6aeb\n/compose-registry-1                  registry:2.7.1                            sha256:b8604a3fe8543c9e6afc29550de05b36cd162a97aa9b2833864ea8a5be11f3e2\n/compose-registry-auth-1             httpd:2                                   sha256:ad17c88403e2cedd27963b98be7f04bd3f903dfa7490586de397d0404424936d\n/compose-tink-cli-1                  quay.io/tinkerbell/tink-cli:sha-3743d31e  sha256:8c90de15e97362a708cde2c59d3a261f73e3a4242583a54222b5e18d4070acaf\n/compose-tink-server-1               quay.io/tinkerbell/tink:sha-3743d31e      sha256:fb21c42c067588223b87a5c1f1d9b2892f863bfef29ce5fcd8ba755cfa0a990b\n/compose-tink-server-migration-1     quay.io/tinkerbell/tink:sha-3743d31e      sha256:fb21c42c067588223b87a5c1f1d9b2892f863bfef29ce5fcd8ba755cfa0a990b\n/compose-tls-gen-1                   cfssl/cfssl                               sha256:655abf144edde793a3ff1bc883cc82ca61411efb35d0d403a52f202c9c3cd377\n/compose_tls-gen_run_67135735bbb3    cfssl/cfssl                               sha256:655abf144edde793a3ff1bc883cc82ca61411efb35d0d403a52f202c9c3cd377\n/grafana                             grafana/grafana:8.2.5                     sha256:ddfae340d0681fe1a10582b06a2e8ae402196df9d429f0c1cefbe8dedca73cf0\n/loki                                grafana/loki:2.4.1                        sha256:e3e722f23de3fdbb8608dcf1f8824dec62cba65bbfd5ab5ad095eed2d7c5872a\n/meshcommander                       meshcommander                             sha256:aff2fc5004fb7f77b1a14a82c35af72e941fa33715e66c2eab5a5d253820d4bb\n/portainer                           portainer/portainer-ce:2.9.2              sha256:a1c22f3d250fda6b357aa7d2148dd333a698805dd2878a08eb8f055ca8fb4e99\n```\n\nThose containers were started with docker compose and you can use it to\ninspect the tinkerbell containers:\n\n```bash\nvagrant ssh provisioner\nsudo -i\ncd ~/tinkerbell-sandbox/deploy/compose\ndocker compose ps\ndocker compose logs -f\n```\n\nYou can also use the [Portainer](https://github.com/portainer/portainer)\napplication at the address that is displayed after the vagrant environment\nis launched (e.g. at `http://10.3.0.2:9000`).\n\n# Tinkerbell Debian OSIE\n\nThis vagrant environment uses the [Debian based OSIE](https://github.com/rgl/tinkerbell-debian-osie)\ninstead of the [LinuxKit (aka Hook) based OSIE](https://github.com/tinkerbell/hook).\n\nYou can login into it using the `osie` username and password.\n\n# Raspberry Pi\n\nInstall the RPI4-UEFI-IPXE firmware into a sd-card as described at\nhttps://github.com/rgl/rpi4-uefi-ipxe.\n\nInsert an external disk (e.g. an USB flash drive or USB SSD) to use as target on\nyour Tinkerbell Action.\n\n# Intel NUC\n\nYou can [use the Intel Integrator Toolkit ITK6.efi EFI application](https://downloadmirror.intel.com/29345/eng/Intel%20Integrator%20Toolkit%20User%20Guide.pdf) to set the SMBIOS properties.\n\n# Troubleshooting\n\n## Network Packet Capture\n\nYou can see all the network traffic from within the provisioner by running:\n\n```bash\nvagrant ssh-config provisioner \u003etmp/provisioner-ssh-config.conf\n# NB this ignores the following ports:\n#          22: SSH\n#       16992: AMT HTTP\n#       16994: AMT Redirection/TCP\n#        4000: MeshCommander\nwireshark -k -i \u003c(ssh -F tmp/provisioner-ssh-config.conf provisioner 'sudo tcpdump -s 0 -U -n -i eth1 -w - not tcp port 22 and not port 16992 and not port 16994 and not port 4000')\n```\n\nYou can also do it from the host by capturing traffic from the `br-rpi` or `vlan.rpi` interface.\n\n## Database\n\nTinkerbell uses the [tinkerbell](https://github.com/tinkerbell/tink/tree/main/db/migration)\nPostgreSQL database, you can access its console with, e.g.:\n\n```bash\nvagrant ssh provisioner\nsudo -i\ndocker exec -i compose-db-1 psql -U tinkerbell -c '\\dt'\ndocker exec -i compose-db-1 psql -U tinkerbell -c '\\d hardware'\ndocker exec -i compose-db-1 psql -U tinkerbell -c 'select * from template'\ndocker exec -i compose-db-1 psql -U tinkerbell -c 'select * from workflow'\ndocker exec -i compose-db-1 psql -U tinkerbell -c 'select * from workflow_event order by created_at desc'\n```\n\n# Notes\n\n* All workflow actions run as `--privileged` containers.\n\n# Reference\n\n* [IEEE 802.1Q VLAN Tutorial](http://www.microhowto.info/tutorials/802.1q.html)\n* [ContainerSolutions/tinkerbell-rpi4-workflow](https://github.com/ContainerSolutions/tinkerbell-rpi4-workflow/tree/rpi4-tinkerbell-uefi)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgl%2Ftinkerbell-vagrant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frgl%2Ftinkerbell-vagrant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgl%2Ftinkerbell-vagrant/lists"}