Giter Club home page Giter Club logo

goldboot's Introduction


Normal people don't reinstall their OS from scratch very often. When they do, the moment they reach that pristine desktop or terminal after a clean installation, all hell breaks loose. Settings get changed, applications are installed, bloatware is removed, files get downloaded here and there. The system is generally altered from its original state into a new "customized" state by a manual flurry of mouse clicks and key presses.

If you think about your system like a server, this approach is called mutable infrastructure, meaning you mutate the state of your system repeatedly until it eventually suits your needs. And when something goes awry, you have to make the necessary changes to get it back in line.

For normal people, mutable infrastructure works out fine until something major breaks or they have to migrate to a new computer altogether. In these cases, they probably end up starting over from scratch and have to reapply their changes again (and probably differently this time).

Slightly less normal people might have scripts or even use a configuration management tool like Ansible or Puppet to automate all of those customizations. This is great, but you can't start at a boot prompt and immediately run an Ansible playbook. Something (or someone) has to install the OS before the automation can be "kicked off". Also, configuration management tools have limited scope.

Truly sophisticated computer elites practice immutable infrastructure. Meaning that, every time they boot their system, its state begins identically to the time before. Any changes that are made during the course of runtime vanish on reboot. This approach has some real benefits, but requires quite a bit of effort from the user.

If you're looking to achieve something close to immutable infrastructure without creating a lot of extra work for yourself, you've come to the right place.

In the goldboot approach, you choose a starting template containing an absolutely minimal install of your favorite OS. Then you create provisioners which are the scripts that add all of your customizations on top of the template. From these pieces, goldboot builds a machine image ready to be deployed to real hardware.

Warning: this tool is totally unfinshed and should be used for testing only! Proceed at your own risk!


License build Discord Lines of code Stars

If computer programs could reproduce sexually, goldboot is what you would get if docker and packer were mixed together.

More practically, goldboot is a command-line tool that builds machine images for real hardware instead of containers or virtual machines.

These machine images (also known as golden images) contain your operating system(s), applications, software patches, and configuration all rolled into one easily deployable package.

Like Docker images, your goldboot images can be stored in a registry and pulled onto real hardware.

Examples

The goldboot-examples repo contains example configurations of all supported OS types and system architectures. They are built on a weekly schedule against the latest version of goldboot.

Linux Windows macos
Alpine x86_64 Windows 10 x86_64 macOS x86_64
Arch Linux x86_64
Debian x86_64
Pop!_OS x86_64
Steam Deck x86_64
Steam OS x86_64

Installation

Docker

Docker Pulls Docker Image Size Docker Stars

Install from DockerHub

alias goldboot="docker run --rm -v .:/root fossable/goldboot"
Crates.io

Crates.io Total Downloads

Install from crates.io

cargo install goldboot
Arch Linux

AUR Votes AUR Version AUR Last Modified

Install from the AUR

  cd /tmp
  curl https://aur.archlinux.org/cgit/aur.git/snapshot/goldboot.tar.gz | tar xf -
  makepkg -si
Github Actions

Running on Github actions

Building golden images with CI is common practice, so there's also a Github action to make it easy:

steps:
  - name: Checkout
    uses: actions/checkout@v4

  - name: Build goldboot image
    uses: fossable/goldboot-action@main
    with:
      config-path: goldboot.json
      output-path: image.gb

  - name: Save image artifact
    uses: actions/upload-artifact@v3
    with:
      name: my_image.gb
      path: image.gb

Your first golden image

Let's build a basic Arch Linux image to prove we're real Linux users.

First, create a directory to hold our configuration (which can later be tracked in version control):

mkdir Test && cd Test

Initialize the directory and choose ArchLinux to start with:

goldboot init \
  --name Test \
  --mold ArchLinux \
  --size 10G \
  --format json

This will create goldboot.json which contains configuration options that can be tweaked to suit your needs. For example:

{
  "alloy": [
    {
      "mold": {
        "ArchLinux": {
          "hostname": "YeahIUseArch",
          "root_password": {
            "plaintext": "123456"
          }
        }
      },
      "source": {
        "Iso": {
          "url": "https://mirrors.edge.kernel.org/archlinux/iso/2024.01.01/archlinux-2024.01.01-x86_64.iso",
          "checksum": "sha256:12addd7d4154df1caf5f258b80ad72e7a724d33e75e6c2e6adc1475298d47155"
        }
      }
    }
  ],
  "arch": "Amd64",
  "name": "Test",
  "size": "10G"
}

There are many ways to customize the image, but for now just build it:

goldboot build .

Once the build succeeds, the image will be saved to the system's library directory. To deploy it to a physical disk, you can use a bootable USB drive:

# THIS WILL OVERWRITE /dev/sdX!
goldboot make_usb --output /dev/sdX --include Test

Once the USB is created, you can use it to boot into the goldboot live environment and select an image to write:

Once the image has been applied, remove the bootable USB drive and reboot the machine.

goldboot's People

Contributors

cilki avatar dependabot[bot] avatar github-actions[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

goldboot's Issues

Add multiboot images

It should be possible to support multiboot images (multiple operating systems in one image) by running the regular build process on each template in parallel and then merging the results into a final image.

The trick will be how to create a new EFI partition based on the originals. Merging those partitions might be complicated, so it may be best to just preserve them and chainload from GRUB.

Add PXE support

In order to enable PXE booting, the user would need to also add the goldboot registry's IP to their DHCP server.

When enabled, the registry will:

  • Start a TFTP listener on 69/UDP
  • Send a specialized goldboot linux image wrapped in an EFI binary
    • According to the requestor's MAC address, the goldboot linux image automatically pulls the appropriate public image and applies it

Add generic template

It would be useful to have a base template that does nothing and allows a user to configure things like the boot command manually.

Finalize configuration format

The main bottleneck here is finishing the config format which is a critical component that everything else depends. It's user-facing, so it should be both intuitive and stable.

Some required features:

  • Support multiboot images
  • Flexible enough to conveniently support any kind of operating system
  • Support custom provisioners for certain operating systems (MirrorlistProvisioner for certain Linux distributions, for example)
  • JSON, YAML, and maybe even TOML
  • Documentation can be generated from Rust structs

This format is what I was working towards previously, but I think there's still room for improvement:

{
  "name": "ArchLinux",
  "arch": "x86_64",
  "templates": [
    {
      "base": "ArchLinux",
      "iso_checksum": "sha1:3700a16d4fcabbd29e9a7fbc97da732c4577dc2a",
      "iso_url": "https://mirrors.edge.kernel.org/archlinux/iso/latest/archlinux-2022.05.01-x86_64.iso",
      "mirrorlist": [
        "https://mirrors.edge.kernel.org/archlinux/$repo/os/$arch"
      ],
      "root_password": "root",
      "storage_size": "4Gb",
      "provisioners": [
        {
          "type": "ansible",
          "playbook": "ansible.yml"
        }
      ]
    }
  ]
}

Since the above isn't fully implemented yet, there's still time to pivot onto a slightly better path if there is one.

Unable to compile on macOS

Hi, apologies if the cause is user error, but I wanted to try out this project but was unable to compile it on latest macOS.|

I made sure to install gtk4 via brew.

โžœ  goldboot git:(master) rustc --version
rustc 1.73.0 (cc66ad468 2023-10-03)
โžœ  goldboot git:(master) cargo build
warning: some crates are on edition 2021 which defaults to `resolver = "2"`, but virtual workspaces default to `resolver = "1"`
note: to keep the current resolver, specify `workspace.resolver = "1"` in the workspace root's manifest
note: to use the edition 2021 resolver, specify `workspace.resolver = "2"` in the workspace root's manifest
   Compiling gdk-pixbuf-sys v0.18.0
   Compiling cairo-sys-rs v0.18.2
   Compiling pango-sys v0.18.0
   Compiling gobject-sys v0.18.0
   Compiling graphene-sys v0.18.1
   Compiling gdk4-sys v0.7.2
   Compiling libssh2-sys v0.3.0
   Compiling openssl-sys v0.9.95
   Compiling gsk4-sys v0.7.3
   Compiling gtk4-sys v0.7.3
   Compiling rustls-webpki v0.101.7
   Compiling sct v0.7.1
   Compiling gio-sys v0.18.1
   Compiling rustls v0.21.8
   Compiling glib v0.18.3
   Compiling ssh2 v0.9.4
   Compiling goldboot v0.0.1 (/Users/vdmkenny/goldboot/goldboot)
error[E0432]: unresolved import `crate::cache::MediaFormat`
 --> goldboot/src/templates/linux/arch.rs:3:25
  |
3 |     cache::{MediaCache, MediaFormat},
  |                         ^^^^^^^^^^^ no `MediaFormat` in `cache`

error[E0432]: unresolved import `crate::cache::MediaFormat`
 --> goldboot/src/templates/linux/ubuntu.rs:3:25
  |
3 |     cache::{MediaCache, MediaFormat},
  |                         ^^^^^^^^^^^ no `MediaFormat` in `cache`

error[E0432]: unresolved import `crate::templates::TemplateId`
 --> goldboot/src/cmd/init.rs:4:27
  |
4 |     templates::{Template, TemplateId},
  |                           ^^^^^^^^^^
  |                           |
  |                           no `TemplateId` in `templates`
  |                           help: a similar name exists in the module: `Template`

error[E0433]: failed to resolve: could not find `debian` in `linux`
   --> goldboot/src/templates/mod.rs:202:49
    |
202 |             Template::Debian => Box::new(linux::debian::DebianTemplate::default()),
    |                                                 ^^^^^^ could not find `debian` in `linux`

error[E0433]: failed to resolve: could not find `goldboot` in `linux`
   --> goldboot/src/templates/mod.rs:207:51
    |
207 |             Template::Goldboot => Box::new(linux::goldboot::GoldbootTemplate::default()),
    |                                                   ^^^^^^^^ could not find `goldboot` in `linux`

error[E0433]: failed to resolve: use of undeclared crate or module `macos`
   --> goldboot/src/templates/mod.rs:211:41
    |
211 |             Template::MacOs => Box::new(macos::mac_os::MacOsTemplate::default()),
    |                                         ^^^^^ use of undeclared crate or module `macos`

error[E0433]: failed to resolve: could not find `pop_os` in `linux`
   --> goldboot/src/templates/mod.rs:219:48
    |
219 |             Template::PopOs => Box::new(linux::pop_os::PopOsTemplate::default()),
    |                                                ^^^^^^ could not find `pop_os` in `linux`

error[E0433]: failed to resolve: could not find `steam_deck` in `linux`
   --> goldboot/src/templates/mod.rs:224:52
    |
224 |             Template::SteamDeck => Box::new(linux::steam_deck::SteamDeckTemplate::default()),
    |                                                    ^^^^^^^^^^ could not find `steam_deck` in `linux`

error[E0433]: failed to resolve: could not find `steam_os` in `linux`
   --> goldboot/src/templates/mod.rs:225:50
    |
225 |             Template::SteamOs => Box::new(linux::steam_os::SteamOsTemplate::default()),
    |                                                  ^^^^^^^^ could not find `steam_os` in `linux`

error[E0433]: failed to resolve: use of undeclared crate or module `windows`
   --> goldboot/src/templates/mod.rs:230:45
    |
230 |             Template::Windows10 => Box::new(windows::windows_10::Windows10Template::default()),
    |                                             ^^^^^^^ use of undeclared crate or module `windows`

error[E0404]: expected trait, found enum `Template`
  --> goldboot/src/build.rs:51:55
   |
51 |     pub fn get_templates(&self) -> Result<Vec<Box<dyn Template>>, Box<dyn Error>> {
   |                                                       ^^^^^^^^ not a trait

error[E0404]: expected trait, found enum `Template`
  --> goldboot/src/build.rs:52:40
   |
52 |         let mut templates: Vec<Box<dyn Template>> = Vec::new();
   |                                        ^^^^^^^^ not a trait

error[E0412]: cannot find type `TemplateBase` in this scope
  --> goldboot/src/build.rs:56:20
   |
56 |             let t: TemplateBase = serde_json::from_value(template.to_owned())?;
   |                    ^^^^^^^^^^^^ help: an enum with a similar name exists: `Template`
   |
  ::: goldboot/src/templates/mod.rs:20:1
   |
20 | pub enum Template {
   | ----------------- similarly named enum `Template` defined here

error[E0404]: expected trait, found enum `Template`
   --> goldboot/src/build.rs:119:44
    |
119 |     fn new_worker(&self, template: Box<dyn Template>) -> Result<BuildWorker, Box<dyn Error>> {
    |                                            ^^^^^^^^ not a trait

error[E0404]: expected trait, found enum `Template`
   --> goldboot/src/build.rs:261:27
    |
261 |     pub template: Box<dyn Template>,
    |                           ^^^^^^^^ not a trait

error[E0412]: cannot find type `TemplateMetadata` in this scope
   --> goldboot/src/cmd/init.rs:110:40
    |
110 |                     let templates: Vec<TemplateMetadata> = TemplateMetadata::load()
    |                                        ^^^^^^^^^^^^^^^^ not found in this scope
    |
help: you might be missing a type parameter
    |
30  | pub fn run<TemplateMetadata>(cmd: crate::cmd::Commands) -> Result<(), Box<dyn Error>> {
    |           ++++++++++++++++++

error[E0425]: cannot find function `to_vec` in crate `toml`
   --> goldboot/src/image.rs:502:38
    |
502 |             let config_bytes = toml::to_vec(&config)?;
    |                                      ^^^^^^ not found in `toml`
    |
help: consider importing this function
    |
1   + use serde_json::to_vec;
    |
help: if you import `to_vec`, refer to it directly
    |
502 -             let config_bytes = toml::to_vec(&config)?;
502 +             let config_bytes = to_vec(&config)?;
    |

error[E0412]: cannot find type `IsoSource` in this scope
  --> goldboot/src/templates/linux/arch.rs:28:9
   |
28 |     Iso(IsoSource),
   |         ^^^^^^^^^ not found in this scope
   |
help: consider importing this struct
   |
1  + use crate::sources::IsoSource;
   |

error[E0425]: cannot find value `MIRRORLIST` in this scope
   --> goldboot/src/templates/linux/arch.rs:154:25
    |
154 |                 .items(&MIRRORLIST)
    |                         ^^^^^^^^^^ not found in this scope

error[E0425]: cannot find value `MIRRORLIST` in this scope
   --> goldboot/src/templates/linux/arch.rs:157:33
    |
157 |             self.mirrors = vec![MIRRORLIST[mirror_index].to_string()];
    |                                 ^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type `IsoSource` in this scope
   --> goldboot/src/templates/linux/arch.rs:175:70
    |
175 | fn fetch_latest_iso(mirrorlist: ArchMirrorlistProvisioner) -> Result<IsoSource, Box<dyn Error>> {
    |                                                                      ^^^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
1   + use crate::sources::IsoSource;
    |

error[E0422]: cannot find struct, variant or union type `IsoSource` in this scope
   --> goldboot/src/templates/linux/arch.rs:183:35
    |
183 |                         return Ok(IsoSource {
    |                                   ^^^^^^^^^ not found in this scope
    |
help: consider importing this struct
    |
1   + use crate::sources::IsoSource;
    |

error[E0412]: cannot find type `IsoSource` in this scope
  --> goldboot/src/templates/linux/ubuntu.rs:58:9
   |
58 |     Iso(IsoSource),
   |         ^^^^^^^^^ not found in this scope
   |
help: consider importing this struct
   |
1  + use crate::sources::IsoSource;
   |

error[E0412]: cannot find type `HostnameProvisoner` in this scope
   --> goldboot/src/templates/linux/ubuntu.rs:63:14
    |
63  |     Hostname(HostnameProvisoner),
    |              ^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `HostnameProvisioner`
    |
   ::: goldboot/src/provisioners.rs:173:1
    |
173 | pub struct HostnameProvisioner {
    | ------------------------------ similarly named struct `HostnameProvisioner` defined here

error[E0404]: expected trait, found enum `Template`
  --> goldboot/src/templates/linux/ubuntu.rs:76:6
   |
76 | impl Template for UbuntuTemplate {
   |      ^^^^^^^^ not a trait

error[E0412]: cannot find type `GeneralContainer` in this scope
   --> goldboot/src/templates/linux/ubuntu.rs:109:26
    |
109 |     fn general(&self) -> GeneralContainer {
    |                          ^^^^^^^^^^^^^^^^ not found in this scope

error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Template::Alpine`
   --> goldboot/src/templates/mod.rs:155:13
    |
21  |     Alpine(templates::linux::alpine::AlpineTemplate),
    |     ------------------------------------------------ `Template::Alpine` defined here
...
155 |             Template::Alpine => false,
    |             ^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Template::Alpine(_)`

error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Template::Arch`
   --> goldboot/src/templates/mod.rs:156:13
    |
22  |     Arch(templates::linux::arch::ArchTemplate),
    |     ------------------------------------------ `Template::Arch` defined here
...
156 |             Template::Arch => false,
    |             ^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Template::Arch(_)`

error[E0404]: expected trait, found enum `Template`
   --> goldboot/src/templates/mod.rs:195:34
    |
195 |     pub fn new(&self) -> Box<dyn Template> {
    |                                  ^^^^^^^^ not a trait

error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Template::Alpine`
   --> goldboot/src/templates/mod.rs:197:13
    |
21  |     Alpine(templates::linux::alpine::AlpineTemplate),
    |     ------------------------------------------------ `Template::Alpine` defined here
...
197 |             Template::Alpine => Box::new(linux::alpine::AlpineTemplate::default()),
    |             ^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Template::Alpine(_)`

error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Template::Arch`
   --> goldboot/src/templates/mod.rs:198:13
    |
22  |     Arch(templates::linux::arch::ArchTemplate),
    |     ------------------------------------------ `Template::Arch` defined here
...
198 |             Template::Arch => Box::new(linux::arch::ArchTemplate::default()),
    |             ^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Template::Arch(_)`

warning: unused import: `info`
 --> goldboot/src/lib.rs:2:18
  |
2 | use log::{debug, info};
  |                  ^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `process::Command`
 --> goldboot/src/lib.rs:6:61
  |
6 | use std::{default::Default, error::Error, net::TcpListener, process::Command};
  |                                                             ^^^^^^^^^^^^^^^^

warning: unused import: `validator::Validate`
 --> goldboot/src/lib.rs:8:5
  |
8 | use validator::Validate;
  |     ^^^^^^^^^^^^^^^^^^^

warning: unused imports: `Read`, `Write`
 --> goldboot/src/cache.rs:9:10
  |
9 |     io::{Read, Write},
  |          ^^^^  ^^^^^

warning: unused import: `console::Style`
 --> goldboot/src/cmd/build.rs:5:5
  |
5 | use console::Style;
  |     ^^^^^^^^^^^^^^

warning: unused imports: `Confirm`, `Input`, `Select`, `theme::ColorfulTheme`
 --> goldboot/src/cmd/build.rs:6:17
  |
6 | use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
  |                 ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^  ^^^^^  ^^^^^^

warning: unused import: `console::Style`
 --> goldboot/src/cmd/image.rs:6:5
  |
6 | use console::Style;
  |     ^^^^^^^^^^^^^^

warning: unused imports: `Confirm`, `Input`, `Select`, `theme::ColorfulTheme`
 --> goldboot/src/cmd/image.rs:7:17
  |
7 | use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
  |                 ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^  ^^^^^  ^^^^^^

warning: unused import: `Template`
 --> goldboot/src/cmd/init.rs:4:17
  |
4 |     templates::{Template, TemplateId},
  |                 ^^^^^^^^

warning: unused imports: `Confirm`, `Select`
 --> goldboot/src/cmd/registry.rs:5:39
  |
5 | use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
  |                                       ^^^^^^^         ^^^^^^

warning: unused imports: `Input`, `Select`
 --> goldboot/src/cmd/write.rs:3:48
  |
3 | use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
  |                                                ^^^^^  ^^^^^^

warning: unused imports: `Deserialize`, `Serialize`
 --> goldboot/src/image.rs:7:13
  |
7 | use serde::{Deserialize, Serialize};
  |             ^^^^^^^^^^^  ^^^^^^^^^

warning: unused import: `validator::Validate`
  --> goldboot/src/image.rs:17:5
   |
17 | use validator::Validate;
   |     ^^^^^^^^^^^^^^^^^^^

warning: unused import: `debug`
 --> goldboot/src/provisioners.rs:9:11
  |
9 | use log::{debug, info};
  |           ^^^^^

warning: unused imports: `Display`, `EnumIter`
  --> goldboot/src/provisioners.rs:13:13
   |
13 | use strum::{Display, EnumIter};
   |             ^^^^^^^  ^^^^^^^^

warning: unused import: `path::Path`
 --> goldboot/src/templates/mod.rs:3:39
  |
3 | use std::{error::Error, fmt::Display, path::Path};
  |                                       ^^^^^^^^^^

warning: unused import: `cache::*`
 --> goldboot/src/templates/linux/alpine.rs:2:25
  |
2 |     build::BuildWorker, cache::*, provisioners::*, qemu::QemuArgs, sources::*, templates::*,
  |                         ^^^^^^^^

warning: use of deprecated unit variant `templates::linux::alpine::AlpineRelease::V3_14`
   --> goldboot/src/templates/linux/alpine.rs:159:5
    |
159 |     V3_14,
    |     ^^^^^
    |
    = note: `#[warn(deprecated)]` on by default

error[E0433]: failed to resolve: use of undeclared type `TemplateMetadata`
   --> goldboot/src/cmd/init.rs:110:60
    |
110 |                     let templates: Vec<TemplateMetadata> = TemplateMetadata::load()
    |                                                            ^^^^^^^^^^^^^^^^ use of undeclared type `TemplateMetadata`

Some errors have detailed explanations: E0404, E0412, E0422, E0425, E0432, E0433, E0532.
For more information about an error, try `rustc --explain E0404`.
warning: `goldboot` (lib) generated 18 warnings
error: could not compile `goldboot` (lib) due to 32 previous errors; 18 warnings emitted
warning: build failed, waiting for other jobs to finish...

Export to ISO9660

Because of how widespread the ISO9660 format is, it may be worthwhile to optionally allow exporting a bootable .iso instead of a regular .gb image. The main obstacle is goldboot works below the filesystem level, so copying the files manually would be really difficult (especially universally).

One alternative may be to utilize goldboot-linux virtually along with xorriso after the provisioning step. This is similar to how merging multiboot images is envisioned to work, so the necessary machinery may already be in place by the time I get to this issue. That would reduce the effort needed to just what's required to figure out the arcane xorriso arguments.

Test Steam Deck Image

goldboot init --profile SteamDeck
goldboot build

The above builds a stock Steam Deck image successfully, but I have no way to test it on real hardware yet (I'm far down on the waitlist). Looking for someone who doesn't mind wiping their Deck and trying this image.

Evolving golden images over time

Last year I asked someone who I think has a notably customized desktop setup, what they thought about goldboot's central concept (define your system declaratively and build golden images that can be deployed to bare metal).

The reply was that they prefer to setup their system from scratch because it's a forced opportunity to revisit past decisions and therefore make improvements. If all of that process is automated, then you end up with basically the same system over and over again.

Surely others share this perspective too, so we should think about how exactly to facilitate an image evolving over time through this lens. My opinion is that it's sort of like refining a piece of code: you make improvements to a particular section and then actually run it to see if the changes are good (in this analogy, "code changes" are like changing your goldboot config, and "running it" is like building a new image and trying it out).

To distill it down into a potentially simpler question: imagine your system is already defined as a goldboot config and have a CI pipeline outputting golden images. How do you improve that config over time?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.