Skip to content

Commit 649b11a

Browse files
committed
update and migrator: signed migrations
1 parent 9a17514 commit 649b11a

20 files changed

+656
-348
lines changed

packages/os/migrator.service

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Description=Bottlerocket data store migrator
33

44
[Service]
55
Type=oneshot
6-
ExecStart=/usr/bin/migrator --datastore-path /var/lib/bottlerocket/datastore/current --migration-directories /var/lib/bottlerocket-migrations --migrate-to-version-from-os-release
6+
ExecStart=/usr/bin/migrator --datastore-path /var/lib/bottlerocket/datastore/current --migration-directory /var/lib/bottlerocket-migrations --root-path /usr/share/updog/root.json --metadata-directory /var/cache/bottlerocket-metadata --migrate-to-version-from-os-release
77
RemainAfterExit=true
88
StandardError=journal+console
99

sources/Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sources/api/migration/migrator/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@ semver = "0.9"
1818
simplelog = "0.7"
1919
snafu = "0.6"
2020
update_metadata = { path = "../../../updater/update_metadata" }
21+
tempfile = "3.1.0"
22+
tough = { version = "0.5.0" }
23+
lz4 = "1.23.1"
2124

2225
[build-dependencies]
2326
cargo-readme = "3.1"
2427

28+
[dev-dependencies]
29+
tempfile = "3.1"
30+
2531
[[bin]]
2632
name = "migrator"
2733
path = "src/main.rs"

sources/api/migration/migrator/src/args.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ fn usage() -> ! {
1515
eprintln!(
1616
r"Usage: {}
1717
--datastore-path PATH
18-
--migration-directories PATH[:PATH:PATH...]
18+
--migration-directory PATH
19+
--root-path PATH
20+
--metadata-directory PATH
21+
--working-directory PATH
1922
(--migrate-to-version x.y | --migrate-to-version-from-os-release)
2023
[ --no-color ]
2124
[ --log-level trace|debug|info|warn|error ]",
@@ -34,8 +37,10 @@ fn usage_msg<S: AsRef<str>>(msg: S) -> ! {
3437
pub(crate) struct Args {
3538
pub(crate) datastore_path: PathBuf,
3639
pub(crate) log_level: LevelFilter,
37-
pub(crate) migration_directories: Vec<PathBuf>,
40+
pub(crate) migration_directory: PathBuf,
3841
pub(crate) migrate_to_version: Version,
42+
pub(crate) root_path: PathBuf,
43+
pub(crate) metadata_directory: PathBuf,
3944
}
4045

4146
impl Args {
@@ -44,8 +49,10 @@ impl Args {
4449
// Required parameters.
4550
let mut datastore_path = None;
4651
let mut log_level = None;
47-
let mut migration_directories = None;
52+
let mut migration_directory = None;
4853
let mut migrate_to_version = None;
54+
let mut root_path = None;
55+
let mut metadata_path = None;
4956

5057
let mut iter = args.skip(1);
5158
while let Some(arg) = iter.next() {
@@ -84,16 +91,12 @@ impl Args {
8491
}));
8592
}
8693

87-
"--migration-directories" => {
88-
let paths_str = iter.next().unwrap_or_else(|| {
89-
usage_msg("Did not give argument to --migration-directories")
94+
"--migration-directory" => {
95+
let path_str = iter.next().unwrap_or_else(|| {
96+
usage_msg("Did not give argument to --migration-directory")
9097
});
91-
trace!("Given --migration-directories: {}", paths_str);
92-
let paths: Vec<_> = paths_str.split(':').map(PathBuf::from).collect();
93-
if paths.is_empty() {
94-
usage_msg("Found no paths in argument to --migration-directories");
95-
}
96-
migration_directories = Some(paths);
98+
trace!("Given --migration-directory: {}", path_str);
99+
migration_directory = Some(PathBuf::from(path_str));
97100
}
98101

99102
"--migrate-to-version" => {
@@ -114,15 +117,36 @@ impl Args {
114117
migrate_to_version = Some(br.version_id)
115118
}
116119

117-
_ => usage(),
120+
"--root-path" => {
121+
let path_str = iter
122+
.next()
123+
.unwrap_or_else(|| usage_msg("Did not give argument to --root-path"));
124+
trace!("Given --root-path: {}", path_str);
125+
root_path = Some(PathBuf::from(path_str));
126+
}
127+
128+
"--metadata-directory" => {
129+
let path_str = iter.next().unwrap_or_else(|| {
130+
usage_msg("Did not give argument to --metadata-directory")
131+
});
132+
trace!("Given --metadata-directory: {}", path_str);
133+
metadata_path = Some(PathBuf::from(path_str));
134+
}
135+
_ => usage_msg(format!("Unable to parse input '{}'", arg)),
118136
}
119137
}
120138

121139
Self {
122-
datastore_path: datastore_path.unwrap_or_else(|| usage()),
140+
datastore_path: datastore_path
141+
.unwrap_or_else(|| usage_msg("--datastore_path is empty")),
123142
log_level: log_level.unwrap_or_else(|| LevelFilter::Info),
124-
migration_directories: migration_directories.unwrap_or_else(|| usage()),
125-
migrate_to_version: migrate_to_version.unwrap_or_else(|| usage()),
143+
migration_directory: migration_directory
144+
.unwrap_or_else(|| usage_msg("--migration_directory is empty")),
145+
migrate_to_version: migrate_to_version
146+
.unwrap_or_else(|| usage_msg("--migrate_to_version is empty")),
147+
root_path: root_path.unwrap_or_else(|| usage_msg("--root_path is empty")),
148+
metadata_directory: metadata_path
149+
.unwrap_or_else(|| usage_msg("--metadata_directory is empty")),
126150
}
127151
}
128152
}

sources/api/migration/migrator/src/error.rs

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! This module owns the error type used by the migrator.
22
33
use semver::Version;
4-
use snafu::Snafu;
4+
use snafu::{Backtrace, Snafu};
55
use std::io;
66
use std::path::PathBuf;
77
use std::process::{Command, Output};
@@ -13,6 +13,12 @@ pub(crate) enum Error {
1313
#[snafu(display("Internal error: {}", msg))]
1414
Internal { msg: String },
1515

16+
#[snafu(display("Unable to create tempdir for migration binaries: '{}'", source))]
17+
CreateRunDir { source: std::io::Error },
18+
19+
#[snafu(display("Unable to create tempdir for tough datastore: '{}'", source))]
20+
CreateToughTempDir { source: std::io::Error },
21+
1622
#[snafu(display("Data store path '{}' contains invalid UTF-8", path.display()))]
1723
DataStorePathNotUTF8 { path: PathBuf },
1824

@@ -22,6 +28,21 @@ pub(crate) enum Error {
2228
#[snafu(display("Data store link '{}' points to /", path.display()))]
2329
DataStoreLinkToRoot { path: PathBuf },
2430

31+
#[snafu(display("Unable to delete directory '{}': {}", path.display(), source))]
32+
DeleteDirectory {
33+
path: PathBuf,
34+
source: std::io::Error,
35+
},
36+
37+
#[snafu(display("Failed to convert '{}' to a URL", path.display()))]
38+
DirectoryUrl { path: PathBuf, backtrace: Backtrace },
39+
40+
#[snafu(display("Error finding migration: {}", source))]
41+
FindMigrations {
42+
source: update_metadata::error::Error,
43+
backtrace: Backtrace,
44+
},
45+
2546
#[snafu(display("Data store path '{}' contains invalid version: {}", path.display(), source))]
2647
InvalidDataStoreVersion {
2748
path: PathBuf,
@@ -59,9 +80,58 @@ pub(crate) enum Error {
5980
#[snafu(display("Failed listing migration directory '{}': {}", dir.display(), source))]
6081
ListMigrations { dir: PathBuf, source: io::Error },
6182

83+
#[snafu(display("Error loading manifest: {}", source))]
84+
LoadManifest {
85+
source: update_metadata::error::Error,
86+
backtrace: Backtrace,
87+
},
88+
89+
#[snafu(display("Error loading migration '{}': {}", migration, source))]
90+
LoadMigration {
91+
migration: String,
92+
source: tough::error::Error,
93+
backtrace: Backtrace,
94+
},
95+
96+
#[snafu(display("Failed to decode LZ4-compressed migration {}: {}", migration, source))]
97+
Lz4Decode {
98+
migration: String,
99+
source: std::io::Error,
100+
backtrace: Backtrace,
101+
},
102+
103+
#[snafu(display("Migration '{}' not found", migration))]
104+
MigrationNotFound {
105+
migration: String,
106+
backtrace: Backtrace,
107+
},
108+
109+
#[snafu(display("Error saving migration '{}': {}", path.display(), source))]
110+
MigrationSave {
111+
path: PathBuf,
112+
source: std::io::Error,
113+
backtrace: Backtrace,
114+
},
115+
116+
#[snafu(display("Failed to open trusted root metadata file {}: {}", path.display(), source))]
117+
OpenRoot {
118+
path: PathBuf,
119+
source: std::io::Error,
120+
backtrace: Backtrace,
121+
},
122+
123+
#[snafu(display("Unable to create URL from path '{}'", path.display()))]
124+
PathUrl { path: PathBuf, backtrace: Backtrace },
125+
62126
#[snafu(display("Failed reading migration directory entry: {}", source))]
63127
ReadMigrationEntry { source: io::Error },
64128

129+
#[snafu(display("Failed to load TUF repo: {}", source))]
130+
RepoLoad {
131+
source: tough::error::Error,
132+
backtrace: Backtrace,
133+
},
134+
65135
#[snafu(display("Failed reading metadata of '{}': {}", path.display(), source))]
66136
PathMetadata { path: PathBuf, source: io::Error },
67137

@@ -70,9 +140,6 @@ pub(crate) enum Error {
70140

71141
#[snafu(display("Migration path '{}' contains invalid UTF-8", path.display()))]
72142
MigrationNameNotUTF8 { path: PathBuf },
73-
74-
#[snafu(display("Logger setup error: {}", source))]
75-
Logger { source: simplelog::TermLogError },
76143
}
77144

78145
/// Result alias containing our Error type.

0 commit comments

Comments
 (0)