diff --git a/.gitignore b/.gitignore index 4d173c5e73d92fd79d162b24d4f1e7e1a42b992b..0cac753eeb1da6376bc189165bca0c1a59c09325 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ target/ # KubeOS bin /bin + +# scripts-auto +/scripts-auto diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 0000000000000000000000000000000000000000..2af124fff5d4c6184b9f68260fa65da0307fa676 --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,6 @@ +[[rule]] + +[rule.formatting] +indent_string = " " +reorder_arrays = true +reorder_keys = true diff --git a/KubeOS-Rust/Cargo.lock b/KubeOS-Rust/Cargo.lock index 93e3d07d7e6bc4fc2ec18a2264510197c5699a3c..f79f79838947fba7fe8ec7adbacfbbbab94557ac 100644 --- a/KubeOS-Rust/Cargo.lock +++ b/KubeOS-Rust/Cargo.lock @@ -61,7 +61,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -72,7 +72,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -172,11 +172,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -184,7 +190,46 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_derive", + "clap_lex", + "indexmap 1.9.3", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -224,6 +269,31 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-common" version = "0.1.6" @@ -504,7 +574,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -632,6 +702,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -859,7 +935,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.51.1", ] [[package]] @@ -1067,6 +1143,21 @@ dependencies = [ "url", ] +[[package]] +name = "kbimg" +version = "1.0.5" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "log", + "nix 0.29.0", + "regex", + "serde", + "sysinfo", + "toml 0.7.6", +] + [[package]] name = "kube" version = "0.66.0" @@ -1178,9 +1269,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libredox" @@ -1234,7 +1325,7 @@ dependencies = [ "log", "mockall", "mockito", - "nix", + "nix 0.26.4", "predicates", "regex", "reqwest", @@ -1352,12 +1443,33 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "normalize-line-endings" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -1406,7 +1518,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -1448,11 +1560,17 @@ dependencies = [ "lazy_static", "log", "manager", - "nix", + "nix 0.26.4", "serde", "serde_json", ] +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "parity-tokio-ipc" version = "0.9.0" @@ -1524,7 +1642,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -1587,14 +1705,38 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -1632,9 +1774,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -1710,6 +1852,26 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1987,7 +2149,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -2013,6 +2175,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2129,9 +2300,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -2144,6 +2315,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sysinfo" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4115055da5f572fff541dd0c4e61b0262977f453cc9fe04be83aba25a89bdab" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -2194,24 +2379,30 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -2274,7 +2465,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -2371,6 +2562,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2455,7 +2680,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", ] [[package]] @@ -2589,7 +2814,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -2623,7 +2848,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2684,6 +2909,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.51.1" @@ -2693,6 +2928,49 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2708,7 +2986,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -2728,17 +3006,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2749,9 +3028,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2761,9 +3040,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2773,9 +3052,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2785,9 +3070,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2797,9 +3082,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2809,9 +3094,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2821,9 +3106,18 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] [[package]] name = "winreg" diff --git a/KubeOS-Rust/Cargo.toml b/KubeOS-Rust/Cargo.toml index 68ee670a026cabae220e87acf29c57b4c4506f8e..2886023f580ed89804e93a5c9c0b386e4374167d 100644 --- a/KubeOS-Rust/Cargo.toml +++ b/KubeOS-Rust/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["agent", "cli", "manager", "proxy"] +members = ["agent", "cli", "kbimg", "manager", "proxy"] resolver = "2" [profile.release] diff --git a/KubeOS-Rust/kbimg/Cargo.toml b/KubeOS-Rust/kbimg/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..99cdcfb0faab63b23bf5ca1a771f7b91b35a92b8 --- /dev/null +++ b/KubeOS-Rust/kbimg/Cargo.toml @@ -0,0 +1,17 @@ +[package] +description = "KubeOS kbimg" +edition = "2021" +license = "MulanPSL-2.0" +name = "kbimg" +version = "1.0.5" + +[dependencies] +anyhow = { version = "1.0" } +clap = { version = "=3.2.23", features = ["derive"] } +env_logger = { version = "0.9" } +log = { version = "= 0.4.15" } +nix = "0.29.0" +regex = { version = "1.7.3" } +serde = { version = "1.0", features = ["derive"] } +sysinfo = "0.31.2" +toml = { version = "=0.7.6" } diff --git a/KubeOS-Rust/kbimg/kbimg.toml b/KubeOS-Rust/kbimg/kbimg.toml new file mode 100644 index 0000000000000000000000000000000000000000..e5555ef099e7719920a5cb8f2bfb4dadfb0c704c --- /dev/null +++ b/KubeOS-Rust/kbimg/kbimg.toml @@ -0,0 +1,78 @@ +[from_repo] +agent_path = "/root/KubeOS/bin/os-agent" +image_type = "vm-repo" +legacy_bios = false +repo_path = "/etc/yum.repos.d/openEuler.repo" +root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" +version = "v1" +rpmlist = [ + "NetworkManager", + "conntrack-tools", + "containernetworking-plugins", + "coreutils", + "dhcp", + "docker", + "dosfstools", + "dracut", + "ebtables", + "ethtool", + "gawk", + "hwinfo", + "kernel", + "kubernetes-kubeadm", + "kubernetes-kubelet", + "lvm2", + "net-tools", + "openssh-server", + "passwd", + "parted", + "rsyslog", + "socat", + "sudo", + "vi", +] + +# [from_dockerimg] +# docker_img = "" +# image_type = "vm-docker" + +# [admin_container] +# dockerfile = "" +# docker_img = "" + +# [[users]] +# groups = ["admin"] +# name = "foo" +# passwd = "foo" +# sudo = "ALL=(ALL) ALL" + +# [[users]] +# groups = ["example"] +# name = "bar" +# passwd = "bar" + +# [[copy_files]] +# dst = "/root/ztest2" +# src = "/root/KubeOS/ztest2" + +# [[copy_files]] +# dst = "/root/ztest1" +# src = "/root/KubeOS/ztest1/*" + +# [grub] +# passwd = "foo" + +# [systemd_service] +# name = ["kubelet", "containerd"] + +# [chroot_script] +# path = "../../ztest/myscript.sh" + +# [disk_partition] +# first = 100 +# second = 2500 +# third = 2300 +# img_size = 30 + +# [persist_mkdir] +# name = ["lv_data"] diff --git a/KubeOS-Rust/kbimg/src/admin_container.rs b/KubeOS-Rust/kbimg/src/admin_container.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1e649167f62045dfa3a61ced205dc53fb8cf341 --- /dev/null +++ b/KubeOS-Rust/kbimg/src/admin_container.rs @@ -0,0 +1,66 @@ +use std::path::PathBuf; +use std::fs::{File, create_dir_all}; +use anyhow::bail; + +use crate::scripts_gen::*; +use crate::utils::{self, set_permissions}; +use crate::values::*; +use crate::{commands::AdminContainerInfo, Config, CreateImage}; + +impl CreateImage for AdminContainerInfo { + fn prepare(&self, _: &mut Config) -> anyhow::Result<()> { + let dockerfile = &self.dockerfile; + let image_name = &self.docker_img; + verify_admin_input(&dockerfile, &image_name)?; + check_dockerfile_valid(&dockerfile)?; + Ok(()) + } + + fn generate_scripts(&self, _: &Config) -> anyhow::Result { + // admin-container + match create_dir_all(ADMIN_CONTAINER_DIR) { + Ok(_) => { + // Dockerfile + let dockerfile_path = format!("{}/{}", ADMIN_CONTAINER_DIR, ADMIN_DOCKERFILE); + let mut dockerfile = File::create(&dockerfile_path)?; + gen_admin_dockerfile(&mut dockerfile)?; + set_permissions(&dockerfile_path, CONFIG_PERMISSION)?; + // set-ssh-pub-key.service + let set_ssh_pub_key_service_path = format!("{}/{}", ADMIN_CONTAINER_DIR, ADMIN_SET_SSH_PUB_KEY_SERVICE); + let mut set_ssh_pub_key_service = File::create(&set_ssh_pub_key_service_path)?; + gen_set_ssh_pub_key_service(&mut set_ssh_pub_key_service)?; + set_permissions(&set_ssh_pub_key_service_path, CONFIG_PERMISSION)?; + // set-ssh-pub-key.sh + let set_ssh_pub_key_path = format!("{}/{}", ADMIN_CONTAINER_DIR, ADMIN_SET_SSH_PUB_KEY_SH); + let mut set_ssh_pub_key = File::create(&set_ssh_pub_key_path)?; + gen_set_ssh_pub_key(&mut set_ssh_pub_key)?; + set_permissions(&set_ssh_pub_key_path, EXEC_PERMISSION)?; + }, + Err(e) => { + bail!(e); + } + } + // kbimg.sh + let kbimg_path = format!("{}/{}", SCRIPTS_DIR, KBIMG_SH); + let mut kbimg = File::create(&format!("{}/{}", SCRIPTS_DIR, KBIMG_SH))?; + gen_admin_vars(&mut kbimg, &self.docker_img, &self.dockerfile)?; + gen_create_admin_img(&mut kbimg)?; + set_permissions(&kbimg_path, EXEC_PERMISSION)?; + + Ok(PathBuf::from(&format!("{}/{}", SCRIPTS_DIR, KBIMG_SH))) + } +} + +fn verify_admin_input(dockerfile: &PathBuf, image_name: &str) -> anyhow::Result<()> { + if !utils::is_valid_param(dockerfile.to_str().unwrap()) { + bail!("params {} is invalid, please check input", dockerfile.to_str().unwrap()); + } + if !utils::is_valid_param(image_name) { + bail!("params {} is invalid, please check input", image_name); + } + Ok(()) +} + +fn check_dockerfile_valid(dockerfile: &PathBuf) -> anyhow::Result<()> { + utils::is_file_valid("admin-container Dockerfile", dockerfile) +} \ No newline at end of file diff --git a/KubeOS-Rust/kbimg/src/commands.rs b/KubeOS-Rust/kbimg/src/commands.rs new file mode 100644 index 0000000000000000000000000000000000000000..7db829c3ed7d7c3553f726c35ed4deb161908af6 --- /dev/null +++ b/KubeOS-Rust/kbimg/src/commands.rs @@ -0,0 +1,173 @@ +use std::path::PathBuf; + +use clap::{Args, Parser, Subcommand}; +use serde::Deserialize; + +use crate::values::{DISK, LOCAL_IP, NETMASK, NET_NAME, ROOTFS_NAME, ROUTE_IP, SERVER_IP}; + +#[derive(Parser)] +#[clap(name = "kbimg")] +#[clap(author, version, about)] +#[clap(long_about = "A tool for creating KubeOS images.")] +pub struct Cli { + /// Path to the detailed configuration toml file + #[clap(short, long, value_parser)] + pub config: Option, + /// Enable debug mode, keep the scripts after execution + #[clap(short, long, action)] + pub debug: bool, + #[clap(subcommand)] + pub commands: Option, +} + +#[derive(Subcommand, Debug, Deserialize)] +pub enum Commands { + /// Create a new container image for upgrading KubeOS + #[clap(name = "upgrade")] + UpgradeImage(RepoInfo), + /// Create a new KubeOS vm image from repo + #[clap(name = "vm-repo")] + VMRepo(RepoInfo), + /// Create a new KubeOS vm image from docker image + #[clap(name = "vm-docker")] + VMDocker(DockerInfo), + /// Create a new KubeOS pxe image from repo + #[clap(name = "pxe-repo")] + PxeRepo(RepoInfo), + /// Create a new KubeOS pxe image from docker image + #[clap(name = "pxe-docker")] + PxeDocker(DockerInfo), + /// Create a KubeOS admin-container image + #[clap(name = "admin-container")] + AdminContainer(AdminContainerInfo), +} + +#[derive(Args, Debug, Deserialize, Clone)] +pub struct RepoInfo { + /// Required: KubeOS version + #[clap(short, long, value_parser)] + pub version: String, + /// Required: Repo path for installing packages + #[clap(short = 'p', long, value_parser)] + pub repo_path: PathBuf, + /// Required: Path to the agent binary + #[clap(short = 'b', long, value_parser)] + pub agent_path: PathBuf, + /// Required: Encrypted password for root user + #[clap(short = 'e', long, value_parser)] + pub root_passwd: String, + /// Required for upgrade + #[clap(short = 'd', long, value_parser)] + pub docker_img: Option, + /// Required: RPM packages + #[clap(short = 'r', long, value_parser)] + pub rpmlist: Vec, + /// Optional: boot mode, default is uefi, enable this flag for legacy bios + #[clap(short, long, value_parser)] + pub legacy_bios: bool, + #[clap(skip)] + pub image_type: String, + #[clap(skip)] + pub arch: Option, +} + +#[derive(Args, Debug, Deserialize, Clone)] +pub struct DockerInfo { + /// Required: Name of the container image + #[clap(short, long, value_parser)] + pub docker_img: String, + #[clap(skip)] + pub image_type: String, +} + +#[derive(Args, Debug, Deserialize, Clone)] +pub struct AdminContainerInfo { + /// Required: Name of the container image + #[clap(short, long, value_parser)] + pub docker_img: String, + /// Required: Path to the Dockerfile + #[clap(short, long, value_parser)] + pub dockerfile: PathBuf, +} + +// bootup config +#[derive(Debug, Deserialize, Clone)] +pub(crate) struct BootupConfig { + pub rootfs_name: String, + pub disk: String, + pub server_ip: String, + pub local_ip: String, + pub route_ip: String, + pub netmask: String, + pub net_name: String, +} +impl BootupConfig { + pub fn new() -> Self { + BootupConfig { + rootfs_name: String::from(ROOTFS_NAME), + disk: String::from(DISK), + server_ip: String::from(SERVER_IP), + local_ip: String::from(LOCAL_IP), + route_ip: String::from(ROUTE_IP), + netmask: String::from(NETMASK), + net_name: String::from(NET_NAME), + } + } +} + +#[derive(Debug, Deserialize, Default, Clone)] +pub struct Config { + pub from_repo: Option, + pub from_dockerimg: Option, + pub admin_container: Option, + pub bootup_config: Option, + pub users: Option>, + pub copy_files: Option>, + pub grub: Option, + pub systemd_service: Option, + pub chroot_script: Option, + pub disk_partition: Option, + pub persist_mkdir: Option, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct User { + pub name: String, + pub passwd: String, + pub groups: Option>, + pub sudo: Option, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct CopyFile { + pub src: String, + pub dst: String, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct Grub { + pub passwd: Option, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct SystemdService { + pub name: Vec, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct ChrootScript { + pub path: String, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct DiskPartition { + pub first: u32, + pub second: u32, + pub third: u32, + pub img_size: u32, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct PersistMkdir { + pub name: Vec, +} diff --git a/KubeOS-Rust/kbimg/src/docker_img.rs b/KubeOS-Rust/kbimg/src/docker_img.rs new file mode 100644 index 0000000000000000000000000000000000000000..0a7a9303c1712b77799ed0575a2ae80b0150f404 --- /dev/null +++ b/KubeOS-Rust/kbimg/src/docker_img.rs @@ -0,0 +1,69 @@ +use std::process::Command; +use std::path::PathBuf; +use std::fs::File; +use std::str; +use anyhow::bail; + +use crate::commands::BootupConfig; +use crate::scripts_gen::*; +use crate::utils::{self, check_pxe_conf_valid, set_permissions}; +use crate::values::*; +use crate::{commands::DockerInfo, Config, CreateImage}; + +impl CreateImage for DockerInfo { + fn prepare(&self, config: &mut Config) -> anyhow::Result<()> { + let image_name = &self.docker_img; + verify_docker_input(&image_name)?; + check_docker_image(&image_name)?; + config.bootup_config = Some(BootupConfig::new()); + if self.image_type == "pxe-repo" { + check_pxe_conf_valid(config.bootup_config.as_ref().unwrap())?; + } + Ok(()) + } + + fn generate_scripts(&self, config: &Config) -> anyhow::Result { + // kbimg.sh + let kbimg_path = format!("{}/{}", SCRIPTS_DIR, KBIMG_SH); + let mut kbimg = File::create(&kbimg_path)?; + gen_global_vars(&mut kbimg)?; + gen_docker_vars(&mut kbimg, &self.docker_img)?; + gen_global_func(&mut kbimg)?; + gen_create_os_tar_from_docker(&mut kbimg)?; + if self.image_type == "vm-docker" { + // kbimg.sh + gen_init_part(&mut kbimg)?; + gen_create_img(&mut kbimg, false, &config)?; + gen_create_vm_docker_img(&mut kbimg)?; + } + else { + // kbimg.sh + gen_create_pxe_docker_img(&mut kbimg)?; + } + set_permissions(&kbimg_path, EXEC_PERMISSION)?; + + Ok(PathBuf::from(&format!("{}/{}", SCRIPTS_DIR, KBIMG_SH))) + } +} + +fn verify_docker_input(image_name: &str) -> anyhow::Result<()> { + if !utils::is_valid_param(image_name) { + bail!("params {} is invalid, please check input", image_name); + } + Ok(()) +} + +fn check_docker_image(image_name: &str) -> anyhow::Result<()> { + let output = Command::new("docker") + .args(&["images", "-q", image_name]) + .output() + .expect("Failed to execute command"); + + if output.status.success() { + let stdout = str::from_utf8(&output.stdout).expect("Invalid UTF-8 output"); + if stdout.trim().is_empty() { + bail!("docker image does NOT exist, please pull {} first.", image_name); + } + } + Ok(()) +} diff --git a/KubeOS-Rust/kbimg/src/main.rs b/KubeOS-Rust/kbimg/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..98b4451dcd5f51e657a09307a1910df159942bd2 --- /dev/null +++ b/KubeOS-Rust/kbimg/src/main.rs @@ -0,0 +1,124 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. + * KubeOS is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +use std::{fs, path::PathBuf, process::exit}; + +use anyhow::{bail, Result}; +use clap::Parser; +use env_logger::{Builder, Env, Target}; +use log::{debug, error, info}; + +mod admin_container; +mod commands; +mod docker_img; +mod repo; +mod utils; +mod values; +mod scripts_gen; + +use utils::{execute_scripts, get_arch}; +use values::SCRIPTS_DIR; + +use crate::commands::{Cli, Commands, Config}; + +trait CreateImage { + /// validate cmd args, check disk size and other prepare work + fn prepare(&self, config: &mut Config) -> Result<()>; + /// generate scripts for creating image. If debug is enabled, keep the scripts, otherwise execute them + fn generate_scripts(&self, config: &Config) -> Result; +} + +fn process(info: Box, mut config: Config) -> Result<()> { + match fs::create_dir_all(SCRIPTS_DIR) { + Ok(_) => { + info.prepare(&mut config)?; + let path = info.generate_scripts(&config)?; + execute_scripts(path)?; + Ok(()) + }, + Err(e) => bail!(e) + } +} + +fn main() { + let cli = Cli::parse(); + let default_log_level: &str = if cli.debug { "debug" } else { "info" }; + Builder::from_env(Env::default().default_filter_or(default_log_level)) + .target(Target::Stdout) + .init(); + match cli.config { + Some(config) => { + info!("Loading config file"); + debug!("Config file path: {:?}", config); + let content = fs::read_to_string(config).unwrap(); + let data: Config = toml::from_str(&content).unwrap(); + debug!("Config: {:?}", data); + let info = if let Some(mut info) = data.from_repo.clone() { + info.arch = Some(get_arch()); + Some(Box::new(info) as Box) + } else if let Some(info) = data.from_dockerimg.clone() { + Some(Box::new(info) as Box) + } else if let Some(info) = data.admin_container.clone() { + Some(Box::new(info) as Box) + } else { + None + }; + if let Some(i) = info { + match process(i, data) { + Ok(_) => { + info!("Image created successfully"); + }, + Err(e) => { + error!("Failed to create image: {:?}", e); + }, + } + } + exit(0); + }, + None => {}, + } + let info = match cli.commands { + Some(Commands::UpgradeImage(mut info)) => { + info.image_type = "upgrade".to_string(); + Some(Box::new(info) as Box) + }, + Some(Commands::VMRepo(mut info)) => { + info.image_type = "vm-repo".to_string(); + debug!("VMRepo: {:?}", info); + Some(Box::new(info) as Box) + }, + Some(Commands::VMDocker(mut info)) => { + info.image_type = "vm-docker".to_string(); + Some(Box::new(info) as Box) + }, + Some(Commands::PxeRepo(mut info)) => { + info.image_type = "pxe-repo".to_string(); + Some(Box::new(info) as Box) + }, + Some(Commands::PxeDocker(mut info)) => { + info.image_type = "pxe-docker".to_string(); + Some(Box::new(info) as Box) + }, + Some(Commands::AdminContainer(info)) => Some(Box::new(info) as Box), + None => None, + }; + if let Some(i) = info { + match process(i, Config::default()) { + Ok(_) => { + info!("Image created successfully"); + }, + Err(e) => { + error!("Failed to create image: {:?}", e); + }, + } + } +} diff --git a/KubeOS-Rust/kbimg/src/repo.rs b/KubeOS-Rust/kbimg/src/repo.rs new file mode 100644 index 0000000000000000000000000000000000000000..d624d96cb8d14587be442459a2cf0ea547507d3f --- /dev/null +++ b/KubeOS-Rust/kbimg/src/repo.rs @@ -0,0 +1,182 @@ +use std::env; +use std::path::PathBuf; +use std::fs::{File, create_dir_all}; +use anyhow::bail; +use sysinfo::Disks; + +use crate::commands::BootupConfig; +use crate::utils::{self, check_pxe_conf_valid, set_permissions}; +use crate::values::*; +use crate::scripts_gen::*; +use crate::{commands::RepoInfo, Config, CreateImage}; + +impl CreateImage for RepoInfo { + fn prepare(&self, config: &mut Config) -> anyhow::Result<()> { + verify_repo_input(&self)?; + check_disk_space(&self.image_type)?; + check_repo_file_valid(&self.repo_path)?; + check_agent_file_valid(&self.agent_path)?; + config.bootup_config = Some(BootupConfig::new()); + if self.image_type == "pxe-repo" { + check_pxe_conf_valid(&config.bootup_config.as_ref().unwrap())?; + } + Ok(()) + } + + fn generate_scripts(&self, config: &Config) -> anyhow::Result { + // rpmlist + let rpmlist_path = format!("{}/{}", SCRIPTS_DIR, RPMLIST); + let mut rpmlist = File::create(&rpmlist_path)?; + gen_rpm_list(&mut rpmlist, &self.rpmlist)?; + set_permissions(&rpmlist_path, CONFIG_PERMISSION)?; + // 00bootup + match create_dir_all(BOOTUP_DIR) { + Ok(_) => { + let global_cfg_path = format!("{}/{}", BOOTUP_DIR, BOOTUP_GLOBAL_CFG); + let mut global_cfg = File::create(&global_cfg_path)?; + gen_global_cfg(&mut global_cfg, &config.bootup_config.as_ref().unwrap())?; + set_permissions(&global_cfg_path, CONFIG_PERMISSION)?; + let module_setup_path = format!("{}/{}", BOOTUP_DIR, BOOTUP_MODULE_SETUP_SH); + let mut module_setup = File::create(&module_setup_path)?; + gen_module_setup(&mut module_setup)?; + set_permissions(&module_setup_path, EXEC_PERMISSION)?; + let mount_path = format!("{}/{}", BOOTUP_DIR, BOOTUP_MOUNT_SH); + let mut mount = File::create(&mount_path)?; + gen_mount(&mut mount)?; + set_permissions(&mount_path, EXEC_PERMISSION)?; + } + Err(e) => { + bail!(e); + } + } + // misc-files + match create_dir_all(MISC_FILES_DIR) { + Ok(_) => { + let boot_efi_mount_path = format!("{}/{}", MISC_FILES_DIR, MISC_BOOT_EFI_MOUNT); + let mut boot_efi_mount = File::create(&boot_efi_mount_path)?; + gen_boot_efi_mount(&mut boot_efi_mount)?; + set_permissions(&boot_efi_mount_path, CONFIG_PERMISSION)?; + let boot_grub2_mount_path = format!("{}/{}", MISC_FILES_DIR, MISC_BOOT_GRUB2_MOUNT); + let mut boot_grub2_mount = File::create(&boot_grub2_mount_path)?; + gen_boot_grub2_mount(&mut boot_grub2_mount)?; + set_permissions(&boot_grub2_mount_path, CONFIG_PERMISSION)?; + let etc_mount_path = format!("{}/{}", MISC_FILES_DIR, MISC_ETC_MOUNT); + let mut etc_mount = File::create(&etc_mount_path)?; + gen_etc_mount(&mut etc_mount)?; + set_permissions(&etc_mount_path, CONFIG_PERMISSION)?; + let os_agent_service_path = format!("{}/{}", MISC_FILES_DIR, MISC_OS_AGENT_SERVICE); + let mut os_agent_service = File::create(&os_agent_service_path)?; + gen_os_agent_service(&mut os_agent_service)?; + set_permissions(&os_agent_service_path, CONFIG_PERMISSION)?; + let os_release_path = format!("{}/{}", MISC_FILES_DIR, MISC_OS_RELEASE); + let mut os_release = File::create(&os_release_path)?; + gen_os_release(&mut os_release)?; + set_permissions(&os_release_path, CONFIG_PERMISSION)?; + let persist_mount_path = format!("{}/{}", MISC_FILES_DIR, MISC_PERSIST_MOUNT); + let mut persist_mount = File::create(&persist_mount_path)?; + gen_persist_mount(&mut persist_mount)?; + set_permissions(&persist_mount_path, CONFIG_PERMISSION)?; + let var_mount_path = format!("{}/{}", MISC_FILES_DIR, MISC_VAR_MOUNT); + let mut var_mount = File::create(&var_mount_path)?; + gen_var_mount(&mut var_mount)?; + set_permissions(&var_mount_path, CONFIG_PERMISSION)?; + } + Err(e) => { + bail!(e); + } + } + // grub.cfg + let grub_cfg_path = format!("{}/{}", SCRIPTS_DIR, GRUB_CFG); + let mut grub_cfg = File::create(&grub_cfg_path)?; + gen_grub_cfg(&mut grub_cfg)?; + set_permissions(&grub_cfg_path, CONFIG_PERMISSION)?; + // set_in_chroot.sh + let set_in_chroot_path = format!("{}/{}", SCRIPTS_DIR, SET_IN_CHROOT_SH); + let mut set_in_chroot = File::create(&set_in_chroot_path)?; + gen_set_in_chroot(&mut set_in_chroot, self.legacy_bios, &config)?; + set_permissions(&set_in_chroot_path, EXEC_PERMISSION)?; + // kbimg.sh + let kbimg_path = format!("{}/{}", SCRIPTS_DIR, KBIMG_SH); + let mut kbimg = File::create(&kbimg_path)?; + gen_global_vars(&mut kbimg)?; + gen_repo_vars(&mut kbimg, &self)?; + gen_global_func(&mut kbimg)?; + gen_mount_proc_dev_sys(&mut kbimg)?; + gen_unmount_dir(&mut kbimg)?; + gen_create_os_tar_from_repo(&mut kbimg, &self, &config)?; + if self.image_type == "vm-repo" { + // bootloader.sh + let bootloader_path = format!("{}/{}", SCRIPTS_DIR, BOOTLOADER_SH); + let mut bootloader = File::create(&bootloader_path)?; + gen_bootloader(&mut bootloader, self.arch.as_ref().unwrap(), self.legacy_bios)?; + set_permissions(&bootloader_path, EXEC_PERMISSION)?; + // kbimg.sh + gen_init_part(&mut kbimg)?; + gen_create_img(&mut kbimg, self.legacy_bios, &config)?; + gen_create_vm_repo_img(&mut kbimg)?; + } + else if self.image_type == "pxe-repo" { + // kbimg.sh + gen_create_pxe_repo_img(&mut kbimg)?; + } + else { + // Dockerfile + let dockerfile_path = format!("{}/{}", SCRIPTS_DIR, DOCKERFILE); + let mut dockerfile = File::create(&dockerfile_path)?; + gen_dockerfile(&mut dockerfile)?; + set_permissions(&dockerfile_path, CONFIG_PERMISSION)?; + // kbimg.sh + gen_create_docker_img(&mut kbimg)?; + } + set_permissions(&kbimg_path, EXEC_PERMISSION)?; + + Ok(PathBuf::from(&format!("{}/{}", SCRIPTS_DIR, KBIMG_SH))) + } +} + +fn verify_repo_input(info: &RepoInfo) -> anyhow::Result<()> { + if !utils::is_valid_param(info.repo_path.to_str().unwrap()) { + bail!("params {} is invalid, please check input", info.repo_path.to_str().unwrap()); + } + if !utils::is_valid_param(&info.version) { + bail!("params {} is invalid, please check input", info.version); + } + if !utils::is_valid_param(info.agent_path.to_str().unwrap()) { + bail!("params {} is invalid, please check input", info.agent_path.to_str().unwrap()); + } + if let Some(docker_img) = &info.docker_img { + if !utils::is_valid_param(docker_img) { + bail!("params {} is invalid, please check input", docker_img); + } + } + Ok(()) +} + +fn check_disk_space(image_type: &str) -> anyhow::Result<()> { + let max_size: u64 = match image_type { + "upgrade" => 6, + "vm-repo" => 25, + "pxe-repo" => 5, + _ => bail!("Invalid image type: {}", image_type), + }; + + let current_dir = env::current_dir().expect("Failed to get current directory"); + let root_dir = current_dir.ancestors().last().expect("Failed to get current directory").to_path_buf(); + let disks: Disks = Disks::new_with_refreshed_list(); + for d in &disks { + if d.mount_point() == root_dir { + if d.available_space() < max_size * 1024 * 1024 { + bail!("The available disk space is not enough, at least {}GiB.", max_size); + } + } + } + Ok(()) +} + +fn check_repo_file_valid(repo_path: &PathBuf) -> anyhow::Result<()> { + utils::is_file_valid("REPO file", repo_path) +} + +fn check_agent_file_valid(agent_path: &PathBuf) -> anyhow::Result<()> { + utils::is_file_valid("os-agent binary", agent_path) +} diff --git a/KubeOS-Rust/kbimg/src/scripts_gen.rs b/KubeOS-Rust/kbimg/src/scripts_gen.rs new file mode 100644 index 0000000000000000000000000000000000000000..ddf26d3d176ca6aec6e42c604ca5a4bdcea12bfb --- /dev/null +++ b/KubeOS-Rust/kbimg/src/scripts_gen.rs @@ -0,0 +1,1614 @@ +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +use anyhow::{Ok, Result, bail}; + +use crate::commands::*; +use crate::values::SCRIPTS_DIR; + +/* region: kbimg.sh */ +pub(crate) fn gen_global_vars(file: &mut File) -> Result<()> { + writeln!(file, +r#"#!/bin/bash + +set -e + +SCRIPTS_DIR=$(cd "$(dirname "$0")" && pwd) +LOCK="${{SCRIPTS_DIR}}"/test.lock +RPM_ROOT="${{SCRIPTS_DIR}}"/rootfs +TMP_MOUNT_PATH="${{SCRIPTS_DIR}}"/mnt +"# + )?; + Ok(()) +} + +pub(crate) fn gen_global_func(file: &mut File) -> Result<()> { + writeln!(file, +r#"function delete_dir() {{ + local ret=0 + local dir="$1" + unmount_dir "${{dir}}" + ret=$? + if [ "${{ret}}" -eq 0 ]; then + rm -rf "${{dir}}" + return 0 + else + log_error_print "${{dir}} is failed to unmount , can not delete ${{dir}}." + return 1 + fi +}} + +function delete_file() {{ + local file="$1" + if [ ! -e "${{file}}" ]; then + return 0 + fi + + if [ ! -f "${{file}}" ]; then + log_error_print "${{file}} is not a file." + return 1 + fi + + rm -f "${{file}}" + return 0 +}} + +function clean_space() {{ + delete_dir "${{RPM_ROOT}}" + delete_dir "${{TMP_MOUNT_PATH}}" + delete_file "${{SCRIPTS_DIR}}"/os.tar + rm -rf "${{LOCK}}" + delete_file "${{ADMIN_CONTAINER_DIR}}"/hostshell +}} + +function clean_img() {{ + delete_file "${{SCRIPTS_DIR}}"/system.img + delete_file "${{SCRIPTS_DIR}}"/update.img + delete_file "${{SCRIPTS_DIR}}"/initramfs.img + delete_file "${{SCRIPTS_DIR}}"/kubeos.tar +}} + +function file_lock() {{ + local lock_file=$1 + exec {{lock_fd}}>"${{lock_file}}" + flock -xn "${{lock_fd}}" +}} + +function test_lock() {{ + file_lock "${{LOCK}}" + local status=$? + if [ $status -ne 0 ]; then + log_error_print "There is already an generate process running." + exit 203 + fi +}} + +function log_error_print() {{ + local logmsg + logmsg="[ ERROR ] - ""$(date "+%b %d %Y %H:%M:%S")"" $1" + echo "$logmsg" +}} + +function log_info_print() {{ + local logmsg + logmsg="[ INFO ] - ""$(date "+%b %d %Y %H:%M:%S")"" $1" + echo "$logmsg" +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_mount_proc_dev_sys(file: &mut File) -> Result<()> { + writeln!(file, +r#"function mount_proc_dev_sys() {{ + local tmp_root=$1 + mount -t proc none "${{tmp_root}}"/proc + mount --bind /dev "${{tmp_root}}"/dev + mount --bind /dev/pts "${{tmp_root}}"/dev/pts + mount -t sysfs none "${{tmp_root}}"/sys +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_unmount_dir(file: &mut File) -> Result<()> { + writeln!(file, +r#"function unmount_dir() {{ + local dir=$1 + + if [ -L "${{dir}}" ] || [ -f "${{dir}}" ]; then + log_error_print "${{dir}} is not a directory, please check it." + return 1 + fi + + if [ ! -d "${{dir}}" ]; then + return 0 + fi + + local real_dir + real_dir=$(readlink -e "${{dir}}") + local mnts + mnts=$(awk '{{print $2}}' < /proc/mounts | grep "^${{real_dir}}" | sort -r) + for m in ${{mnts}}; do + log_info_print "Unmount ${{m}}" + umount -f "${{m}}" || true + done + + return 0 +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_init_part(file: &mut File) -> Result<()> { + writeln!(file, +r#"function init_part() {{ + local offset + offset=$(fdisk -l "${{SCRIPTS_DIR}}"/system.img | grep "$1" | awk '{{print $2}}') + local sizelimit + sizelimit=$(fdisk -l "${{SCRIPTS_DIR}}"/system.img | grep "$1" | awk '{{print $3}}') + sizelimit=$(echo "($sizelimit - $offset)*512" | bc) + offset=$(echo "${{offset}}*512" | bc) + local loop + loop=$(losetup -f) + losetup -o "${{offset}}" --sizelimit "${{sizelimit}}" "${{loop}}" "${{SCRIPTS_DIR}}"/system.img + if [ "$2" == "BOOT" ];then + mkfs.vfat -n "$2" "${{loop}}" + mount -t vfat "${{loop}}" "$3" + else + mkfs.ext4 -L "$2" "${{loop}}" + mount -t ext4 "${{loop}}" "$3" + rm -rf "$3/lost+found" + fi +}} +"# + )?; + Ok(()) +} + +// repo +pub(crate) fn gen_repo_vars(file: &mut File, info: &RepoInfo) -> Result<()> { + writeln!(file, +r#"REPO_PATH="{}" +VERSION="{}" +AGENT_PATH="{}" +ROOT_PASSWD='{}' +BOOT_MODE="{}" +"#, + info.repo_path.to_str().unwrap(), + &info.version, + info.agent_path.to_str().unwrap(), + &info.root_passwd, + if info.legacy_bios { "legacy" } else { "efi" } + )?; + if let Some(docker_img) = &info.docker_img { + writeln!(file, "DOCKER_IMG=\"{}\"\n", docker_img)?; + } + Ok(()) +} + +pub(crate) fn gen_prepare_yum(file: &mut File) -> Result<()> { + writeln!(file, +r#"function prepare_yum() {{ + # init rpmdb + rpm --root "${{RPM_ROOT}}" --initdb + mkdir -p "${{RPM_ROOT}}"{{/etc/yum.repos.d,/persist,/proc,/dev/pts,/sys}} + mount_proc_dev_sys "${{RPM_ROOT}}" + # init yum repo + local iso_repo="${{RPM_ROOT}}"/etc/yum.repos.d/iso.repo + cat "${{REPO_PATH}}" > "$iso_repo" +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_install_packages(file: &mut File, arch: &str, legacy_bios: bool) -> Result<()> { + writeln!(file, +r#"function install_packages() {{ + prepare_yum "${{REPO_PATH}}" + + echo "install package.." + + local filesize + filesize=$(stat -c "%s" "${{SCRIPTS_DIR}}"/rpmlist) + local maxsize=$((1024*1024)) + if [ "${{filesize}}" -gt "${{maxsize}}" ]; then + echo "please check if rpmlist is too big or something wrong" + exit 7 + fi + + local rpms_name + rpms_name=$(tr "\n" " " < "${{SCRIPTS_DIR}}"/rpmlist) + old_ifs="$IFS" + IFS=' '"#)?; + + if arch == "x86_64" { + if legacy_bios { + writeln!(file, "\trpms_name+=\" grub2\"")?; + } + else { + writeln!(file, "\trpms_name+=\" grub2-efi grub2-tools grub2-efi-x64-modules grub2-pc-modules\"")?; + } + writeln!(file, +r#" read -ra rpms <<< "${{rpms_name}}" + IFS="$old_ifs" + yum -y --installroot="${{RPM_ROOT}}" install --nogpgcheck --setopt install_weak_deps=False "${{rpms[@]}}""# + )?; + } + else if arch == "aarch64" { + writeln!(file, +r#" read -ra rpms <<< "${{rpms_name}}" + IFS="$old_ifs" + yum -y --installroot="${{RPM_ROOT}}" install --nogpgcheck --setopt install_weak_deps=False "${{rpms[@]}}" grub2-efi grub2-tools grub2-efi-aa64-modules"# + )?; + } + writeln!(file, +r#" yum -y --installroot="${{RPM_ROOT}}" clean all +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_copy_files(file: &mut File, copy_files: &Vec) -> Result<()> { + writeln!(file, "function copy_files() {{")?; + for copy_file in copy_files { + let dst = format!("{}/rootfs{}", SCRIPTS_DIR, ©_file.dst); + let dst = PathBuf::from(dst); + if !dst.exists() { + writeln!(file, "\tmkdir -p \"${{RPM_ROOT}}{}\"", ©_file.dst)?; + } + let src = PathBuf::from(©_file.src); + if src.is_dir() { + writeln!(file, "\tcp -r {} \"${{RPM_ROOT}}{}\"", ©_file.src, ©_file.dst)?; + } + else { + writeln!(file, "\tcp {} \"${{RPM_ROOT}}{}\"", ©_file.src, ©_file.dst)?; + } + } + writeln!(file, "}}\n")?; + Ok(()) +} + +pub(crate) fn gen_grub_config(file: &mut File, legacy_bios: bool, grub: &Grub) -> Result<()> { + writeln!(file, +r#"function grub_config() {{ + local GRUB_PATH"# + )?; + if legacy_bios { + writeln!(file, "\tGRUB_PATH=\"${{RPM_ROOT}}\"/boot/grub2")?; + } + else { + writeln!(file, "\tGRUB_PATH=\"${{RPM_ROOT}}\"/boot/efi/EFI/openEuler")?; + } + if let Some(grub_passwd) = &grub.passwd { + writeln!(file, +r#" local GRUB_PASSWD + GRUB_PASSWD=$(echo -e "{}\n{}" | grub2-mkpasswd-pbkdf2 | grep PBKDF2 | awk '{{print $7}}') + echo "GRUB2_PASSWD=${{GRUB_PASSWD}}" > "${{GRUB_PATH}}"/user.cfg + chmod 600 "${{GRUB_PATH}}"/user.cfg +}} +"#, + grub_passwd, grub_passwd)?; + } + Ok(()) +} + +pub(crate) fn gen_chroot_script(file: &mut File, chroot_script: &ChrootScript) -> Result<()> { + let script_path = PathBuf::from(&chroot_script.path); + match script_path.canonicalize() { + core::result::Result::Ok(absolute_path) => { + if let Some(script_name) = absolute_path.file_name() { + writeln!(file, +r#"function chroot_script() {{ + cp "{}" "${{RPM_ROOT}}" + chroot "${{RPM_ROOT}}" bash /{} +}} +"#, + absolute_path.as_path().to_str().unwrap(), script_name.to_str().unwrap())?; + } + Ok(()) + } + Err(e) => bail!(e) + } +} + +pub(crate) fn gen_install_misc(file: &mut File, legacy_bios: bool, config: &Config) -> Result<()> { + if let Some(copy_files) = &config.copy_files { + gen_copy_files(file, ©_files)?; + } + if let Some(grub) = &config.grub { + gen_grub_config(file, legacy_bios, &grub)?; + } + if let Some(chroot_script) = &config.chroot_script { + gen_chroot_script(file, &chroot_script)?; + } + + writeln!(file, +r#"function install_misc() {{ + cp "${{SCRIPTS_DIR}}"/misc-files/*mount "${{SCRIPTS_DIR}}"/misc-files/os-agent.service "${{RPM_ROOT}}"/usr/lib/systemd/system/ + cp "${{SCRIPTS_DIR}}"/misc-files/os-release "${{RPM_ROOT}}"/usr/lib/ + cp "${{AGENT_PATH}}" "${{RPM_ROOT}}"/usr/bin + rm "${{RPM_ROOT}}"/etc/os-release + + cat < "${{RPM_ROOT}}"/usr/lib/os-release +NAME=${{NAME}} +ID=${{NAME}} +EOF + echo "PRETTY_NAME=\"${{NAME}} ${{VERSION}}\"" >> "${{RPM_ROOT}}"/usr/lib/os-release + echo "VERSION_ID=${{VERSION}}" >> "${{RPM_ROOT}}"/usr/lib/os-release + mv "${{RPM_ROOT}}"/boot/vmlinuz* "${{RPM_ROOT}}"/boot/vmlinuz + mv "${{RPM_ROOT}}"/boot/initramfs* "${{RPM_ROOT}}"/boot/initramfs.img"#)?; + + if legacy_bios { + writeln!(file, +r#" cp "${{SCRIPTS_DIR}}"/grub.cfg "${{RPM_ROOT}}"/boot/grub2 + sed -i "s/insmod part_gpt/insmod part_msdos/g; \ +s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ +s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ +"${{RPM_ROOT}}"/boot/grub2/grub.cfg"# + )?; + } + else { + writeln!(file, "\tcp \"${{SCRIPTS_DIR}}\"/grub.cfg \"${{RPM_ROOT}}\"/boot/efi/EFI/openEuler")?; + } + + writeln!(file, +r#" cp -r "${{SCRIPTS_DIR}}"/00bootup "${{RPM_ROOT}}"/usr/lib/dracut/modules.d/ + cp "${{SCRIPTS_DIR}}"/set_in_chroot.sh "${{RPM_ROOT}}" + + # (optional) custom config"#)?; + + if let Some(_) = &config.copy_files { + writeln!(file, "\tcopy_files")?; + } + if let Some(_) = &config.grub { + writeln!(file, "\tgrub_config")?; + } + if let Some(_) = &config.chroot_script { + writeln!(file, "\tchroot_script")?; + } + + writeln!(file, +r#" + ROOT_PASSWD="${{ROOT_PASSWD}}" BOOT_MODE="${{BOOT_MODE}}" chroot "${{RPM_ROOT}}" bash /set_in_chroot.sh + rm "${{RPM_ROOT}}/set_in_chroot.sh" +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_os_tar_from_repo(file: &mut File, info: &RepoInfo, config: &Config) -> Result<()> { + gen_prepare_yum(file)?; + gen_install_packages(file, info.arch.as_ref().unwrap(), info.legacy_bios)?; + gen_install_misc(file, info.legacy_bios, config)?; + + writeln!(file, +r#"function create_os_tar_from_repo() {{ + install_packages + install_misc + unmount_dir "${{RPM_ROOT}}" + tar -C "${{RPM_ROOT}}" -cf "${{SCRIPTS_DIR}}"/os.tar . +}} +"#)?; + Ok(()) +} + +pub(crate) fn gen_create_img(file: &mut File, legacy_bios: bool, config: &Config) -> Result<()> { + let (first, second, third, img_size) = if let Some(disk_partition) = &config.disk_partition { + let first = disk_partition.first; + let second = disk_partition.second; + let third = disk_partition.third; + let img_size = disk_partition.img_size; + if first + second + third + 2100 > img_size * 1024 { + bail!("Image size({}G) is not enough for partitions, please check input", img_size) + } + (first, first + second, first + second + third, img_size) + } + else { + (60, 2160, 4260, 20) + }; + + writeln!(file, +r#"function create_img() {{ + rm -f "${{SCRIPTS_DIR}}"/system.img "${{SCRIPTS_DIR}}/update.img" + qemu-img create "${{SCRIPTS_DIR}}/system.img" {}G"#, img_size)?; + + if legacy_bios { + writeln!(file, +r#" local BOOT_PATH=${{TMP_MOUNT_PATH}}/boot/grub2 + parted "${{SCRIPTS_DIR}}/system.img" -s mklabel msdos + parted "${{SCRIPTS_DIR}}/system.img" -s mkpart primary ext4 1MiB {}MiB"#, first)?; + } + else { + writeln!(file, +r#" local BOOT_PATH=${{TMP_MOUNT_PATH}}/boot/efi + parted "${{SCRIPTS_DIR}}/system.img" -s mklabel gpt + parted "${{SCRIPTS_DIR}}/system.img" -s mkpart primary fat32 1MiB {}MiB"#, first)?; + } + + writeln!(file, +r#" parted "${{SCRIPTS_DIR}}/system.img" -s mkpart primary ext4 {}MiB {}MiB + parted "${{SCRIPTS_DIR}}/system.img" -s mkpart primary ext4 {}MiB {}MiB + parted "${{SCRIPTS_DIR}}/system.img" -s mkpart primary ext4 {}MiB 100%"#, + first, second, second, third, third)?; + + writeln!(file, +r#" local device + device=$(losetup -f) + losetup "${{device}}" "${{SCRIPTS_DIR}}"/system.img + + mkdir -p "${{TMP_MOUNT_PATH}}" + + init_part "${{SCRIPTS_DIR}}"/system.img2 ROOT-A "${{TMP_MOUNT_PATH}}" + + mkdir -p "${{BOOT_PATH}}" + chmod 755 "${{BOOT_PATH}}""#)?; + + if legacy_bios { + writeln!(file, +r#" init_part "${{SCRIPTS_DIR}}"/system.img1 GRUB2 "${{BOOT_PATH}}" + tar -x -C "${{TMP_MOUNT_PATH}}" -f "${{SCRIPTS_DIR}}"/os.tar + sed -i "s/insmod part_gpt/insmod part_msdos/g; \ +s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ +s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ +"${{TMP_MOUNT_PATH}}"/boot/grub2/grub.cfg"#)?; + } + else { + writeln!(file, +r#" init_part "${{SCRIPTS_DIR}}"/system.img1 BOOT "${{BOOT_PATH}}" + tar -x -C "${{TMP_MOUNT_PATH}}" -f "${{SCRIPTS_DIR}}"/os.tar"#)?; + } + + writeln!(file, +r#" sync + cp "${{SCRIPTS_DIR}}"/bootloader.sh "${{TMP_MOUNT_PATH}}" + mount_proc_dev_sys "${{TMP_MOUNT_PATH}}" + DEVICE="${{device}}" BOOT_MODE="${{BOOT_MODE}}" chroot "${{TMP_MOUNT_PATH}}" bash bootloader.sh + rm -rf "${{TMP_MOUNT_PATH}}"/bootloader.sh + sync + + dd if=/dev/disk/by-label/ROOT-A of="${{SCRIPTS_DIR}}"/update.img bs=8M + sync + unmount_dir "${{TMP_MOUNT_PATH}}" + init_part "${{SCRIPTS_DIR}}"/system.img3 ROOT-B "${{TMP_MOUNT_PATH}}" + umount "${{TMP_MOUNT_PATH}}" + + init_part "${{SCRIPTS_DIR}}"/system.img4 PERSIST "${{TMP_MOUNT_PATH}}" + mkdir "${{TMP_MOUNT_PATH}}"/{{var,etc,etcwork}}"#)?; + + if let Some(persist_mkdir) = &config.persist_mkdir { + for name in &persist_mkdir.name { + writeln!(file, "\tmkdir \"${{TMP_MOUNT_PATH}}\"/{}", name)?; + } + } + + writeln!(file, +r#" mkdir -p "${{TMP_MOUNT_PATH}}"/etc/KubeOS/certs + umount "${{TMP_MOUNT_PATH}}" + + losetup -D + parted "${{SCRIPTS_DIR}}"/system.img -- set 1 boot on + qemu-img convert "${{SCRIPTS_DIR}}"/system.img -O qcow2 "${{SCRIPTS_DIR}}"/system.qcow2 +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_vm_repo_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_vm_repo_img() {{ + create_os_tar_from_repo + create_img +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_vm_repo_img"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_pxe_repo_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_pxe_repo_img() {{ + rm -rf "${{SCRIPTS_DIR}}"/initramfs.img "${{SCRIPTS_DIR}}"/kubeos.tar + create_os_tar_from_repo + tar -xvf "${{SCRIPTS_DIR}}"/os.tar "${{SCRIPTS_DIR}}"/initramfs.img + mv "${{SCRIPTS_DIR}}"/os.tar "${{SCRIPTS_DIR}}"/kubeos.tar +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_pxe_repo_img"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_docker_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_docker_img() {{ + create_os_tar_from_repo + docker build -t "${{DOCKER_IMG}}" -f "${{SCRIPTS_DIR}}"/Dockerfile . +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_docker_img"# + )?; + Ok(()) +} + +// docker +pub(crate) fn gen_docker_vars(file: &mut File, image_name: &str) -> Result<()> { + writeln!(file, +r#" +IMAGE_NAME="{}" +BOOT_MODE=efi +"#, + image_name + )?; + Ok(()) +} + +pub(crate) fn gen_create_os_tar_from_docker(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_os_tar_from_docker() {{ + container_id=$(docker create "${{DOCKER_IMG}}") + echo "$container_id" + docker cp "$container_id":/os.tar "${{SCRIPTS_DIR}}" + docker rm "$container_id" +}} +"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_vm_docker_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_vm_docker_img() {{ + create_os_tar_from_docker + create_img +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_vm_docker_img"# + )?; + Ok(()) +} + +pub(crate) fn gen_create_pxe_docker_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_pxe_docker_img() {{ + rm -rf "${{SCRIPTS_DIR}}"/initramfs.img "${{SCRIPTS_DIR}}"/kubeos.tar + create_os_tar_from_docker + tar -xvf "${{SCRIPTS_DIR}}"/os.tar "${{SCRIPTS_DIR}}"/initramfs.img + mv "${{SCRIPTS_DIR}}"/os.tar "${{SCRIPTS_DIR}}"/kubeos.tar +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_pxe_docker_img"# + )?; + Ok(()) +} + +// admin +pub(crate) fn gen_admin_vars(file: &mut File, docker_img: &str, dockerfile: &PathBuf) -> Result<()> { + writeln!(file, +r#"DOCKER_IMG={} +DOCKERFILE={} +ADMIN_CONTAINER_DIR="${{SCRIPTS_DIR}}"/admin-container +"#, + dockerfile.to_str().unwrap(), + docker_img + )?; + Ok(()) +} + +pub(crate) fn gen_create_admin_img(file: &mut File) -> Result<()> { + writeln!(file, +r#"function create_admin_img() {{ + local kubeos_root_dir=$(dirname $(dirname $(dirname "${{SCRIPTS_DIR}}"))) + cp "${{kubeos_root_dir}}"/bin/hostshell "${{ADMIN_CONTAINER_DIR}}" + docker build -t "${{DOCKER_IMG}}" -f "${{DOCKERFILE}}" "${{ADMIN_CONTAINER_DIR}}" + rm -rf "${{ADMIN_CONTAINER_DIR}}"/hostshell +}} + +test_lock +trap clean_space EXIT +trap clean_img ERR + +create_admin_img"# + )?; + Ok(()) +} +/* endregion */ + +/* region: set_in_chroot.sh */ +pub(crate) fn gen_add_users(file: &mut File, users: &Vec) -> Result<()> { + writeln!(file, "# add users")?; + for user in users { + let name = &user.name; + let passwd = &user.passwd; + let groups = match user.groups.clone() { + Some(groups) => groups, + None => vec![name.clone()], + }; + for group in &groups { + writeln!(file, +r#"if ! getent group "{}" > /dev/null 2>&1; then + groupadd "{}" +fi"#, + group, group)?; + } + write!(file, "useradd -m -g {}", &groups[0])?; + if groups.len() > 1 { + let additional_groups = &groups[1..].join(","); + write!(file, " -G {}", additional_groups)?; + } + writeln!(file, " -s /bin/bash \"{}\"", &name)?; + writeln!(file, "echo \"{}:{}\" | chpasswd", name, passwd)?; + if let Some(sudo) = &user.sudo { + writeln!(file, +r#"if visudo -c; then + echo -e "{} {}" | tee -a /etc/sudoers +else + echo "Sudoers file syntax check failed. Please fix the sudoers file manually." + exit 5 +fi"#, + name, sudo)?; + } + } + Ok(()) +} + +pub(crate) fn gen_systemd_services(file: &mut File, systemd_services: &SystemdService) -> Result<()> { + writeln!(file, "# systemd")?; + for service_name in &systemd_services.name { + writeln!(file, "systemctl enable {}", service_name)?; + } + Ok(()) +} + +pub(crate) fn gen_set_in_chroot(file: &mut File, legacy_bios: bool, config: &Config) -> Result<()> { + writeln!(file, +r#"#!/bin/bash +ln -s /usr/lib/systemd/system/os-agent.service /usr/lib/systemd/system/multi-user.target.wants/os-agent.service +ln -s /usr/lib/systemd/system/kubelet.service /usr/lib/systemd/system/multi-user.target.wants/kubelet.service"#)?; + if legacy_bios { + writeln!(file, "ln -s /usr/lib/systemd/system/boot-grub2.mount /lib/systemd/system/local-fs.target.wants/boot-grub2.mount")?; + } + else { + writeln!(file, "ln -s /usr/lib/systemd/system/boot-efi.mount /lib/systemd/system/local-fs.target.wants/boot-efi.mount")?; + } + writeln!(file, r#"ln -s /usr/lib/systemd/system/etc.mount /lib/systemd/system/local-fs.target.wants/etc.mount"#)?; + + if let Some(users) = &config.users { + gen_add_users(file, users)?; + } + if let Some(systemd_services) = &config.systemd_service { + gen_systemd_services(file, systemd_services)?; + } + + writeln!(file, +r#" +str=$(sed -n '/^root:/p' /etc/shadow | awk -F "root:" '{{print $2}}') +umask 0666 +mv /etc/shadow /etc/shadow_bak +sed -i '/^root:/d' /etc/shadow_bak +echo "root:""${{ROOT_PASSWD}}""${{str:1}}" > /etc/shadow +cat /etc/shadow_bak >> /etc/shadow +rm -rf /etc/shadow_bak + +dracut -f -v --add bootup /initramfs.img --kver "$(ls /lib/modules)" +rm -rf /usr/lib/dracut/modules.d/00bootup"# + )?; + + Ok(()) +} +/* endregion */ + +/* region: bootloader.sh */ +pub(crate) fn gen_bootloader(file: &mut File, arch: &str, legacy_bios: bool) -> Result<()> { + writeln!(file, +r#"#!/bin/bash +set -eu +set -o pipefail +set -x + +function install_grub2 () {{"#)?; + + if arch == "aarch64" || (arch == "x86_64" && !legacy_bios) { + writeln!(file, +r#" cp -r /usr/lib/grub/x86_64-efi boot/efi/EFI/openEuler + eval "grub2-mkimage -d /usr/lib/grub/x86_64-efi -O x86_64-efi --output=/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" + + mkdir -p /boot/efi/EFI/BOOT/ + cp -f /boot/efi/EFI/openEuler/grubx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI +}} +"# + )?; + } + else { + writeln!(file, +r#" GRUBNAME=$(which grub2-install) + echo "Installing GRUB2..." + FORCE_OPT=${{FORCE_OPT:-"--force"}} + TARGET_OPT=${{TARGET_OPT:-"--target=i386-pc"}} + + $GRUBNAME --modules="biosdisk part_msdos" "$FORCE_OPT" "$TARGET_OPT" "$DEVICE" +}} +"# + )?; + } + + writeln!(file, +r#"install_grub2 +"# + )?; + Ok(()) +} +/* endregion */ + +/* region: rpmlist */ +pub(crate) fn gen_rpm_list(file: &mut File, rpmlist: &Vec) -> Result<()> { + for rpm in rpmlist { + writeln!(file, "{}", rpm)?; + } + Ok(()) +} +/* endregion */ + +/* region: grub.cfg */ +pub(crate) fn gen_grub_cfg(file: &mut File) -> Result<()> { + writeln!(file, +r#"set pager=1 + +if [ -f ${{config_directory}}/grubenv ]; then + load_env -f ${{config_directory}}/grubenv +elif [ -s $prefix/grubenv ]; then + load_env +fi +if [ "${{next_entry}}" ] ; then + set default="${{next_entry}}" + set next_entry= + save_env next_entry + set boot_once=true +else + set default="${{saved_entry}}" +fi + +if [ x"${{feature_menuentry_id}}" = xy ]; then + menuentry_id_option="--id" +else + menuentry_id_option="" +fi + +export menuentry_id_option + +if [ "${{prev_saved_entry}}" ]; then + set saved_entry="${{prev_saved_entry}}" + save_env saved_entry + set prev_saved_entry= + save_env prev_saved_entry + set boot_once=true +fi + +function savedefault {{ + if [ -z "${{boot_once}}" ]; then + saved_entry="${{chosen}}" + save_env saved_entry + fi +}} + +function load_video {{ + if [ x$feature_all_video_module = xy ]; then + insmod all_video + else + insmod efi_gop + insmod efi_uga + insmod ieee1275_fb + insmod vbe + insmod vga + insmod video_bochs + insmod video_cirrus + fi +}} + +terminal_output console +if [ x$feature_timeout_style = xy ] ; then + set timeout_style=menu + set timeout=5 +# Fallback normal timeout code in case the timeout_style feature is +# unavailable. +else + set timeout=5 +fi +set superusers="root" +### END /etc/grub.d/00_header ### + +### BEGIN /etc/grub.d/01_users ### +if [ -f ${{prefix}}/user.cfg ]; then + source ${{prefix}}/user.cfg + if [ -n "${{GRUB2_PASSWORD}}" ]; then + set superusers="root" + export superusers + password_pbkdf2 root ${{GRUB2_PASSWORD}} + fi +fi +### END /etc/grub.d/01_users ### + +### BEGIN /etc/grub.d/10_linux ### +menuentry 'A' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-A' {{ + load_video + set gfxpayload=keep + insmod gzio + insmod part_gpt + insmod ext2 + set root='hd0,gpt2' + linux /boot/vmlinuz root=/dev/vda2 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3 + initrd /boot/initramfs.img +}} + +menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-B' {{ + load_video + set gfxpayload=keep + insmod gzio + insmod part_gpt + insmod ext2 + set root='hd0,gpt3' + linux /boot/vmlinuz root=/dev/vda3 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3 + initrd /boot/initramfs.img +}} + +### END /etc/grub.d/10_linux ### + +### BEGIN /etc/grub.d/10_reset_boot_success ### +# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry +if [ "${{boot_success}}" = "1" -o "${{boot_indeterminate}}" = "1" ]; then + set menu_hide_ok=1 +else + set menu_hide_ok=0 +fi +# Reset boot_indeterminate after a successful boot +if [ "${{boot_success}}" = "1" ] ; then + set boot_indeterminate=0 +# Avoid boot_indeterminate causing the menu to be hidden more then once +elif [ "${{boot_indeterminate}}" = "1" ]; then + set boot_indeterminate=2 +fi +# Reset boot_success for current boot +set boot_success=0 +save_env boot_success boot_indeterminate +### END /etc/grub.d/10_reset_boot_success ### + +### BEGIN /etc/grub.d/12_menu_auto_hide ### +if [ x$feature_timeout_style = xy ] ; then + if [ "${{menu_show_once}}" ]; then + unset menu_show_once + save_env menu_show_once + set timeout_style=menu + set timeout=60 + elif [ "${{menu_auto_hide}}" -a "${{menu_hide_ok}}" = "1" ]; then + set orig_timeout_style=${{timeout_style}} + set orig_timeout=${{timeout}} + if [ "${{fastboot}}" = "1" ]; then + # timeout_style=menu + timeout=0 avoids the countdown code keypress check + set timeout_style=menu + set timeout=0 + else + set timeout_style=hidden + set timeout=1 + fi + fi +fi +### END /etc/grub.d/12_menu_auto_hide ### + +### BEGIN /etc/grub.d/20_linux_xen ### +### END /etc/grub.d/20_linux_xen ### + +### BEGIN /etc/grub.d/20_ppc_terminfo ### +### END /etc/grub.d/20_ppc_terminfo ### + +### BEGIN /etc/grub.d/30_uefi-firmware ### +### END /etc/grub.d/30_uefi-firmware ### + +### BEGIN /etc/grub.d/40_custom ### +# This file provides an easy way to add custom menu entries. Simply type the +# menu entries you want to add after this comment. Be careful not to change +# the 'exec tail' line above. +### END /etc/grub.d/40_custom ### + +### BEGIN /etc/grub.d/41_custom ### +if [ -f ${{config_directory}}/custom.cfg ]; then + source ${{config_directory}}/custom.cfg +elif [ -z "${{config_directory}}" -a -f $prefix/custom.cfg ]; then + source $prefix/custom.cfg; +fi +### END /etc/grub.d/41_custom ### +"# + )?; + Ok(()) +} +/* endregion */ + +/* region: 00bootup */ +// 00bootup/global.cfg +pub(crate) fn gen_global_cfg(file: &mut File, pxe_config: &BootupConfig) -> Result<()> { + writeln!(file, +r#"# rootfs file name +rootfs_name={} + +# select the target disk to install kubeOS +disk={} + +# pxe server ip address where stores the rootfs on the http server +server_ip={} +# target machine ip +local_ip={} +# target machine route +route_ip={} +# target machine netmask +netmask={} +# target machine netDevice name +net_name={} +"#, + pxe_config.rootfs_name, + pxe_config.disk, + pxe_config.server_ip, + pxe_config.local_ip, + pxe_config.route_ip, + pxe_config.netmask, + pxe_config.net_name + )?; + Ok(()) +} + +// 00bootup/module-setup.sh +pub(crate) fn gen_module_setup(file: &mut File) -> Result<()> { + writeln!(file, +r#"#!/bin/bash + +check() {{ + return 0 +}} + +depends() {{ + echo systemd +}} + +install() {{ + inst_multiple -o grub2-mkimage mkfs.ext4 mkfs.vfat lsblk tar cpio gunzip lspci parted dhclient ifconfig curl hwinfo head tee arch df awk route + inst_hook mount 00 "$moddir/mount.sh" + inst_simple "$moddir/mount.sh" "/mount.sh" + inst_simple "$moddir/Global.cfg" "/Global.cfg" +}} + +installkernel() {{ + hostonly='' + instmods='drivers/ata drivers/nvme drivers/scsi drivers/net fs/fat fs/nls' +}} +"# + )?; + Ok(()) +} + +// 00bootup/mount.sh +pub(crate) fn gen_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"#!/bin/bash +arch=$(arch) +min_size=8 +log=/install.log + +source ./Global.cfg + +function CheckSpace() {{ + local disk_ava + disk_ava="$(parted -l | grep "${{disk}}" | awk '{{print $3}}')" + if echo "${{disk_ava}}" | grep "[GT]B$"; then + if echo "${{disk_ava}}" | grep GB$; then + disk_ava="$(echo "${{disk_ava}}" | awk -F G '{{print $1}}' | awk -F . '{{print $1}}')" + if [ "${{disk_ava}}" -lt ${{min_size}} ]; then + echo "The available disk space is not enough, at least ${{min_size}}GB." | tee -a ${{log}} + return 1 + fi + fi + else + echo "The available disk space is not enough, at least ${{min_size}}G." | tee -a ${{log}} + return 1 + fi + + return 0 +}} + +function mount_proc_dev_sys() {{ + local tmp_root=$1 + mount -t proc none "${{tmp_root}}/proc" + mount --bind /dev "${{tmp_root}}/dev" + mount --bind /dev/pts "${{tmp_root}}/dev/pts" + mount -t sysfs none "${{tmp_root}}/sys" +}} + +function GetDisk() {{ + mapfile -t disks < <(hwinfo --disk --short 2>&1 | grep -vi "^disk" | awk '{{print $1}}') + if [ ${{#disks[*]}} -gt 0 ]; then + if [ -n "${{disk}}" ] && echo "${{disks[@]}}" | grep -wq "${{disk}}" ; then + echo "${{disk}} exists, start partition" | tee -a ${{log}} + else + echo "disk not exist, please choose correct disk" | tee -a ${{log}} + fi + else + echo "no disk found" | tee -a ${{log}} + return 1 + fi + CheckSpace + local status=$? + if [ $status -ne 0 ]; then + echo "no enough space on ${{disk}}" | tee -a ${{log}} + return 1 + fi + + return 0 +}} + +function PartitionAndFormatting() {{ + echo "Partitioning and formatting disk $disk..." + # partition and format + parted "${{disk}}" -s mklabel gpt >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + parted "${{disk}}" -s mkpart primary fat16 1M 100M >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + parted "${{disk}}" -s mkpart primary ext4 100M 2600M >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + parted "${{disk}}" -s mkpart primary ext4 2600M 5100M >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + parted "${{disk}}" -s mkpart primary ext4 5100M 100% >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + parted "${{disk}}" -s set 1 boot on >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "partition failed" | tee -a ${{log}} + return 1 + fi + + mkfs.vfat -n "BOOT" "${{disk}}"1 >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "format failed" | tee -a ${{log}} + return 1 + fi + + mkfs.ext4 -L "ROOT-A" "${{disk}}"2 >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "format failed" | tee -a ${{log}} + return 1 + fi + + mkfs.ext4 -L "ROOT-B" "${{disk}}"3 >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "format failed" | tee -a ${{log}} + return 1 + fi + + mkfs.ext4 -L "PERSIST" "${{disk}}"4 >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "format failed" | tee -a ${{log}} + return 1 + fi + + return 0 +}} + +function InitNetwork() {{ + echo "Initializing network..." + mapfile -t netNames < <(ifconfig -a | awk '{{print $1}}' | grep : | grep '^e' | awk -F: '{{print $1}}') + if [ ${{#netNames[*]}} -gt 0 ]; then + if [ -n "${{net_name}}" ] && echo "${{netNames[@]}}" | grep -wq "${{net_name}}" ; then + echo "${{net_name}} exists, start set ip" | tee -a ${{log}} + else + echo "net_name not exist, choose default net" | tee -a ${{log}} + net_name=${{netNames[0]}} + fi + else + echo "no net Device found" | tee -a ${{log}} + return 1 + fi + + ifconfig "${{net_name}}" up + local status=$? + if [ $status -ne 0 ]; then + echo "load net card failed" | tee -a ${{log}} + return 1 + fi + sleep 3 + + ifconfig "${{net_name}}" "${{local_ip}}" netmask "${{netmask}}" >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "ip set failed" | tee -a ${{log}} + return 1 + fi + sleep 3 + + route add default gw "${{route_ip}}" >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "add route failed" | tee -a ${{log}} + return 1 + fi + sleep 3 + return 0 +}} + +function MountRoot() {{ + echo "Mounting rootfs..." + # mount rootfs + mount "${{disk}}"2 /sysroot >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "mount rootfs failed" | tee -a ${{log}} + return 1 + fi + + return 0 +}} + +function MountPersist() {{ + echo "Mounting persist" + mount "${{disk}}"4 /sysroot/persist >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "mount persist failed" | tee -a ${{log}} + return 1 + fi + mkdir /sysroot/persist/{{var,etc,etcwork}} + mkdir -p /sysroot/persist/etc/KubeOS/certs + return 0 +}} + +function MountBoot() {{ + echo "Mounting boot" + mkdir -p /sysroot/boot/efi + mount "${{disk}}"1 /sysroot/boot/efi >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "mount boot failed" | tee -a ${{log}} + return 1 + fi + return 0 +}} + +function GetRootfs() {{ + echo "Downloading rootfs..." + + curl -o /"${{rootfs_name}}" http://"${{server_ip}}"/"${{rootfs_name}}" + if [ ! -e "/${{rootfs_name}}" ]; then + echo "download rootfs failed" | tee -a ${{log}} + return 1 + fi + + tar -xf /"${{rootfs_name}}" -C /sysroot + local status=$? + if [ $status -ne 0 ]; then + echo "decompose rootfs failed" | tee -a ${{log}} + return 1 + fi + + rm -rf "${{rootfs_name:?}}" + mount -o remount,ro "${{disk}}"2 /sysroot >> ${{log}} 2>&1 + return 0 +}} + +function Inst_Grub2_x86() {{ + # copy the files that boot need + cp -r /sysroot/usr/lib/grub/x86_64-efi /sysroot/boot/efi/EFI/openEuler + eval "grub2-mkimage -d /sysroot/usr/lib/grub/x86_64-efi -O x86_64-efi --output=/sysroot/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "grub2-mkimage on x86 failed" | tee -a ${{log}} + return 1 + fi + + mkdir -p /sysroot/boot/efi/EFI/BOOT/ + cp -f /sysroot/boot/efi/EFI/openEuler/grubx64.efi /sysroot/boot/efi/EFI/BOOT/BOOTX64.EFI + + return 0 +}} + +function Inst_Grub2_aarch64() {{ + cp -r /sysroot/usr/lib/grub/arm64-efi /sysroot/boot/efi/EFI/openEuler/ + eval "grub2-mkimage -d /sysroot/usr/lib/grub/arm64-efi -O arm64-efi --output=/sysroot/boot/efi/EFI/openEuler/grubaa64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" >> ${{log}} 2>&1 + local status=$? + if [ $status -ne 0 ]; then + echo "grub2-mkimage on aarch64 failed" | tee -a ${{log}} + return 1 + fi + + mkdir -p /sysroot/boot/efi/EFI/BOOT/ + cp -f /sysroot/boot/efi/EFI/openEuler/grubaa64.efi /sysroot/boot/efi/EFI/BOOT/BOOTAA64.EFI + + return 0 +}} + +function SetBoot() {{ + # mount boot + echo "Setting boot" + + if [ "$arch" == "x86_64" ]; then + Inst_Grub2_x86 + local status=$? + if [ $status -ne 0 ]; then + echo "install grub on x86 failed" | tee -a ${{log}} + return 1 + fi + fi + + if [ "$arch" == "aarch64" ]; then + Inst_Grub2_aarch64 + local status=$? + if [ $status -ne 0 ]; then + echo "install grub on aarch64 failed" | tee -a ${{log}} + return 1 + fi + fi + sed -i 's#/dev/sda#'"${{disk}}"'#g' /sysroot/boot/efi/EFI/openEuler/grub.cfg + + return 0 +}} + +function Bootup_Main() {{ + # get disk + echo "Checking disk info..." | tee -a ${{log}} + GetDisk + local status=$? + if [ $status -ne 0 ]; then + echo "Checking disk info failed" | tee -a ${{log}} + return 1 + fi + + # partition and format disk + echo "Partion and formatting..." | tee -a ${{log}} + PartitionAndFormatting + local status=$? + if [ $status -ne 0 ]; then + echo "Partition and formatting disk failed" | tee -a ${{log}} + return 1 + fi + + # init network + echo "Initializing network..." | tee -a ${{log}} + InitNetwork + local status=$? + if [ $status -ne 0 ]; then + echo "Initializing network failed" | tee -a ${{log}} + return 1 + fi + + # mount partitions + + # mount boot + echo "Mounting root..." | tee -a ${{log}} + MountRoot + local status=$? + if [ $status -ne 0 ]; then + echo "Mounting root failed" | tee -a ${{log}} + return 1 + fi + + echo "Mounting boot..." | tee -a ${{log}} + MountBoot + local status=$? + if [ $status -ne 0 ]; then + echo "Mounting boot failed" | tee -a ${{log}} + return 1 + fi + + # download rootfs + echo "Downloading rootfs..." | tee -a ${{log}} + GetRootfs + local status=$? + if [ $status -ne 0 ]; then + echo "Downloading rootfs failed" | tee -a ${{log}} + return 1 + fi + mount_proc_dev_sys /sysroot + # set boot + echo "Setting boot..." | tee -a ${{log}} + SetBoot + local status=$? + if [ $status -ne 0 ]; then + echo "Setting boot failed" | tee -a ${{log}} + return 1 + fi + # mount persist + echo "Mounting persist..." | tee -a ${{log}} + MountPersist + local status=$? + if [ $status -ne 0 ]; then + echo "Mounting persist failed" | tee -a ${{log}} + return 1 + fi + return 0 +}} + +Bootup_Main +ret=$? +if [ ${{ret}} -eq 0 ]; then + echo "kubeOS install success! switch to root" | tee -a ${{log}} + cp ${{log}} /sysroot/persist +else + echo "kubeOS install failed, see install.log" | tee -a ${{log}} +fi + +"# + )?; + Ok(()) +} +/* endregion */ + +/* region: dockerfile */ +pub(crate) fn gen_dockerfile(file: &mut File) -> Result<()> { + writeln!(file, +r#"FROM scratch +COPY os.tar / +CMD ["/bin/sh"] +"# + )?; + Ok(()) +} +/* endregion */ + +/* region: admin-container */ +// admin-container/dockerfile +pub(crate) fn gen_admin_dockerfile(file: &mut File) -> Result<()> { + writeln!(file, +r#"FROM openeuler-22.03-lts +MAINTAINER + +RUN yum -y install openssh-clients util-linux + +ADD ./sysmaster-0.2.3-1.oe2203.aarch64.rpm /home +RUN rpm -ivh /home/sysmaster-0.2.3-1.oe2203.aarch64.rpm + +COPY ./hostshell /usr/bin/ +COPY ./set-ssh-pub-key.sh /usr/local/bin +COPY ./set-ssh-pub-key.service /usr/lib/sysmaster + +EXPOSE 22 +# set sshd.service and set-ssh-pub-key.service pulled up by default +RUN sed -i 's/sysinit.target/sysinit.target;sshd.service;set-ssh-pub-key.service/g' /usr/lib/sysmaster/basic.target + +CMD ["/usr/lib/sysmaster/init"] +"# + )?; + Ok(()) +} + +// admin-container/set-ssh-pub-key.service +pub(crate) fn gen_set_ssh_pub_key_service(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description="set ssh authorized keys according to the secret which is set by user" + +[Service] +ExecStart="/usr/local/bin/set-ssh-pub-key.sh" +"# + )?; + Ok(()) +} + +// admin-container/set-ssh-pub-key.sh +pub(crate) fn gen_set_ssh_pub_key(file: &mut File) -> Result<()> { + writeln!(file, +r#"ssh_pub=$(cat /etc/secret-volume/ssh-pub-key) +ssh_dir="/root/.ssh" +authorized_file="$ssh_dir/authorized_keys" + +if [ ! -d "$ssh_dir" ]; then + mkdir "$ssh_dir" + chmod 700 "$ssh_dir" +fi + +if [ ! -f "$authorized_file" ]; then + touch "$authorized_file" + chmod 600 "$authorized_file" +fi + +echo "$ssh_pub" >> "$authorized_file" +"# + )?; + Ok(()) +} +/* endregion */ + +/* region: misc-files */ +// misc-files/boot-efi.mount +pub(crate) fn gen_boot_efi_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=grub2 Dir +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target + +[Mount] +What=/dev/disk/by-label/BOOT +Where=/boot/efi +Type=vfat +Options=defaults + +[Install] +WantedBy=local-fs.target +"# + )?; + Ok(()) +} + +// misc-files/boot-grub2.mount +pub(crate) fn gen_boot_grub2_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=grub2 Dir +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target + +[Mount] +What=/dev/disk/by-label/GRUB2 +Where=/boot/grub2 +Type=ext4 +Options=defaults + +[Install] +WantedBy=local-fs.target +"# + )?; + Ok(()) +} + +// misc-files/etc.mount +pub(crate) fn gen_etc_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=etc Dir +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target +Wants=persist.mount +After=persist.mount + +[Mount] +What=overlay +Where=/etc +Type=overlay +Options=upperdir=/persist/etc,lowerdir=/etc,workdir=/persist/etcwork + +[Install] +WantedBy=local-fs.target +"# + )?; + Ok(()) +} + +// misc-files/os-agent.service +pub(crate) fn gen_os_agent_service(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=Agent For KubeOS + +[Service] +Environment=GOTRACEBACK=crash +ExecStart=/usr/bin/os-agent +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target +"# + )?; + Ok(()) +} + +// misc-files/os-release +pub(crate) fn gen_os_release(file: &mut File) -> Result<()> { + writeln!(file, +r#"NAME=KubeOS +ID=KubeOS +"# + )?; + Ok(()) +} + +// misc-files/persist.mount +pub(crate) fn gen_persist_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=PERSIST Dir (/persist) +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target + +[Mount] +What=/dev/disk/by-label/PERSIST +Where=/persist +Type=ext4 +Options=defaults + +[Install] +WantedBy=local-fs.target +"# + )?; + Ok(()) +} + +// misc-files/var.mount +pub(crate) fn gen_var_mount(file: &mut File) -> Result<()> { + writeln!(file, +r#"[Unit] +Description=var Dir +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target +Wants=persist.mount +After=persist.mount + +[Mount] +What=/persist/var +Where=/var +Type=node +Options=bind + +[Install] +WantedBy=local-fs.target +"# + )?; + Ok(()) +} +/* endregion */ \ No newline at end of file diff --git a/KubeOS-Rust/kbimg/src/utils.rs b/KubeOS-Rust/kbimg/src/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..3ef27b7bb39498bc546a25707706a9f538b84621 --- /dev/null +++ b/KubeOS-Rust/kbimg/src/utils.rs @@ -0,0 +1,129 @@ +use std::path::PathBuf; +use std::process::Command; +use std::fs; +use std::os::unix::fs::PermissionsExt; +use anyhow::bail; + +use crate::commands::BootupConfig; + +pub(crate) fn execute_scripts(script: PathBuf) -> anyhow::Result<()> { + if !script.exists() { + bail!("Script does not exist: {:?}", script); + } + let status = Command::new("bash").arg(&script).status()?; + if !status.success() { + bail!("Failed to execute script: {}\n", script.display()); + } + Ok(()) +} + +// pub(crate) fn write_vector_to_file(scripts: Vec, file_name: &str) -> anyhow::Result<()> { +// debug!("Writing scripts to file: {:?}", file_name); +// let mut file = File::create(file_name)?; +// // set permissions based on regulation +// for line in scripts { +// writeln!(file, "{}", line)?; +// } +// Ok(()) +// } + +pub(crate) fn set_permissions(path: &str, permission_value: u32) -> anyhow::Result<()> { + let metadata = fs::metadata(path)?; + let mut permissions = metadata.permissions(); + permissions.set_mode(permission_value); + fs::set_permissions(path, permissions)?; + Ok(()) +} + +/// Check if the input parameter is valid +pub(crate) fn is_valid_param + std::fmt::Debug>(param: S) -> bool { + let special_chars = vec!["|", ";", "&", "&&", "||", ">", ">>", "<", ",", "#", "!", "$"]; + !param.as_ref().chars().any(|c| special_chars.contains(&c.to_string().as_str())) +} + +/// Check if the path exists and is indeed a file +pub(crate) fn is_file_valid(msg: &str, path: &PathBuf) -> anyhow::Result<()> { + if !path.exists() { + bail!("{} does not exist: {:?}", msg, path); + } + if !path.is_file() { + bail!("{} exists but is not a file: {:?}", msg, path); + } + Ok(()) +} + +/// Check if addr is valid +pub(crate) fn is_addr_valid(addr: &str) -> bool { + let ip_pattern = regex::Regex::new(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$").unwrap(); + if !ip_pattern.is_match(addr) { + return false; + } + + for quad in addr.split('.') { + if let Ok(num) = quad.parse::() { + if num <= 255 { + continue; + } + } + return false; + } + + true +} + +/// Check pxe config +pub(crate) fn check_pxe_conf_valid(pxe_config: &BootupConfig) -> anyhow::Result<()> { + if !is_addr_valid(&pxe_config.server_ip) { + bail!("address {} is invalid, please check input", &pxe_config.server_ip); + } + if !is_addr_valid(&pxe_config.local_ip) { + bail!("address {} is invalid, please check input", &pxe_config.local_ip); + } + if !is_addr_valid(&pxe_config.route_ip) { + bail!("address {} is invalid, please check input", &pxe_config.route_ip); + } + if !is_addr_valid(&pxe_config.netmask) { + bail!("address {} is invalid, please check input", &pxe_config.netmask); + } + Ok(()) +} + +/// Get architecture +pub(crate) fn get_arch() -> String { + let output = std::process::Command::new("arch") + .output() + .expect("Failed to execute `arch` command"); + + String::from_utf8_lossy(&output.stdout).trim().to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + fn init() { + let _ = env_logger::builder() + .target(env_logger::Target::Stdout) + .filter_level(log::LevelFilter::Trace) + .is_test(true) + .try_init(); + } + + #[test] + fn test_is_valid_param() { + init(); + assert_eq!(is_valid_param("test"), true); + assert_eq!(is_valid_param("test|test"), false); + assert_eq!(is_valid_param("test;test"), false); + assert_eq!(is_valid_param("test&test"), false); + assert_eq!(is_valid_param("test&&test"), false); + assert_eq!(is_valid_param("test||test"), false); + assert_eq!(is_valid_param("test>test"), false); + assert_eq!(is_valid_param("test>>test"), false); + assert_eq!(is_valid_param("test -### 参数说明 ### +### 配置文件说明 ### -* COMMANDS +* from_repo: 从 repo 创建 OCI 镜像、虚拟机镜像或物理机镜像 - | 参数 | 描述 | - |------------------------------| ---------------------------------------------- | - | upgrade-image | 生成用于安装和升级的OCI镜像格式的 KubeOS 镜像 | - | vm-image | 生成用于部署和升级的虚拟机镜像 | - | pxe-image | 生成物理机安装所需的镜像及文件 | + | 参数 | 描述 | + | --- | --- | + | agent_path | os-agent 二进制的路径 | + | image_type | upgrade: 用于安装和升级的 OCI 镜像格式的 KubeOS 镜像; vm-repo: 用于部署和升级的虚拟机镜像; pxe-repo: 物理机安装所需的镜像及文件 | + | legacy_bios | 镜像为 legacy 引导或 UEFI 引导 | + | repo_path | repo 文件的路径,repo 文件中配置制作镜像所需要的 yum 源 | + | root_passwd | KubeOS 镜像 root 用户密码,加密后的带盐值的密码,可以用 openssl、kiwi 命令生成 | + | version | 制作出来的 KubeOS 镜像的版本 | + | rpmlist | 镜像所需的 rpm 包 | + | docker_img | 生成或者使用的 docker 镜像 | +* from_docker: 从 docker 镜像创建虚拟机镜像或物理机镜像 + | 参数 | 描述 | + | --- | --- | + | docker_img | 生成或者使用的 docker 镜像 | + | image_type | vm-docker: 用于部署和升级的虚拟机镜像; pxe-docker: 物理机安装所需的镜像及文件 | -* OPTIONS +* admin_container: - | 参数 | 描述 | - | ------------ | ------------------------------------------------------------ | - | -p | repo 文件的路径,repo 文件中配置制作镜像所需要的 yum 源 | - | -v | 制作出来的KubeOS镜像的版本 | - | -b | os-agent二进制的路径 | - | -e | KubeOS 镜像 root 用户密码,加密后的带盐值的密码,可以用 openssl,kiwi 命令生成 | - | -d | 生成或者使用的 docke r镜像 | - | -l | 如果指定参数,则镜像为legacy引导,不指定默认是UEFI引导 | - | -h --help | 查看帮助信息 | + | 参数 | 描述 | + | --- | --- | + | dockerfile | dockerfile 路径 | + | docker_img | 生成或者使用的 docker 镜像 | +* [OPTIONAL] users: 添加用户 + | 参数 | 描述 | + | --- | --- | + | groups | [OPTIONAL] 用户组 (第一个为主组,其他为附加组) | + | name | 用户名 | + | passwd | 密码 | + | sudo | [OPTIONAL] 用户是否具有 sudo 权限 | + +* [OPTIONAL] copy_files: 拷贝文件到指定目录 + + | 参数 | 描述 | + | --- | --- | + | dst | 目标目录 | + | src | 源文件路径 | + +* [OPTIONAL] grub: grub配置 + + | 参数 | 描述 | + | --- | --- | + | passwd | [OPTIONAL] grub 密码 | + +* [OPTIONAL] systemd_service: 新增 systemd 服务 + + | 参数 | 描述 | + | --- | --- | + | name | systemd 服务名 | + +* [OPTIONAL] chroot_script: 自定义 chroot 脚本 + + | 参数 | 描述 | + | --- | --- | + | path | 脚本路径 | + +* [OPTIONAL] disk_partition: 自定义分区大小和镜像大小 + + | 参数 | 描述 | + | --- | --- | + | first | 引导分区大小 | + | second | ROOT-A 分区大小 | + | third | ROOT-B 分区大小 | + | img_size | 镜像大小 | + +* [OPTIONAL] persist_mkdir: persist 分区新建目录 + + | 参数 | 描述 | + | --- | --- | + | name | 目录名 | ## 使用说明 ## @@ -43,6 +95,82 @@ kbimg是KubeOS部署和升级所需的镜像制作工具,可以使用kbimg制 * kbimg.sh 执行需要 root 权限 * 当前仅支持 x86和 AArch64 架构使用 * 容器 OS 镜像制作工具的 rpm 包源为 openEuler 具体版本的 everything 仓库和 EPOL 仓库。制作镜像时提供的 repo 文件中,yum 源建议同时配置 openEuler 具体版本的 everything 仓库和 EPOL 仓库 +* 新增 systemd 服务需要将对应的 .service 文件或 .mount 文件拷贝至镜像```/usr/lib/systemd/system```目录 + + ```toml + [[copy_files]] + dst = "/usr/lib/systemd/system" + src = ".../containerd.service" + + [systemd_service] + name = ["containerd"] + ``` + + * 如需挂载数据盘,请先自定义```persist-data.mount```文件,并启用```copy_files```和```systemd_service```字段设置启动时挂载,启用```persist_mkdir```字段创建挂载点 + * .mount文件名由挂载点路径生成,将斜杠替换为连字符 + * 请先在磁盘映像文件上创建ext4文件系统 + + ``` + # persist-data.mount + [Unit] + Description=Mount Disk + Documentation=man:systemd.mount(5) + + [Mount] + What=/dev/vdb + Where=/persist/data + Type=ext4 + Options=defaults,noatime + + [Install] + WantedBy=local-fs.target + ``` + + ```toml + [[copy_files]] + dst = "/usr/lib/systemd/system" + src = ".../persist-data.mount" + + [systemd_service] + name = ["persist-data.mount"] + + [persist_mkdir] + name = ["data"] + ``` + + * 如需配置逻辑卷,请先自定义```volume.service```文件,并启用```copy_files```和```systemd_service```设置启动时配置逻辑卷,启用```persist_mkdir```字段创建挂载点 + + ``` + # volume.service + [Unit] + Description=Mount Logical Volume + After=local-fs.target + + [Service] + Type=oneshot + RemainAfterExit=yes + ExecStart=pvcreate /dev/vdb + ExecStart=pvcreate /dev/vdc + ExecStart=vgcreate my_vg /dev/vdb /dev/vdc + ExecStart=lvcreate -L 15G -n my_lv my_vg + ExecStart=mkfs.ext4 /dev/my_vg/my_lv + ExecStart=mount /dev/my_vg/my_lv /persist/lv_data + + [Install] + WantedBy=local-fs.target + ``` + + ```toml + [[copy_files]] + dst = "/usr/lib/systemd/system" + src = ".../volume.service" + + [systemd_service] + name = ["volume"] + + [persist_mkdir] + name = ["lv_data"] + ``` ### KubeOS OCI 镜像制作 ### @@ -52,23 +180,40 @@ kbimg是KubeOS部署和升级所需的镜像制作工具,可以使用kbimg制 * 使用默认 rpmlist 进行容器OS镜像制作时所需磁盘空间至少为6G,如自已定义 rpmlist 可能会超过6G #### 使用示例 #### -* 如需进行DNS配置,请先在```scripts```目录下自定义```resolv.conf```文件 -```shell - cd /opt/kubeOS/scripts - touch resolv.conf - vim resolv.conf -``` + +* 如需进行DNS配置,请先自定义```resolv.conf```文件,并启用```copy_files```字段将配置文件拷贝到```/etc```目录 + + ```shell + touch \/resolv.conf + vim \resolv.conf + ``` + + ```toml + [[copy_files]] + dst = "/etc" + src = "" + ``` + * 制作KubeOS容器镜像 -``` shell -cd /opt/kubeOS/scripts -bash kbimg.sh create upgrade-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' -d your_imageRepository/imageName:version -``` -* 制作完成后查看制作出来的KubeOS容器镜像 + ```toml + [from_repo] + agent_path = "/bin/os-agent" + image_type = "upgrade" + legacy_bios = false + repo_path = "xxx.repo" + root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" + version = "v1" + docker_img = "your_imageRepository/imageName:version" + rpmlist = [ + # your rpms + ] + ``` -``` shell -docker images -``` +* 制作完成后查看制作出来的KubeOS容器镜像 + ``` shell + docker images + ``` ### KubeOS 虚拟机镜像制作 ### @@ -82,26 +227,45 @@ docker images #### 使用示例 #### * 使用repo源制作 - * 如需进行DNS配置,请先在```scripts```目录下自定义```resolv.conf```文件 - ```shell - cd /opt/kubeOS/scripts - touch resolv.conf - vim resolv.conf - ``` + + * 如需进行DNS配置,请先自定义```resolv.conf```文件,并启用**copy_files**字段将配置文件拷贝到```/etc```目录 + + ```shell + touch \/resolv.conf + vim \resolv.conf + ``` + + ```toml + [[copy_files]] + dst = "/etc" + src = "" + ``` + * KubeOS虚拟机镜像制作 - ``` shell - cd /opt/kubeOS/scripts - bash kbimg.sh create vm-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' - ``` + + ```toml + [from_repo] + agent_path = "/bin/os-agent" + image_type = "vm-repo" + legacy_bios = false + repo_path = "xxx.repo" + root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" + version = "v1" + rpmlist = [ + # your rpms + ] + ``` * 使用docker镜像制作 - ``` shell - cd /opt/kubeOS/scripts - bash kbimg.sh create vm-image -d your_imageRepository/imageName:version + ```toml + [from_dockerimg] + docker_img = "your_imageRepository/imageName:version" + image_type = "vm-docker" ``` + * 结果说明 - 容器 OS 镜像制作完成后,会在 /opt/kubeOS/scripts 目录下生成: + 容器 OS 镜像制作完成后,会在 KubeOS-Rust/kbimg/scripts-auto 目录下生成: * system.qcow2: qcow2 格式的系统镜像,大小默认为 20GiB,支持的根文件系统分区大小 < 2020 MiB,持久化分区 < 16GiB 。 * update.img: 用于升级的根文件系统分区镜像 @@ -116,44 +280,54 @@ docker images * 不支持多个磁盘都安装KubeOS,可能会造成启动失败或挂载紊乱 * 容器OS 目前不支持 x86 架构的物理机使用 legacy 启动模式启动 * 使用默认rpmlist进行镜像制作时所需磁盘空间至少为5G,如自已定义 rpmlist 可能会超过5G + #### 使用示例 #### -* 首先需要修改```00bootup/Global.cfg```的配置,对相关参数进行配置,参数均为必填,ip目前仅支持ipv4,配置示例如下 +* 首先需要修改```values.rs```中```bootup config```的配置,对相关参数进行配置,参数均为必填,ip目前仅支持ipv4,配置示例如下 - ```shell - # rootfs file name - rootfs_name=kubeos.tar - # select the target disk to install kubeOS - disk=/dev/sda - # pxe server ip address where stores the rootfs on the http server - server_ip=192.168.1.50 - # target machine temporary ip - local_ip=192.168.1.100 - # target machine temporary route - route_ip=192.168.1.1 - # target machine temporary netmask - netmask=255.255.255.0 - # target machine netDevice name - net_name=eth0 + ```rust + pub(crate) const ROOTFS_NAME: &str = "kubeos.tar"; + pub(crate) const DISK: &str = "/dev/sda"; + pub(crate) const SERVER_IP: &str = "192.168.1.50"; + pub(crate) const LOCAL_IP: &str = "192.168.1.100"; + pub(crate) const ROUTE_IP: &str = "192.168.1.1"; + pub(crate) const NETMASK: &str = "255.255.255.0"; + pub(crate) const NET_NAME: &str = "eth0"; ``` * 使用 repo 源制作 - * 如需进行DNS配置,请在```scripts```目录下自定义```resolv.conf```文件 - ```shell - cd /opt/kubeOS/scripts - touch resolv.conf - vim resolv.conf - ``` - * KubeOS物理机安装所需镜像制作 - ``` - cd /opt/kubeOS/scripts - bash kbimg.sh create pxe-image -p xxx.repo -v v1 -b ../bin/os-agent -e '''$1$xyz$RdLyKTL32WEvK3lg8CXID0''' - ``` + * 如需进行DNS配置,请先自定义```resolv.conf```文件,并启用```copy_files```字段将配置文件拷贝到```/etc```目录 + + ```shell + touch \/resolv.conf + vim \resolv.conf + ``` + + ```toml + [[copy_files]] + dst = "/etc" + src = "" + ``` + + * KubeOS物理机安装所需镜像制作 + ```toml + [from_repo] + agent_path = "/bin/os-agent" + image_type = "pxe-repo" + legacy_bios = true + repo_path = "xxx.repo" + root_passwd = "$1$xyz$RdLyKTL32WEvK3lg8CXID0" + version = "v1" + rpmlist = [ + # your rpms + ] + ``` * 使用 docker 镜像制作 - ``` shell - cd /opt/kubeOS/scripts - bash kbimg.sh create pxe-image -d your_imageRepository/imageName:version + ```toml + [from_dockerimg] + docker_img = "your_imageRepository/imageName:version" + image_type = "vm-docker" ``` * 结果说明 diff --git a/files/boot-efi.mount b/files/boot-efi.mount deleted file mode 100644 index cd0e79b7bba0cb2e9f1d608cbbcbf7fd5a95e3b1..0000000000000000000000000000000000000000 --- a/files/boot-efi.mount +++ /dev/null @@ -1,24 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description=grub2 Dir -DefaultDependencies=no -Conflicts=umount.target -Before=local-fs.target umount.target - -[Mount] -What=/dev/disk/by-label/BOOT -Where=/boot/efi -Type=vfat -Options=defaults - -[Install] -WantedBy=local-fs.target diff --git a/files/boot-grub2.mount b/files/boot-grub2.mount deleted file mode 100644 index e6c4150066c5c847e2e5fb9d97ab7e06abb014e0..0000000000000000000000000000000000000000 --- a/files/boot-grub2.mount +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=grub2 Dir -DefaultDependencies=no -Conflicts=umount.target -Before=local-fs.target umount.target - -[Mount] -What=/dev/disk/by-label/GRUB2 -Where=/boot/grub2 -Type=ext4 -Options=defaults - -[Install] -WantedBy=local-fs.target diff --git a/files/etc.mount b/files/etc.mount deleted file mode 100644 index 7501f78a5558abc902d0ecdaafad1353fe8fd083..0000000000000000000000000000000000000000 --- a/files/etc.mount +++ /dev/null @@ -1,26 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description=etc Dir -DefaultDependencies=no -Conflicts=umount.target -Before=local-fs.target umount.target -Wants=persist.mount -After=persist.mount - -[Mount] -What=overlay -Where=/etc -Type=overlay -Options=upperdir=/persist/etc,lowerdir=/etc,workdir=/persist/etcwork - -[Install] -WantedBy=local-fs.target diff --git a/files/os-agent.service b/files/os-agent.service deleted file mode 100644 index f77880499b5e759537e861c87ee50d121df498cc..0000000000000000000000000000000000000000 --- a/files/os-agent.service +++ /dev/null @@ -1,21 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description=Agent For KubeOS - -[Service] -Environment=GOTRACEBACK=crash -ExecStart=/usr/bin/os-agent -KillMode=process -Restart=on-failure - -[Install] -WantedBy=multi-user.target diff --git a/files/os-release b/files/os-release deleted file mode 100644 index e55b57caaad92766c0f7919fb215be773dbc378b..0000000000000000000000000000000000000000 --- a/files/os-release +++ /dev/null @@ -1,2 +0,0 @@ -NAME=KubeOS -ID=KubeOS diff --git a/files/persist.mount b/files/persist.mount deleted file mode 100644 index edc46d2b13bcd423c369ae7516ff49dd63c734b3..0000000000000000000000000000000000000000 --- a/files/persist.mount +++ /dev/null @@ -1,24 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description=PERSIST Dir (/persist) -DefaultDependencies=no -Conflicts=umount.target -Before=local-fs.target umount.target - -[Mount] -What=/dev/disk/by-label/PERSIST -Where=/persist -Type=ext4 -Options=defaults - -[Install] -WantedBy=local-fs.target diff --git a/files/var.mount b/files/var.mount deleted file mode 100644 index 4343207d007da47c235286b91ae9be61242825df..0000000000000000000000000000000000000000 --- a/files/var.mount +++ /dev/null @@ -1,26 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description=var Dir -DefaultDependencies=no -Conflicts=umount.target -Before=local-fs.target umount.target -Wants=persist.mount -After=persist.mount - -[Mount] -What=/persist/var -Where=/var -Type=node -Options=bind - -[Install] -WantedBy=local-fs.target diff --git a/scripts/00bootup/Global.cfg b/scripts/00bootup/Global.cfg deleted file mode 100644 index dd78617c1a28a14e1ffbc8bbdb7dc0dce0a74922..0000000000000000000000000000000000000000 --- a/scripts/00bootup/Global.cfg +++ /dev/null @@ -1,16 +0,0 @@ -# rootfs file name -rootfs_name=kubeos.tar - -# select the target disk to install kubeOS -disk=/dev/sda - -# pxe server ip address where stores the rootfs on the http server -server_ip=192.168.1.50 -# target machine ip -local_ip=192.168.1.100 -# target machine route -route_ip=192.168.1.1 -# target machine netmask -netmask=255.255.255.0 -# target machine netDevice name -net_name=eth0 diff --git a/scripts/00bootup/module-setup.sh b/scripts/00bootup/module-setup.sh deleted file mode 100644 index 5460b2bcd0075a90d33fbfcd01d6210e49c91333..0000000000000000000000000000000000000000 --- a/scripts/00bootup/module-setup.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -check() { - return 0 -} - -depends() { - echo systemd -} - -install() { - inst_multiple -o grub2-mkimage mkfs.ext4 mkfs.vfat lsblk tar cpio gunzip lspci parted dhclient ifconfig curl hwinfo head tee arch df awk route - inst_hook mount 00 "$moddir/mount.sh" - inst_simple "$moddir/mount.sh" "/mount.sh" - inst_simple "$moddir/Global.cfg" "/Global.cfg" -} - -installkernel() { - hostonly='' \ - instmods \ - =drivers/ata \ - =drivers/nvme \ - =drivers/scsi \ - =drivers/net \ - =fs/fat \ - =fs/nls -} - diff --git a/scripts/00bootup/mount.sh b/scripts/00bootup/mount.sh deleted file mode 100644 index 7f00fd6afe0a38fd34b34ffee88a964eacd15f38..0000000000000000000000000000000000000000 --- a/scripts/00bootup/mount.sh +++ /dev/null @@ -1,341 +0,0 @@ -#!/bin/bash -arch=$(arch) -min_size=8 -log=/install.log - -source /Global.cfg - -function CheckSpace() { - local disk_ava="$(parted -l | grep ${disk} | awk '{print $3}')" - if echo "${disk_ava}" | grep [GT]B$; then - if echo "${disk_ava}" | grep GB$; then - disk_ava="$(echo ${disk_ava} | awk -F G '{print $1}' | awk -F . '{print $1}')" - if [ "${disk_ava}" -lt ${min_size} ]; then - echo "The available disk space is not enough, at least ${min_size}GB." | tee -a ${log} - return 1 - fi - fi - else - echo "The available disk space is not enough, at least ${min_size}G." | tee -a ${log} - return 1 - fi - - return 0 -} - -function mount_proc_dev_sys() { - local tmp_root=$1 - mount -t proc none "${tmp_root}/proc" - mount --bind /dev "${tmp_root}/dev" - mount --bind /dev/pts "${tmp_root}/dev/pts" - mount -t sysfs none "${tmp_root}/sys" -} - -function GetDisk() { - disks=(`hwinfo --disk --short 2>&1 | grep -vi "^disk" | awk '{print $1}'`) - if [ ${#disks[*]} -gt 0 ]; then - if [ -n "${disk}" ] && echo "${disks[@]}" | grep -wq "${disk}" ; then - echo "${disk} exists, start partition" | tee -a ${log} - else - echo "disk not exist, please choose correct disk" | tee -a ${log} - fi - else - echo "no disk found" | tee -a ${log} - return 1 - fi - CheckSpace - if [ $? -ne 0 ]; then - echo "no enough space on ${disk}" | tee -a ${log} - return 1 - fi - - return 0 -} - -function PartitionAndFormatting() { - echo "Partitioning and formatting disk $disk..." - # partition and format - parted ${disk} -s mklabel gpt >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - parted ${disk} -s mkpart primary fat16 1M 100M >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - parted ${disk} -s mkpart primary ext4 100M 2600M >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - parted ${disk} -s mkpart primary ext4 2600M 5100M >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - parted ${disk} -s mkpart primary ext4 5100M 100% >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - parted ${disk} -s set 1 boot on >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "partition failed" | tee -a ${log} - return 1 - fi - - mkfs.vfat -n "BOOT" ${disk}1 >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "format failed" | tee -a ${log} - return 1 - fi - - mkfs.ext4 -L "ROOT-A" ${disk}2 >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "format failed" | tee -a ${log} - return 1 - fi - - mkfs.ext4 -L "ROOT-B" ${disk}3 >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "format failed" | tee -a ${log} - return 1 - fi - - mkfs.ext4 -L "PERSIST" ${disk}4 >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "format failed" | tee -a ${log} - return 1 - fi - - return 0 -} - -function InitNetwork() { - echo "Initializing network..." - netNames=(`ifconfig -a | awk '{print $1}' | grep : | grep '^e' | awk -F: '{print $1}'`) - if [ ${#netNames[*]} -gt 0 ]; then - if [ -n "${net_name}" ] && echo "${netNames[@]}" | grep -wq "${net_name}" ; then - echo "${net_name} exists, start set ip" | tee -a ${log} - else - echo "net_name not exist, choose default net" | tee -a ${log} - net_name=${netNames[0]} - fi - else - echo "no net Device found" | tee -a ${log} - return 1 - fi - - ifconfig ${net_name} up - if [ $? -ne 0 ]; then - echo "load net card failed" | tee -a ${log} - return 1 - fi - sleep 3 - - ifconfig ${net_name} ${local_ip} netmask ${netmask} >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "ip set failed" | tee -a ${log} - return 1 - fi - sleep 3 - - route add default gw ${route_ip} >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "add route failed" | tee -a ${log} - return 1 - fi - sleep 3 - return 0 -} - -function MountRoot() { - echo "Mounting rootfs..." - # mount rootfs - mount ${disk}2 /sysroot >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "mount rootfs failed" | tee -a ${log} - return 1 - fi - - return 0 -} - -function MountPersist() { - echo "Mounting persist" - mount ${disk}4 /sysroot/persist >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "mount persist failed" | tee -a ${log} - return 1 - fi - mkdir /sysroot/persist/{var,etc,etcwork} - mkdir -p /sysroot/persist/etc/KubeOS/certs - return 0 -} - -function MountBoot() { - echo "Mounting boot" - mkdir -p /sysroot/boot/efi - mount ${disk}1 /sysroot/boot/efi >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "mount boot failed" | tee -a ${log} - return 1 - fi - return 0 -} - -function GetRootfs() { - echo "Downloading rootfs..." - - curl -o /${rootfs_name} http://${server_ip}/${rootfs_name} - if [ ! -e "/${rootfs_name}" ]; then - echo "download rootfs failed" | tee -a ${log} - return 1 - fi - - tar -xf /${rootfs_name} -C /sysroot - if [ $? -ne 0 ]; then - echo "decompose rootfs failed" | tee -a ${log} - return 1 - fi - - rm -rf /${rootfs_name} - mount -o remount,ro ${disk}2 /sysroot >> ${log} 2>&1 - return 0 -} - -function Inst_Grub2_x86() { - # copy the files that boot need - cp -r /sysroot/usr/lib/grub/x86_64-efi /sysroot/boot/efi/EFI/openEuler - eval "grub2-mkimage -d /sysroot/usr/lib/grub/x86_64-efi -O x86_64-efi --output=/sysroot/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "grub2-mkimage on x86 failed" | tee -a ${log} - return 1 - fi - - mkdir -p /sysroot/boot/efi/EFI/BOOT/ - cp -f /sysroot/boot/efi/EFI/openEuler/grubx64.efi /sysroot/boot/efi/EFI/BOOT/BOOTX64.EFI - - return 0 -} - -function Inst_Grub2_aarch64() { - cp -r /sysroot/usr/lib/grub/arm64-efi /sysroot/boot/efi/EFI/openEuler/ - eval "grub2-mkimage -d /sysroot/usr/lib/grub/arm64-efi -O arm64-efi --output=/sysroot/boot/efi/EFI/openEuler/grubaa64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" >> ${log} 2>&1 - if [ $? -ne 0 ]; then - echo "grub2-mkimage on aarch64 failed" | tee -a ${log} - return 1 - fi - - mkdir -p /sysroot/boot/efi/EFI/BOOT/ - cp -f /sysroot/boot/efi/EFI/openEuler/grubaa64.efi /sysroot/boot/efi/EFI/BOOT/BOOTAA64.EFI - - return 0 -} - -function SetBoot() { - # mount boot - echo "Setting boot" - - if [ $arch == "x86_64" ]; then - Inst_Grub2_x86 - if [ $? -ne 0 ]; then - echo "install grub on x86 failed" | tee -a ${log} - return 1 - fi - fi - - if [ $arch == "aarch64" ]; then - Inst_Grub2_aarch64 - if [ $? -ne 0 ]; then - echo "install grub on aarch64 failed" | tee -a ${log} - return 1 - fi - fi - sed -i 's#/dev/sda#'${disk}'#g' /sysroot/boot/efi/EFI/openEuler/grub.cfg - - return 0 -} - -function Bootup_Main() { - # get disk - echo "Checking disk info..." | tee -a ${log} - GetDisk - if [ $? -ne 0 ]; then - echo "Checking disk info failed" | tee -a ${log} - return 1 - fi - - # partition and format disk - echo "Partion and formatting..." | tee -a ${log} - PartitionAndFormatting - if [ $? -ne 0 ]; then - echo "Partition and formatting disk failed" | tee -a ${log} - return 1 - fi - - # init network - echo "Initializing network..." | tee -a ${log} - InitNetwork - if [ $? -ne 0 ]; then - echo "Initializing network failed" | tee -a ${log} - return 1 - fi - - # mount partitions - - # mount boot - echo "Mounting root..." | tee -a ${log} - MountRoot - if [ $? -ne 0 ]; then - echo "Mounting root failed" | tee -a ${log} - return 1 - fi - - echo "Mounting boot..." | tee -a ${log} - MountBoot - if [ $? -ne 0 ]; then - echo "Mounting boot failed" | tee -a ${log} - return 1 - fi - - # download rootfs - echo "Downloading rootfs..." | tee -a ${log} - GetRootfs - if [ $? -ne 0 ]; then - echo "Downloading rootfs failed" | tee -a ${log} - return 1 - fi - mount_proc_dev_sys /sysroot - # set boot - echo "Setting boot..." | tee -a ${log} - SetBoot - if [ $? -ne 0 ]; then - echo "Setting boot failed" | tee -a ${log} - return 1 - fi - # mount persist - echo "Mounting persist..." | tee -a ${log} - MountPersist - if [ $? -ne 0 ]; then - echo "Mounting persist failed" | tee -a ${log} - return 1 - fi - return 0 -} - -Bootup_Main -ret=$? -if [ ${ret} -eq 0 ]; then - echo "kubeOS install success! switch to root" | tee -a ${log} - cp ${log} /sysroot/persist -else - echo "kubeOS install failed, see install.log" | tee -a ${log} -fi diff --git a/scripts/Dockerfile b/scripts/Dockerfile deleted file mode 100644 index 3da47081370bec1a0f3d68ad12e28474370225e4..0000000000000000000000000000000000000000 --- a/scripts/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM scratch -COPY os.tar / -CMD ["/bin/sh"] diff --git a/scripts/admin-container/Dockerfile b/scripts/admin-container/Dockerfile deleted file mode 100644 index d4ddd06246fb67f5f0f8f7f7a738f6fbbca1f58e..0000000000000000000000000000000000000000 --- a/scripts/admin-container/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -FROM openeuler-22.03-lts -MAINTAINER - -RUN yum -y install openssh-clients util-linux - - -ADD ./sysmaster-0.2.3-1.oe2203.aarch64.rpm /home -RUN rpm -ivh /home/sysmaster-0.2.3-1.oe2203.aarch64.rpm - -COPY ./hostshell /usr/bin/ -COPY ./set-ssh-pub-key.sh /usr/local/bin -COPY ./set-ssh-pub-key.service /usr/lib/sysmaster - -EXPOSE 22 -# set sshd.service and set-ssh-pub-key.service pulled up by default -RUN sed -i 's/sysinit.target/sysinit.target;sshd.service;set-ssh-pub-key.service/g' /usr/lib/sysmaster/basic.target - -CMD ["/usr/lib/sysmaster/init"] diff --git a/scripts/admin-container/set-ssh-pub-key.service b/scripts/admin-container/set-ssh-pub-key.service deleted file mode 100644 index 84dd12d928d93d8c9a4c9fbe6c22973b3804715e..0000000000000000000000000000000000000000 --- a/scripts/admin-container/set-ssh-pub-key.service +++ /dev/null @@ -1,15 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. - -[Unit] -Description="set ssh authorized keys according to the secret which is set by user" - -[Service] -ExecStart="/usr/local/bin/set-ssh-pub-key.sh" diff --git a/scripts/admin-container/set-ssh-pub-key.sh b/scripts/admin-container/set-ssh-pub-key.sh deleted file mode 100755 index e91a15de3500ae0e8b54b9165f122d2f8e077301..0000000000000000000000000000000000000000 --- a/scripts/admin-container/set-ssh-pub-key.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -ssh_pub=$(cat /etc/secret-volume/ssh-pub-key) -ssh_dir="/root/.ssh" -authorized_file="$ssh_dir/authorized_keys" - -if [ ! -d "$ssh_dir" ]; then - mkdir "$ssh_dir" - chmod 700 "$ssh_dir" -fi - -if [ ! -f "$authorized_file" ]; then - touch "$authorized_file" - chmod 600 "$authorized_file" -fi - -echo "$ssh_pub" >> "$authorized_file" diff --git a/scripts/bootloader.sh b/scripts/bootloader.sh deleted file mode 100644 index df4be3290121f5ca6b3426e1c291c3d446f71aeb..0000000000000000000000000000000000000000 --- a/scripts/bootloader.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -set -eu -set -o pipefail -set -x -ARCH=`arch` - -function install_grub2_x86 () -{ - if [ "$BOOT_MODE" = "legacy" ]; then - # make boot.img/core.img and setup, to support legacy boot mode - GRUBNAME=$(which grub2-install) - echo "Installing GRUB2..." - GRUB_OPTS=${GRUB_OPTS:-"--force"} - GRUB_OPTS="$GRUB_OPTS --target=i386-pc" - - $GRUBNAME --modules="biosdisk part_msdos" $GRUB_OPTS $DEVICE - else - # make efi file, and save in FAT16 partition, to support UEFI boot mode - cp -r /usr/lib/grub/x86_64-efi boot/efi/EFI/openEuler - eval "grub2-mkimage -d /usr/lib/grub/x86_64-efi -O x86_64-efi --output=/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" - - mkdir -p /boot/efi/EFI/BOOT/ - cp -f /boot/efi/EFI/openEuler/grubx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI - fi -} - -function install_grub2_efi () -{ - cp -r /usr/lib/grub/arm64-efi /boot/efi/EFI/openEuler/ - eval "grub2-mkimage -d /usr/lib/grub/arm64-efi -O arm64-efi --output=/boot/efi/EFI/openEuler/grubaa64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" - - mkdir -p /boot/efi/EFI/BOOT/ - cp -f /boot/efi/EFI/openEuler/grubaa64.efi /boot/efi/EFI/BOOT/BOOTAA64.EFI -} - -if [ $ARCH == "x86_64" ]; then - install_grub2_x86 -fi - -if [ $ARCH == "aarch64" ]; then - install_grub2_efi -fi diff --git a/scripts/common/globalVariables.sh b/scripts/common/globalVariables.sh deleted file mode 100644 index 95af9c857c9b6f7c17009c2f10bb31ca4b23c77f..0000000000000000000000000000000000000000 --- a/scripts/common/globalVariables.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -IMG_SIZE=20 -PWD="$(pwd)" -TMP_MOUNT_PATH="${PWD}/mnt" -RPM_ROOT="${PWD}/rootfs" -ARCH=$(arch) - -export IMG_SIZE -export PWD -export TMP_MOUNT_PATH -export RPM_ROOT -export ARCH diff --git a/scripts/common/log.sh b/scripts/common/log.sh deleted file mode 100644 index 4d3ed2b7dd54490df19d5a611cea278f297668b9..0000000000000000000000000000000000000000 --- a/scripts/common/log.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -function log_error_print(){ - local logmsg="[ ERROR ] - ""`date "+%b %d %Y %H:%M:%S"`"" $1" - echo $logmsg -} - -function log_info_print(){ - local logmsg="[ INFO ] - ""`date "+%b %d %Y %H:%M:%S"`"" $1" - echo $logmsg -} diff --git a/scripts/common/utils.sh b/scripts/common/utils.sh deleted file mode 100644 index ec244b78c948fb6f1dc065a14ca5272d607065f2..0000000000000000000000000000000000000000 --- a/scripts/common/utils.sh +++ /dev/null @@ -1,191 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -CHECK_REGEX='\||;|&|&&|\|\||>|>>|<|,|#|!|\$' - -function mount_proc_dev_sys() { - local tmp_root=$1 - mount -t proc none "${tmp_root}/proc" - mount --bind /dev "${tmp_root}/dev" - mount --bind /dev/pts "${tmp_root}/dev/pts" - mount -t sysfs none "${tmp_root}/sys" -} - -function unmount_dir() { - local dir=$1 - - if [ -L "${dir}" ] || [ -f "${dir}" ]; then - log_error_print "${dir} is not a directory, please check it." - return 1 - fi - - if [ ! -d "${dir}" ]; then - return 0 - fi - - local real_dir=$(readlink -e "${dir}") - local mnts=$(awk '{print $2}' < /proc/mounts | grep "^${real_dir}" | sort -r) - for m in ${mnts}; do - log_info_print "Unmount ${m}" - umount -f "${m}" || true - done - - return 0 -} - -function init_part() { - local offset=$(fdisk -l system.img | grep $1 | awk '{print $2}') - local sizelimit=$(fdisk -l system.img | grep $1 | awk '{print $3}') - sizelimit=$(echo "($sizelimit - $offset)*512" | bc) - offset=$(echo "${offset}*512" | bc) - local loop=$(losetup -f) - losetup -o "${offset}" --sizelimit "${sizelimit}" "${loop}" system.img - if [ $2 == "BOOT" ];then - mkfs.vfat -n "$2" "${loop}" - mount -t vfat "${loop}" "$3" - else - mkfs.ext4 -L "$2" "${loop}" - mount -t ext4 "${loop}" "$3" - rm -rf "$3/lost+found" - fi -} - -function delete_dir() { - local ret=0 - local dir="$1" - unmount_dir "${dir}" - ret=$? - if [ "${ret}" -eq 0 ]; then - rm -rf "${dir}" - return 0 - else - log_error_print "${dir} is failed to unmount , can not delete $dir." - return 1 - fi -} - -function delete_file() { - local file="$1" - if [ ! -e "${file}" ]; then - return 0 - fi - - if [ ! -f "${file}" ]; then - log_error_print "${file} is not a file." - return 1 - fi - - rm -f "${file}" - return 0 -} - -function check_file_valid() { - local file="$1" - local mesg="$2" - if [ ! -e "${file}" ]; then - log_error_print "${mesg} is not exist." - exit 3 - fi - if [ ! -f "${file}" ];then - log_error_print "${mesg} is not a file." - exit 3 - fi -} - -function check_conf_valid() { - local conf_path="${PWD}/00bootup/Global.cfg" - check_file_valid ${conf_path} "Globab.cfg" - if [ $# != 7 ];then - log_error_print "configure configured in Global.cfg is empty." - exit 3 - fi - for addr in ${server_ip} ${local_ip} ${route_ip} ${netmask}; do - check_ip_valid $addr - done -} - -function check_ip_valid() { - local ipaddr="$1"; - if [[ ! $ipaddr =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] ; then - log_error_print "ip address configured in Global.cfg is not valid." - exit 3; - fi - for quad in $(echo "${ipaddr//./ }"); do - if [ $quad -ge 0 ] && [ $quad -le 255 ];then - continue - fi - log_error_print "ip address configured in Global.cfg is not valid." - exit 3; - done - -} - -function check_binary_exist() { - check_file_valid "$1" "os-agent binary" -} - -function check_repo_path() { - check_file_valid $1 "REPO file" - if [ -d "${RPM_ROOT}" ]; then - log_error_print "there is a rootfs folder. please confirm if rootfs is being used, if not, please remove ${RPM_ROOT} first." - exit 5 - fi -} - -function check_disk_space() { - local disk_ava="$(df ${PWD} | awk 'NR==2{print}' | awk '{print $4}')" - case $1 in - docker) - local maxsize=$((6*1024*1024)) - if [ "${disk_ava}" -lt "${maxsize}" ]; then - log_error_print "The available disk space is not enough, at least 6GiB." - exit 6 - fi - ;; - vm) - local maxsize=$((25*1024*1024)) - if [ "${disk_ava}" -lt "${maxsize}" ]; then - log_error_print "The available disk space is not enough, at least 25GiB." - exit 6 - fi - ;; - pxe) - local maxsize=$((5*1024*1024)) - if [ "${disk_ava}" -lt "${maxsize}" ]; then - log_error_print "The available disk space is not enough, at least 5GiB." - exit 6 - fi - ;; - esac -} - -function check_param() { - set +eE - local arg=$1 - echo "${arg}" | grep -v -E -q ${CHECK_REGEX} - filterParam=$(echo "${arg}" | grep -v -E ${CHECK_REGEX}) - if [[ "${filterParam}" != "${arg}" ]]; then - log_error_print "params ${arg} is invalid, please check it." - exit 3 - fi - set -eE -} - -function check_docker_exist() { - if [[ "$(docker images -q $1 2> /dev/null)" == "" ]]; then - log_error_print "docker is not exist please pull $1 first " - exit 9 - fi -} - -function check_docker_file() { - check_file_valid $1 "admin-container Dockerfile" -} \ No newline at end of file diff --git a/scripts/create/imageCreate.sh b/scripts/create/imageCreate.sh deleted file mode 100644 index 4d02f9d15cb02c174b6f6f2c1b97b617c3107374..0000000000000000000000000000000000000000 --- a/scripts/create/imageCreate.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -TMP_MOUNT_PATH="${PWD}/mnt" -RPM_ROOT="${PWD}/rootfs" -IMG_SIZE=20 -PWD="$(pwd)" -function create_img() { - local BOOT_MODE=$1 - rm -f system.img update.img - qemu-img create system.img ${IMG_SIZE}G - if [ "$BOOT_MODE" = "legacy" ]; then - local BOOT_PATH=${TMP_MOUNT_PATH}/boot/grub2 - parted system.img -s mklabel msdos - parted system.img -s mkpart primary ext4 1MiB 60MiB - else - local BOOT_PATH=${TMP_MOUNT_PATH}/boot/efi - parted system.img -s mklabel gpt - parted system.img -s mkpart primary fat32 1MiB 60MiB - fi - parted system.img -s mkpart primary ext4 60MiB 2160MiB - parted system.img -s mkpart primary ext4 2160MiB 4260MiB - parted system.img -s mkpart primary ext4 4260MiB 100% - local device=$(losetup -f) - losetup "${device}" system.img - - mkdir -p "${TMP_MOUNT_PATH}" - - init_part system.img2 ROOT-A "${TMP_MOUNT_PATH}" - - mkdir -p ${BOOT_PATH} - chmod 755 ${BOOT_PATH} - if [ "$BOOT_MODE" = "legacy" ]; then - init_part system.img1 GRUB2 "${BOOT_PATH}" - else - init_part system.img1 BOOT "${BOOT_PATH}" - fi - tar -x -C ${TMP_MOUNT_PATH} -f os.tar - if [ "$BOOT_MODE" = "legacy" ]; then - sed -i "s/insmod part_gpt/insmod part_msdos/g; \ -s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ -s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ -"${TMP_MOUNT_PATH}"/boot/grub2/grub.cfg - fi - sync - cp bootloader.sh "${TMP_MOUNT_PATH}" - mount_proc_dev_sys "${TMP_MOUNT_PATH}" - DEVICE="${device}" BOOT_MODE="${BOOT_MODE}" chroot "${TMP_MOUNT_PATH}" bash bootloader.sh - rm -rf "${TMP_MOUNT_PATH}/bootloader.sh" - sync - - dd if=/dev/disk/by-label/ROOT-A of=update.img bs=8M - sync - unmount_dir "${TMP_MOUNT_PATH}" - init_part system.img3 ROOT-B "${TMP_MOUNT_PATH}" - umount "${TMP_MOUNT_PATH}" - - init_part system.img4 PERSIST "${TMP_MOUNT_PATH}" - mkdir ${TMP_MOUNT_PATH}/{var,etc,etcwork} - mkdir -p ${TMP_MOUNT_PATH}/etc/KubeOS/certs - umount "${TMP_MOUNT_PATH}" - - losetup -D - parted system.img -- set 1 boot on - qemu-img convert system.img -O qcow2 system.qcow2 -} - -function create_pxe_img() { - rm -rf initramfs.img kubeos.tar - local opt=$1 - shift - case $opt in - "repo") - create_os_tar_from_repo "$@" - ;; - "docker") - create_os_tar_from_docker "$@" - ;; - esac - tar -xvf os.tar ./initramfs.img - mv os.tar kubeos.tar -} - -function create_docker_image() { - local DOCKER_IMG="$6" - create_os_tar_from_repo "$@" - docker build -t ${DOCKER_IMG} -f ./Dockerfile . -} - -function create_vm_img() { - local opt=$1 - shift - local BOOT_MODE=$5 - case $opt in - "repo") - create_os_tar_from_repo "$@" - create_img "${BOOT_MODE}" - ;; - "docker") - create_os_tar_from_docker "$@" - create_img "${BOOT_MODE}" - ;; - esac - -} - -function create_admin_img() { - local DOCKERFILE="$1" - local DOCKER_IMG="$2" - local ADMIN_CONTAINER_DIR="$3" - cp ../bin/hostshell ${ADMIN_CONTAINER_DIR} - docker build -t ${DOCKER_IMG} -f ${DOCKERFILE} ${ADMIN_CONTAINER_DIR} - rm -rf ${ADMIN_CONTAINER_DIR}/hostshell -} \ No newline at end of file diff --git a/scripts/create/rootfsCreate.sh b/scripts/create/rootfsCreate.sh deleted file mode 100644 index 377cbf851de3f8e341f2ab73166d2fd850f91fa2..0000000000000000000000000000000000000000 --- a/scripts/create/rootfsCreate.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -function prepare_yum() { - # init rpmdb - local REPO=$1 - rpm --root "${RPM_ROOT}" --initdb - mkdir -p "${RPM_ROOT}"{/etc/yum.repos.d,/persist,/proc,/dev/pts,/sys} - mount_proc_dev_sys "${RPM_ROOT}" - # init yum repo - local iso_repo="${RPM_ROOT}/etc/yum.repos.d/iso.repo" - cat "${REPO}" > ${RPM_ROOT}/etc/yum.repos.d/iso.repo -} - -function install_packages() { - local REPO=$1 - local BOOT_MODE=$2 - prepare_yum ${REPO} - - echo "install package.." - - local filesize=$(stat -c "%s" ./rpmlist) - local maxsize=$((1024*1024)) - if [ "${filesize}" -gt "${maxsize}" ]; then - echo "please check if rpmlist is too big or something wrong" - exit 7 - fi - - local rpms=$(cat ./rpmlist | tr "\n" " ") - if [ "${ARCH}" == "x86_64" ]; then - if [ "${BOOT_MODE}" = "legacy" ]; then - rpms+=" grub2" - else - rpms+=" grub2-efi grub2-tools grub2-efi-x64-modules grub2-pc-modules" - fi - yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} - elif [ "${ARCH}" == "aarch64" ]; then - yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2-efi grub2-tools grub2-efi-aa64-modules - fi - yum -y --installroot="${RPM_ROOT}" clean all -} - -function install_misc() { - local VERSION=$1 - local AGENT_PATH=$2 - local PASSWD=$3 - local BOOT_MODE=$4 - local DNS_CONF="${PWD}/resolv.conf" - cp ../files/*mount ../files/os-agent.service "${RPM_ROOT}/usr/lib/systemd/system/" - cp ../files/os-release "${RPM_ROOT}/usr/lib/" - cp "${AGENT_PATH}" "${RPM_ROOT}/usr/bin" - rm "${RPM_ROOT}/etc/os-release" - - cat < "${RPM_ROOT}/usr/lib/os-release" -NAME=${NAME} -ID=${NAME} -EOF - echo "PRETTY_NAME=\"${NAME} ${VERSION}\"" >> "${RPM_ROOT}/usr/lib/os-release" - echo "VERSION_ID=${VERSION}" >> "${RPM_ROOT}/usr/lib/os-release" - mv "${RPM_ROOT}"/boot/vmlinuz* "${RPM_ROOT}/boot/vmlinuz" - mv "${RPM_ROOT}"/boot/initramfs* "${RPM_ROOT}/boot/initramfs.img" - if [ "$BOOT_MODE" = "legacy" ]; then - cp grub.cfg "${RPM_ROOT}"/boot/grub2 - sed -i "s/insmod part_gpt/insmod part_msdos/g; \ -s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ -s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ -"${RPM_ROOT}"/boot/grub2/grub.cfg - else - cp grub.cfg "${RPM_ROOT}"/boot/efi/EFI/openEuler - fi - cp -r ./00bootup ${RPM_ROOT}/usr/lib/dracut/modules.d/ - cp set_in_chroot.sh "${RPM_ROOT}" - ROOT_PWD="${PASSWD}" BOOT_MODE="${BOOT_MODE}" chroot "${RPM_ROOT}" bash /set_in_chroot.sh - rm "${RPM_ROOT}/set_in_chroot.sh" - if [ -e "${DNS_CONF}" ]; then - cp "${DNS_CONF}" "${RPM_ROOT}/etc/resolv.conf" - fi -} - -function create_os_tar_from_repo() { - local REPO=$1 - local VERSION=$2 - local AGENT_PATH=$3 - local PASSWD=$4 - local BOOT_MODE=$5 - install_packages ${REPO} ${BOOT_MODE} - install_misc ${VERSION} ${AGENT_PATH} ${PASSWD} ${BOOT_MODE} - unmount_dir "${RPM_ROOT}" - tar -C "$RPM_ROOT" -cf ./os.tar . -} -function create_os_tar_from_docker() { - local DOCKER_IMG=$1 - container_id=$(docker create ${DOCKER_IMG}) - echo "$container_id" - docker cp $container_id:/os.tar ./ - docker rm $container_id -} diff --git a/scripts/grub.cfg b/scripts/grub.cfg deleted file mode 100644 index 984b16168438ed378dfbc10d7fb594a747425706..0000000000000000000000000000000000000000 --- a/scripts/grub.cfg +++ /dev/null @@ -1,173 +0,0 @@ -## Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - # KubeOS is licensed under the Mulan PSL v2. - # You can use this software according to the terms and conditions of the Mulan PSL v2. - # You may obtain a copy of Mulan PSL v2 at: - # http://license.coscl.org.cn/MulanPSL2 - # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR - # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - # PURPOSE. -## See the Mulan PSL v2 for more details. -set pager=1 - -if [ -f ${config_directory}/grubenv ]; then - load_env -f ${config_directory}/grubenv -elif [ -s $prefix/grubenv ]; then - load_env -fi -if [ "${next_entry}" ] ; then - set default="${next_entry}" - set next_entry= - save_env next_entry - set boot_once=true -else - set default="${saved_entry}" -fi - -if [ x"${feature_menuentry_id}" = xy ]; then - menuentry_id_option="--id" -else - menuentry_id_option="" -fi - -export menuentry_id_option - -if [ "${prev_saved_entry}" ]; then - set saved_entry="${prev_saved_entry}" - save_env saved_entry - set prev_saved_entry= - save_env prev_saved_entry - set boot_once=true -fi - -function savedefault { - if [ -z "${boot_once}" ]; then - saved_entry="${chosen}" - save_env saved_entry - fi -} - -function load_video { - if [ x$feature_all_video_module = xy ]; then - insmod all_video - else - insmod efi_gop - insmod efi_uga - insmod ieee1275_fb - insmod vbe - insmod vga - insmod video_bochs - insmod video_cirrus - fi -} - -terminal_output console -if [ x$feature_timeout_style = xy ] ; then - set timeout_style=menu - set timeout=5 -# Fallback normal timeout code in case the timeout_style feature is -# unavailable. -else - set timeout=5 -fi -set superusers="root" -### END /etc/grub.d/00_header ### - -### BEGIN /etc/grub.d/01_users ### -if [ -f ${prefix}/user.cfg ]; then - source ${prefix}/user.cfg - if [ -n "${GRUB2_PASSWORD}" ]; then - set superusers="root" - export superusers - password_pbkdf2 root ${GRUB2_PASSWORD} - fi -fi -### END /etc/grub.d/01_users ### - -### BEGIN /etc/grub.d/10_linux ### -menuentry 'A' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-A' { - load_video - set gfxpayload=keep - insmod gzio - insmod part_gpt - insmod ext2 - set root='hd0,gpt2' - linux /boot/vmlinuz root=/dev/sda2 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3 - initrd /boot/initramfs.img -} - -menuentry 'B' --class KubeOS --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'KubeOS-B' { - load_video - set gfxpayload=keep - insmod gzio - insmod part_gpt - insmod ext2 - set root='hd0,gpt3' - linux /boot/vmlinuz root=/dev/sda3 ro rootfstype=ext4 nomodeset quiet oops=panic softlockup_panic=1 nmi_watchdog=1 rd.shell=0 selinux=0 crashkernel=256M panic=3 - initrd /boot/initramfs.img -} - -### END /etc/grub.d/10_linux ### - -### BEGIN /etc/grub.d/10_reset_boot_success ### -# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry -if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then - set menu_hide_ok=1 -else - set menu_hide_ok=0 -fi -# Reset boot_indeterminate after a successful boot -if [ "${boot_success}" = "1" ] ; then - set boot_indeterminate=0 -# Avoid boot_indeterminate causing the menu to be hidden more then once -elif [ "${boot_indeterminate}" = "1" ]; then - set boot_indeterminate=2 -fi -# Reset boot_success for current boot -set boot_success=0 -save_env boot_success boot_indeterminate -### END /etc/grub.d/10_reset_boot_success ### - -### BEGIN /etc/grub.d/12_menu_auto_hide ### -if [ x$feature_timeout_style = xy ] ; then - if [ "${menu_show_once}" ]; then - unset menu_show_once - save_env menu_show_once - set timeout_style=menu - set timeout=60 - elif [ "${menu_auto_hide}" -a "${menu_hide_ok}" = "1" ]; then - set orig_timeout_style=${timeout_style} - set orig_timeout=${timeout} - if [ "${fastboot}" = "1" ]; then - # timeout_style=menu + timeout=0 avoids the countdown code keypress check - set timeout_style=menu - set timeout=0 - else - set timeout_style=hidden - set timeout=1 - fi - fi -fi -### END /etc/grub.d/12_menu_auto_hide ### - -### BEGIN /etc/grub.d/20_linux_xen ### -### END /etc/grub.d/20_linux_xen ### - -### BEGIN /etc/grub.d/20_ppc_terminfo ### -### END /etc/grub.d/20_ppc_terminfo ### - -### BEGIN /etc/grub.d/30_uefi-firmware ### -### END /etc/grub.d/30_uefi-firmware ### - -### BEGIN /etc/grub.d/40_custom ### -# This file provides an easy way to add custom menu entries. Simply type the -# menu entries you want to add after this comment. Be careful not to change -# the 'exec tail' line above. -### END /etc/grub.d/40_custom ### - -### BEGIN /etc/grub.d/41_custom ### -if [ -f ${config_directory}/custom.cfg ]; then - source ${config_directory}/custom.cfg -elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then - source $prefix/custom.cfg; -fi -### END /etc/grub.d/41_custom ### diff --git a/scripts/kbimg.sh b/scripts/kbimg.sh deleted file mode 100644 index 0f75f0db63e268d92afb75f16386b0655b5586ab..0000000000000000000000000000000000000000 --- a/scripts/kbimg.sh +++ /dev/null @@ -1,402 +0,0 @@ -#!/bin/bash -## Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved. -# KubeOS is licensed under the Mulan PSL v2. -# You can use this software according to the terms and conditions of the Mulan PSL v2. -# You may obtain a copy of Mulan PSL v2 at: -# http://license.coscl.org.cn/MulanPSL2 -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -# PURPOSE. -## See the Mulan PSL v2 for more details. - -set -e - -NAME=KubeOS -REPO="" -VERSION="" -AGENT_PATH="" -PASSWD="" -DOCKER_IMG="" -DOCKERFILE="" -LOCK=./test.lock -ADMIN_CONTAINER_DIR=./admin-container -BOOT_MODE=efi - -source common/globalVariables.sh &>/dev/null -source common/log.sh &>/dev/null -source common/utils.sh &>/dev/null -source create/rootfsCreate.sh &>/dev/null -source create/imageCreate.sh &>/dev/null -source 00bootup/Global.cfg &>/dev/null - -function show_options() { - cat << EOF - -Usage : sh kbimg [COMMAND] [OPTIONS] - -kbimg is a tool used to handle KubeOS image , like create KubeOS images - -Commands: - create create KubeOS images -Options: - -h,--help show help information - -Run 'kbimg COMMAND --help' for more information on a command. -EOF -} - -function show_create_usage() { - cat << EOF - -Usage : kbimg create [COMMAND] [OPTIONS] - -commands: - upgrade-image create KubeOS OCI image used for installation and upgrade - vm-image create KubeOS virtual machine image - pxe-image create images required for KubeOS PXE installation on physical machines - admin-image create KubeOS admin container OCI image used for debug of worker nodes in clusters -options: - -h,--help show help information - -Run 'kbimg create COMMAND --help' for more information on a command. -EOF -} - -function show_upgrade_image_usage() { - cat << EOF - -Usage : kbimg create upgrade-image -p isopath -v osversion -b osagentdir -e ospassword -d repository/name:tag - -options: - -p repo path - -v KubeOS version - -b directory of os-agent binary - -e os encrypted password - -d docker image like repository/name:tag - -l boot to legacy BIOS mode, if not specify, then UEFI mode - -h,--help show help information -EOF -} - -function show_vm_pxe_image_usage() { - cat << EOF - -Usage : kbimg create [vm-image|pxe-image] -p iso-path -v os-version -b os-agent-dir -e os-password - or - kbimg create [vm-image|pxe-image] -d repository/name:tag - -options: - -p repo path - -v KubeOS version - -b directory of os-agent binary - -e os encrypted password - -d docker image like repository/name:tag - -l boot to legacy BIOS mode, if not specify, then UEFI mode - -h,--help show help information -EOF -} - -function show_admin_image_usage() { - cat << EOF - -Usage : kbimg create admin-image -f dockerfile-path -d repository/name:tag - -options: - -f Dockerfile path - -d admin container image like repository/name:tag - -h,--help show help information -EOF -} - -function file_lock() { - local lock_file=$1 - exec {lock_fd}>"${lock_file}" - flock -xn "${lock_fd}" -} - -function test_lock() { - file_lock "${LOCK}" - if [ $? -ne 0 ]; then - log_error_print "There is already an generate process running." - exit 203 - fi -} - -function clean_space() { - delete_dir "${RPM_ROOT}" - delete_dir "${TMP_MOUNT_PATH}" - delete_file os.tar - rm -rf "${LOCK}" - delete_file ${ADMIN_CONTAINER_DIR}/hostshell -} - -function clean_img() { - delete_file system.img - delete_file update.img - delete_file initramfs.img - delete_file kubeos.tar -} - -function verify_upgrade_image_input() { - set +eE - for i in "p" "v" "b" "e" "d" - do - echo "$@" | grep -q "\-$i " - if [ "$?" -ne 0 ];then - log_error_print "option -$i is mandatory, please check input" - show_upgrade_image_usage - exit 3 - fi - done - set -eE - while getopts "p:v:e:b:d:l" opt - do - case $opt in - p) - check_param $OPTARG - REPO="$OPTARG" - ;; - v) - check_param $OPTARG - VERSION="$OPTARG" - ;; - b) - check_param $OPTARG - AGENT_PATH="$OPTARG" - ;; - e) - # encrypted password contains special characters.,not verify. - PASSWD="$OPTARG" - ;; - d) - check_param $OPTARG - DOCKER_IMG="$OPTARG" - ;; - l) - BOOT_MODE=legacy - ;; - *) - log_error_print "option $opt not found" - show_upgrade_image_usage - exit 3 - ;; - esac - done -} - -function verify_repo_input() { - set +eE - for i in "p" "v" "b" "e" - do - echo "$@" | grep -q "\-$i " - if [ "$?" -ne 0 ];then - log_error_print "option -$i is mandatory, please check input" - show_vm_pxe_image_usage - exit 3 - fi - done - set -eE - while getopts "p:v:e:b:l" opt - do - case $opt in - p) - check_param $OPTARG - REPO="$OPTARG" - ;; - v) - check_param $OPTARG - VERSION="$OPTARG" - ;; - b) - check_param $OPTARG - AGENT_PATH="$OPTARG" - ;; - e) - # encrypted password contains special characters.,not verify. - PASSWD="$OPTARG" - ;; - l) - BOOT_MODE=legacy - ;; - *) - log_error_print "option $opt not found" - show_vm_pxe_image_usage - exit 3 - ;; - esac - done -} - -function verify_docker_input() { - if [ $1 != "-d" ]; then - log_error_print "option $1 not found" - show_vm_pxe_image_usage - exit 3 - fi - check_param $2 - DOCKER_IMG=$2 -} - -function verify_admin_input() { - set +eE - for i in "f" "d" - do - echo "$@" | grep -q "\-$i " - if [ "$?" -ne 0 ];then - log_error_print "option -$i is mandatory, please check input" - show_admin_image_usage - exit 3 - fi - done - set -eE - while getopts "f:d:" opt - do - case $opt in - f) - check_param $OPTARG - DOCKERFILE="$OPTARG" - ;; - d) - check_param $OPTARG - DOCKER_IMG="$OPTARG" - ;; - *) - log_error_print "option $opt not found" - show_admin_image_usage - exit 3 - ;; - esac - done -} - -function verify_create_input() { - local ret= - local cmd=$1 - case $1 in - "upgrade-image") - shift - if [ $# -eq 1 ]; then - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - show_upgrade_image_usage - exit 0 - fi - fi - if [[ $# -ne 10 && $# -ne 11 ]]; then - log_error_print "the number of parameters is incorrect, please check it." - show_upgrade_image_usage - exit 3 - fi - check_disk_space "docker" - verify_upgrade_image_input "$@" - check_repo_path "${REPO}" - check_binary_exist "${AGENT_PATH}" - create_docker_image "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" "${BOOT_MODE}" "${DOCKER_IMG}" - ;; - "vm-image") - shift - if [ $# -eq 1 ]; then - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - show_vm_pxe_image_usage - exit 0 - fi - fi - check_disk_space "vm" - if [[ $# -eq 8 || $# -eq 9 ]]; then - verify_repo_input "$@" - check_repo_path "${REPO}" - check_binary_exist "${AGENT_PATH}" - create_vm_img "repo" "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" "${BOOT_MODE}" - elif [ $# -eq 2 ]; then - verify_docker_input "$@" - check_docker_exist "${DOCKER_IMG}" - create_vm_img "docker" "${DOCKER_IMG}" - else - log_error_print "the number of parameters is incorrect, please check it." - show_vm_pxe_image_usage - exit 3 - fi - ;; - "pxe-image") - shift - if [ $# -eq 1 ]; then - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - show_vm_pxe_image_usage - exit 0 - fi - fi - check_disk_space "pxe" - check_conf_valid ${rootfs_name} ${disk} ${server_ip} ${local_ip} ${route_ip} ${netmask} ${net_name} - if [ $# -eq 8 ]; then - verify_repo_input "$@" - check_repo_path "${REPO}" - check_binary_exist "${AGENT_PATH}" - create_pxe_img "repo" "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" - elif [ $# -eq 2 ]; then - verify_docker_input "$@" - check_docker_exist "${DOCKER_IMG}" - create_pxe_img "docker" "${DOCKER_IMG}" - else - log_error_print "the number of parameters is incorrect, please check it." - show_vm_pxe_image_usage - exit 3 - fi - ;; - "admin-image") - shift - if [ $# -eq 1 ]; then - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - show_admin_image_usage - exit 0 - fi - fi - if [ $# -ne 4 ]; then - log_error_print "the number of parameters is incorrect, please check it." - show_admin_image_usage - exit 3 - fi - verify_admin_input "$@" - check_docker_file "${DOCKERFILE}" - create_admin_img "${DOCKERFILE}" "${DOCKER_IMG}" "${ADMIN_CONTAINER_DIR}" - ;; - "-h"|"--help") - show_create_usage - ;; - *) - log_error_print "error command $1 not found" - show_create_usage - exit 3 - esac -} - -function kubeos_image_main() { - local ret= - local cmd=$1 - if [ "$#" -eq 1 ]; then - case $1 in - -h|--help) - show_options - exit 0;; - *) - log_error_print "params is invalid,please check it." - show_options - exit 3;; - esac - fi - case $cmd in - create) - shift - verify_create_input "$@" - ;; - *) - log_error_print "command $1 not found" - show_options - exit 3 - ;; - esac -} - -test_lock -trap clean_space EXIT -trap clean_img ERR - -kubeos_image_main "$@" diff --git a/scripts/rpmlist b/scripts/rpmlist deleted file mode 100644 index fb6f23810a4042f96f46b4a38fcb1e49317b03aa..0000000000000000000000000000000000000000 --- a/scripts/rpmlist +++ /dev/null @@ -1,22 +0,0 @@ -kernel -passwd -dhcp -NetworkManager -openssh-server -docker -kubernetes-kubeadm -kubernetes-kubelet -containernetworking-plugins -socat -conntrack-tools -ebtables -ethtool -rsyslog -vi -net-tools -hwinfo -dracut -coreutils -gawk -parted -dosfstools \ No newline at end of file diff --git a/scripts/set_in_chroot.sh b/scripts/set_in_chroot.sh deleted file mode 100644 index 80b5a91b851824cfb6ec42b8d40ebf86fe67f2b9..0000000000000000000000000000000000000000 --- a/scripts/set_in_chroot.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -ln -s /usr/lib/systemd/system/os-agent.service /usr/lib/systemd/system/multi-user.target.wants/os-agent.service -ln -s /usr/lib/systemd/system/kubelet.service /usr/lib/systemd/system/multi-user.target.wants/kubelet.service -if [ "$BOOT_MODE" = "legacy" ]; then - ln -s /usr/lib/systemd/system/boot-grub2.mount /lib/systemd/system/local-fs.target.wants/boot-grub2.mount -else - ln -s /usr/lib/systemd/system/boot-efi.mount /lib/systemd/system/local-fs.target.wants/boot-efi.mount -fi -ln -s /usr/lib/systemd/system/etc.mount /lib/systemd/system/local-fs.target.wants/etc.mount - -str=`sed -n '/^root:/p' /etc/shadow | awk -F "root:" '{print $2}'` -umask 0666 -mv /etc/shadow /etc/shadow_bak -sed -i '/^root:/d' /etc/shadow_bak -echo "root:"${ROOT_PWD}${str:1} > /etc/shadow -cat /etc/shadow_bak >> /etc/shadow -rm -rf /etc/shadow_bak - -dracut -f -v --add bootup /initramfs.img --kver `ls /lib/modules` -rm -rf /usr/lib/dracut/modules.d/00bootup \ No newline at end of file