Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

models, sundog, prairiedog: add kernel boot config support #2029

Merged
merged 7 commits into from
May 16, 2022

Conversation

etungsten
Copy link
Contributor

@etungsten etungsten commented Mar 30, 2022

Issue number:
N/A

Description of changes:

    models: new boot settings to specify kernel boot config

    This adds `settings.boot` to help configure kernel boot config settings.
    prairiedog: add boot config functionality

     - Adds new subcommand `generate-boot-config` to generate an initrd
    image file with boot config contents populated from Bottlerocket boot
    settings.
     - Adds new subcommand `generate-boot-settings` to generate bottlerocket
    settings from kernel's bootconfig file at `/proc/bootconfig`

    Moves prairiedog from `sources/prairiedog` to `sources/api/prairiedog`
    now that it needs to query from the Bottlerocket API and need settings
    model information.
    sundog: update settings retrieval to use prefix

    This updates the settings retrieval to use prefixes for matching and
    querying. We cannot use full keys for matching because we now have
    settings generator for keys that map to top level structs that
    encompasses multiple settings.

    models: add metadata for 'settings.boot'

    Add settings generator for `settings.boot` and restart commands for when
    boot settings change.
    migrations: add migrations for new `settings.boot` setting
    README: add description and example for 'settings.boot'
    metal: remove kernel console settings from variant metadata

    We've added bootconfig support so console settings should be specified
    through there. The console settings specified to the kernel commandline
    will always take effect, so we're removing them from the variant
    metadata.

Testing done:
Launched instance with the following user-data:

[settings.boot]
kernel.test1 = ["bark", "barkbark"]
kernel.test2 = ["woof", "woofwoof"]
init.test1 = ["good", "morning"]
init.test2 = ["hello", "goodbye"]

Prairiedog successfully generates the initrd image file containing boot config:

[ec2-user@ip-192-168-10-10 ~]$ hexdump -C bootconfig.data
00000000  69 6e 69 74 2e 74 65 73  74 31 20 3d 20 22 67 6f  |init.test1 = "go|
00000010  6f 64 22 2c 20 22 6d 6f  72 6e 69 6e 67 22 0a 69  |od", "morning".i|
00000020  6e 69 74 2e 74 65 73 74  32 20 3d 20 22 68 65 6c  |nit.test2 = "hel|
00000030  6c 6f 22 2c 20 22 67 6f  6f 64 62 79 65 22 0a 6b  |lo", "goodbye".k|
00000040  65 72 6e 65 6c 2e 74 65  73 74 31 20 3d 20 22 62  |ernel.test1 = "b|
00000050  61 72 6b 22 2c 20 22 62  61 72 6b 62 61 72 6b 22  |ark", "barkbark"|
00000060  0a 6b 65 72 6e 65 6c 2e  74 65 73 74 32 20 3d 20  |.kernel.test2 = |
00000070  22 77 6f 6f 66 22 2c 20  22 77 6f 6f 66 77 6f 6f  |"woof", "woofwoo|
00000080  66 22 00 00 84 00 00 00  fb 29 00 00 23 42 4f 4f  |f".......)..#BOO|
00000090  54 43 4f 4e 46 49 47 0a                           |TCONFIG.|
00000098

Verified that it's a valid initrd image file with valid boot config content with the linux kernel's bootconfig tool:

$ linux/tools/bootconfig/bootconfig -l bootconfig.data
init.test1 = "good", "morning"
init.test2 = "hello", "goodbye"
kernel.test1 = "bark", "barkbark"
kernel.test2 = "woof", "woofwoof"
  • Integrated test on real bare-metal hosts with a provisioned boot config file

Built a metal-dev image and dd'd it to a baremetal server's /dev/sda.
I manually provisioned a bootconfig.data file that contained the following bootconfig:

$ ./bootconfig -l bootconfig.data
kernel.console = "tty0", "ttyS1,115200n8"
init.systemd.log_level = "debug"

and copied it into the BOTTLEROCKET-PRIVATE partition.
Then I booted the baremetal host from its harddrive.

Connected to the server's serial port over IP and saw that the host comes up successfully.
Checked settings and it's generated correctly from /proc/bootconfig:

[ec2-user@admin]$ apiclient get settings.boot
{
  "settings": {
    "boot": {
      "init": {
        "systemd.log_level": [
          "debug"
        ]
      },
      "kernel": {
        "console": [
          "tty0",
          "ttyS1,115200n8"
        ]
      }
    }
  }
}

If I check systemd, the log-level is correctly set to "debug"

bash-5.0# systemd-analyze get-log-level
debug

If I change the settings, /var/lib/bottlerocket/bootconfig.data gets updated as expected:

[ec2-user@admin]$ apiclient set --json '{"boot":{"kernel":{"console":["tty0","ttyS1,115200n8"]},"init":{"systemd.log_level":["info"]}}}'
[ec2-user@admin]$ cat /.bottlerocket/rootfs/var/lib/bottlerocket/bootconfig.data
init.systemd.log_level = "info"
kernel.console = "tty0", "ttyS1,115200n8"L#BOOTCONFIG

If I reboot, I can see that the systemd log-level gets updated to info as expected.

bash-5.0# cat /proc/bootconfig                                                                                                     
init.systemd.log_level = "info"                                                                                                    
kernel.console = "tty0", "ttyS1,115200n8"
                                                                              
bash-5.0# systemd-analyze get-log-level                                                                                            
info
  • Integrated test on real bare-metal hosts with a provisioned user-data.toml file

Built a metal-dev image and dd'd it to a baremetal server's /dev/sda.
I manually provisioned a user-data.toml file that looks like this:

bash-5.0# cat /var/lib/bottlerocket/user-data.toml 
[settings.boot.kernel]
"console" = ["tty0", "ttyS1,115200n8"]
[settings.boot.init]
"systemd.log_level" = ["debug"]

and copied it into the BOTTLEROCKET-PRIVATE partition.
Then I booted the baremetal host from its harddrive and everything comes up fine.

The generated bootconfig.data file is as expected:

[ec2-user@admin]$ hexdump -C /.bottlerocket/rootfs/var/lib/bottlerocket/bootconfig.data
00000000  69 6e 69 74 2e 73 79 73  74 65 6d 64 2e 6c 6f 67  |init.systemd.log|
00000010  5f 6c 65 76 65 6c 20 3d  20 22 64 65 62 75 67 22  |_level = "debug"|
00000020  0a 6b 65 72 6e 65 6c 2e  63 6f 6e 73 6f 6c 65 20  |.kernel.console |
00000030  3d 20 22 74 74 79 30 22  2c 20 22 74 74 79 53 31  |= "tty0", "ttyS1|
00000040  2c 31 31 35 32 30 30 6e  38 22 00 00 4c 00 00 00  |,115200n8"..L...|
00000050  08 18 00 00 23 42 4f 4f  54 43 4f 4e 46 49 47 0a  |....#BOOTCONFIG.|
00000060

If I reboot the host, then the bootconfig above gets loaded by the kernel as expected.

bash-5.0# cat /proc/cmdline                                                                                                        
console="tty0" console="ttyS1,115200n8" .....

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

@etungsten etungsten force-pushed the dasboot branch 3 times, most recently from 7ccdaea to f7ec398 Compare March 30, 2022 01:55
@etungsten etungsten changed the title models, prairiedog: add kernel boot config support for metal variants models, prairiedog: add kernel boot config support Mar 30, 2022
@zmrow zmrow requested review from zmrow and bcressey March 30, 2022 22:52
Copy link
Contributor

@webern webern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

Release.toml Show resolved Hide resolved
packages/os/Cargo.toml Show resolved Hide resolved
sources/models/src/aws-ecs-1/mod.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/de.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/ser.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/error.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Push above and below addresses @webern 's comments.

@etungsten etungsten force-pushed the dasboot branch 3 times, most recently from 5da3a56 to 7b67162 Compare April 6, 2022 23:02
@etungsten
Copy link
Contributor Author

Push above and below limits boot settings to bare metal variants only.

@etungsten
Copy link
Contributor Author

I need to figure out conditional compilation for certain parts of prairiedog that deals with boot settings that only exist for metal variants.

README.md Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/ser.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

Push above add conditional compilation for boot config related functionalities in prairedog.

sources/models/src/lib.rs Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/lib.rs Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
sources/api/prairiedog/README.md Outdated Show resolved Hide resolved
sources/api/prairiedog/build.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/mod.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

etungsten commented Apr 13, 2022

Push above and below and tries to address comments.

Unit tests all pass.

@etungsten etungsten force-pushed the dasboot branch 2 times, most recently from 8ec1969 to 974e101 Compare April 13, 2022 03:30
@etungsten
Copy link
Contributor Author

Push above simplifies padding calculation a bit and addresses some leftover comments.

@etungsten
Copy link
Contributor Author

Push above rebases onto develop to pull the grub changes.

@etungsten
Copy link
Contributor Author

Push above removes some extraneous comments and fixes a log message that was causing sundog to choke.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/main.rs Outdated Show resolved Hide resolved
sources/bootconfig/src/ser.rs Outdated Show resolved Hide resolved
sources/bootconfig/src/ser.rs Outdated Show resolved Hide resolved
sources/bootconfig/src/ser.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Show resolved Hide resolved
sources/bootconfig/src/de.rs Outdated Show resolved Hide resolved
@etungsten
Copy link
Contributor Author

etungsten commented May 12, 2022

Push above addresses @bcressey comments.

  • Removes the bootconfig serde implementation, the bootconfig crate is now gone.
  • Now parses and serializes bootconfig files in prairiedog directly to/from models::BootSettings without serde.

Tested all the changes and they still work as expected:

[erikson@admin]$ apiclient get settings.boot
{
  "settings": {
    "boot": {
      "init": {
        "systemd.log_level": [
          "debug"
        ]
      },
      "kernel": {
        "console": [
          "tty0",
          "ttyS1,115200n8"
        ]
      }
    }
  }
}
[erikson@admin]$ apiclient set --json '{"boot":{"kernel":{"console":["tty0","ttyS1,115200n8"]},"init":{"systemd.log_level":["info"]}}}'
[erikson@admin]$ sudo sheltie
bash-5.1# cat /var/lib/bottlerocket/bootconfig.data 
kernel.console = "tty0", "ttyS1,115200n8"
init.systemd.log_level = "info"
L#BOOTCONFIG

@etungsten
Copy link
Contributor Author

Push above does some minor refactoring and clean-up

@etungsten etungsten force-pushed the dasboot branch 3 times, most recently from 4d999cb to 1743393 Compare May 12, 2022 18:54
@etungsten
Copy link
Contributor Author

Push above fixes initrd generation that I missed in my initial testing.

Copy link
Contributor

@bcressey bcressey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me except for some fussing about single- and double quotes.

sources/api/prairiedog/src/main.rs Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Outdated Show resolved Hide resolved
sources/models/src/modeled_types/shared.rs Outdated Show resolved Hide resolved
sources/api/prairiedog/src/bootconfig.rs Show resolved Hide resolved
This adds `settings.boot` to help configure kernel boot config settings.
 - Adds new subcommand `generate-boot-config` to generate an initrd
image file with boot config contents populated from Bottlerocket boot
settings.
 - Adds new subcommand `generate-boot-settings` to generate bottlerocket
settings from kernel's bootconfig file at `/proc/bootconfig`

Moves prairiedog from `sources/prairiedog` to `sources/api/prairiedog`
now that it needs to query from the Bottlerocket API and need settings
model information.
This updates the settings retrieval to use prefixes for matching and
querying. We cannot use full keys for matching because we now have
settings generator for keys that map to top level structs that
encompasses multiple settings.
Add settings generator for `settings.boot` and restart commands for when
boot settings change.
We've added bootconfig support so console settings should be specified
through there. The console settings specified to the kernel commandline
will always take effect, so we're removing them from the variant
metadata.
@etungsten
Copy link
Contributor Author

etungsten commented May 13, 2022

Pushes above addresses @bcressey 's comments.

  • prairiedog will now error when parsing boot config files that have kernel and init as parent keys to a list of non-null values. This is disallowed since BootSettings model does not support it.
  • BootConfigValue now rejects value strings that mix and contain both single quotes and double quotes. Quotes cannot be escaped in boot config values.

@etungsten etungsten requested a review from bcressey May 13, 2022 00:20
Copy link
Contributor

@bcressey bcressey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

👢 🔧

Copy link
Contributor

@zmrow zmrow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐙

Nice work!

@etungsten etungsten merged commit e49fb60 into bottlerocket-os:develop May 16, 2022
@etungsten etungsten deleted the dasboot branch May 16, 2022 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants