mirror of
https://github.com/CachyOS/New-Cli-Installer.git
synced 2025-02-02 22:07:13 +08:00
🚧 prepare for release
This commit is contained in:
parent
8175b11080
commit
ffbbef14c7
@ -7,7 +7,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|||||||
## name and version
|
## name and version
|
||||||
##
|
##
|
||||||
project(cachyos-installer
|
project(cachyos-installer
|
||||||
VERSION 0.0.1
|
VERSION 0.5.0
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
|
|
||||||
##
|
##
|
||||||
|
94
README.md
Normal file
94
README.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# cachyos-new-installer
|
||||||
|
CLI net-installer for CachyOS, inspired by manjaro-architect
|
||||||
|
|
||||||
|
This installer provides online installation for CachyOS.
|
||||||
|
|
||||||
|
### Libraries used in this project
|
||||||
|
|
||||||
|
* [Functional Terminal (X) User interface](https://github.com/ArthurSonzogni/FTXUI) used for TUI.
|
||||||
|
* [A modern formatting library](https://github.com/fmtlib/fmt) used for formatting strings, output and logging.
|
||||||
|
* [Fast C++ logging library](https://github.com/gabime/spdlog) used for logging process of the installer.
|
||||||
|
* [Parsing gigabytes of JSON per second](https://github.com/simdjson/simdjson) used for config deserialization.
|
||||||
|
* [Curl for People](https://github.com/libcpr/cpr) used for connection check and maybe in future fetching netinstall config from github.
|
||||||
|
* [Ranges](https://github.com/ericniebler/range-v3) used for ranges support with clang.
|
||||||
|
|
||||||
|
|
||||||
|
**Simple menu overview:**
|
||||||
|
|
||||||
|
TODO: should be simple as calamares
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Advanced menu overview:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Main Menu
|
||||||
|
|
|
||||||
|
├── Prepare Installation
|
||||||
|
| ├── Set Virtual Console (TODO)
|
||||||
|
| ├── List Devices
|
||||||
|
| ├── Partition Disk
|
||||||
|
| ├── RAID (WIP)
|
||||||
|
| ├── LUKS Encryption (WIP)
|
||||||
|
| ├── Logical Volume Management (WIP)
|
||||||
|
| ├── Mount Partitions
|
||||||
|
| ├── Configure Installer Mirrorlist (TODO)
|
||||||
|
| | ├── Edit Pacman Configuration
|
||||||
|
| | ├── Edit Pacman Mirror Configuration
|
||||||
|
| | └── Rank Mirrors by Speed
|
||||||
|
| |
|
||||||
|
│ └── Refresh Pacman Keys (TODO)
|
||||||
|
|
|
||||||
|
├── Install System
|
||||||
|
│ ├── Install Base Packages
|
||||||
|
│ ├── Install Desktop
|
||||||
|
│ ├── Install Bootloader
|
||||||
|
│ ├── Configure Base
|
||||||
|
| │ ├── Generate FSTAB (seems broken)
|
||||||
|
| │ ├── Set Hostname
|
||||||
|
| │ ├── Set System Locale (WIP)
|
||||||
|
| │ ├── Set Timezone and Clock
|
||||||
|
| │ ├── Set Root Password
|
||||||
|
| │ └── Add New User(s) (seems broken)
|
||||||
|
| │
|
||||||
|
│ ├── Install Custom Packages
|
||||||
|
│ ├── System Tweaks (TODO)
|
||||||
|
| │ ├── Enable Automatic Login
|
||||||
|
| │ ├── Enable Hibernation
|
||||||
|
| │ ├── Performance
|
||||||
|
| | │ ├── I/O schedulers
|
||||||
|
| | │ ├── Swap configuration
|
||||||
|
| | │ └── Preload
|
||||||
|
| | │
|
||||||
|
| │ ├── Security and systemd Tweaks
|
||||||
|
| | │ ├── Amend journald Logging
|
||||||
|
| | │ ├── Disable Coredump Logging
|
||||||
|
| | │ └── Restrict Access to Kernel Logs
|
||||||
|
| | │
|
||||||
|
| │ └── Restrict Access to Kernel Logs
|
||||||
|
| │
|
||||||
|
│ ├── Review Configuration Files (TODO)
|
||||||
|
│ └── Chroot into Installation (TODO)
|
||||||
|
|
|
||||||
|
└── System Rescue
|
||||||
|
├── Install Hardware Drivers (TODO)
|
||||||
|
│ ├── Install Display Drivers
|
||||||
|
│ └── Install Network Drivers
|
||||||
|
|
|
||||||
|
├── Install Bootloader
|
||||||
|
├── Configure Base
|
||||||
|
| └── ... (see 'Install System')
|
||||||
|
│
|
||||||
|
├── Install Custom Packages
|
||||||
|
├── Remove Packages
|
||||||
|
├── Review Configuration Files (TODO)
|
||||||
|
├── Chroot into Installation (TODO)
|
||||||
|
├── Data Recovery (TODO)
|
||||||
|
│ └── Btrfs snapshots..
|
||||||
|
│
|
||||||
|
└── View System Logs (TODO)
|
||||||
|
├── Dmesg
|
||||||
|
├── Pacman log
|
||||||
|
├── Xorg log
|
||||||
|
└── Journalctl
|
||||||
|
```
|
@ -1,5 +1,5 @@
|
|||||||
project('cachyos-installer', 'cpp',
|
project('cachyos-installer', 'cpp',
|
||||||
version: '0.0.1',
|
version: '0.5.0',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
meson_version: '>=0.55.0',
|
meson_version: '>=0.55.0',
|
||||||
default_options: ['cpp_std=c++20',
|
default_options: ['cpp_std=c++20',
|
||||||
|
113
src/tui.cpp
113
src/tui.cpp
@ -140,7 +140,7 @@ bool exit_done() noexcept {
|
|||||||
|
|
||||||
spdlog::info("exit installer.");
|
spdlog::info("exit installer.");
|
||||||
|
|
||||||
static constexpr auto LogInfo = "Would you like to save the installation-log to the installed system?\nIt will be copied to";
|
static constexpr auto LogInfo = "Would you like to save\nthe installation-log to the installed system?\nIt will be copied to\n";
|
||||||
const auto& do_save_log = detail::yesno_widget(fmt::format("\n{} {}/cachyos-install.log\n", LogInfo, mountpoint), size(HEIGHT, LESS_THAN, 20) | size(WIDTH, LESS_THAN, 40));
|
const auto& do_save_log = detail::yesno_widget(fmt::format("\n{} {}/cachyos-install.log\n", LogInfo, mountpoint), size(HEIGHT, LESS_THAN, 20) | size(WIDTH, LESS_THAN, 40));
|
||||||
if (do_save_log) {
|
if (do_save_log) {
|
||||||
std::filesystem::copy_file("/tmp/cachyos-install.log", fmt::format("{}/cachyos-install.log", mountpoint), fs::copy_options::overwrite_existing);
|
std::filesystem::copy_file("/tmp/cachyos-install.log", fmt::format("{}/cachyos-install.log", mountpoint), fs::copy_options::overwrite_existing);
|
||||||
@ -1685,12 +1685,12 @@ void make_esp() noexcept {
|
|||||||
|
|
||||||
// If it is already a fat/vfat partition...
|
// If it is already a fat/vfat partition...
|
||||||
const auto& ret_status = utils::exec(fmt::format("fsck -N {} | grep fat", partition), true);
|
const auto& ret_status = utils::exec(fmt::format("fsck -N {} | grep fat", partition), true);
|
||||||
bool do_bootpartition{};
|
bool do_boot_partition{};
|
||||||
if (ret_status != "0") {
|
if (ret_status != "0") {
|
||||||
const auto& content = fmt::format("\nThe UEFI partition {} has already been formatted.\n \nReformat? Doing so will erase ALL data already on that partition.\n", partition);
|
const auto& content = fmt::format("\nThe UEFI partition {} has already been formatted.\n \nReformat? Doing so will erase ALL data already on that partition.\n", partition);
|
||||||
do_bootpartition = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
|
do_boot_partition = detail::yesno_widget(content, size(HEIGHT, LESS_THAN, 15) | size(WIDTH, LESS_THAN, 75));
|
||||||
}
|
}
|
||||||
if (do_bootpartition) {
|
if (do_boot_partition) {
|
||||||
#ifdef NDEVENV
|
#ifdef NDEVENV
|
||||||
utils::exec(fmt::format("mkfs.vfat -F32 {} >/dev/null", partition));
|
utils::exec(fmt::format("mkfs.vfat -F32 {} >/dev/null", partition));
|
||||||
#endif
|
#endif
|
||||||
@ -1710,6 +1710,7 @@ void make_esp() noexcept {
|
|||||||
Radiobox(&radiobox_list, &selected),
|
Radiobox(&radiobox_list, &selected),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO(vnepogodin): create helper for radiobox component
|
||||||
auto screen = ScreenInteractive::Fullscreen();
|
auto screen = ScreenInteractive::Fullscreen();
|
||||||
auto content = Renderer(component, [&] {
|
auto content = Renderer(component, [&] {
|
||||||
return component->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
return component->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40) | vscroll_indicator | yframe | flex;
|
||||||
@ -1821,9 +1822,10 @@ void mount_partitions() noexcept {
|
|||||||
success = true;
|
success = true;
|
||||||
screen.ExitLoopClosure()();
|
screen.ExitLoopClosure()();
|
||||||
};
|
};
|
||||||
|
/* clang-format off */
|
||||||
detail::menu_widget(partitions, ok_callback, &selected, &screen);
|
detail::menu_widget(partitions, ok_callback, &selected, &screen);
|
||||||
if (!success)
|
if (!success) { return; }
|
||||||
return;
|
/* clang-format on */
|
||||||
}
|
}
|
||||||
spdlog::info("partition: {}", std::get<std::string>(config_data["PARTITION"]));
|
spdlog::info("partition: {}", std::get<std::string>(config_data["PARTITION"]));
|
||||||
|
|
||||||
@ -1831,10 +1833,10 @@ void mount_partitions() noexcept {
|
|||||||
config_data["MOUNT"] = "";
|
config_data["MOUNT"] = "";
|
||||||
|
|
||||||
// Format with FS (or skip) -> // Make the directory and mount. Also identify LUKS and/or LVM
|
// Format with FS (or skip) -> // Make the directory and mount. Also identify LUKS and/or LVM
|
||||||
if (!tui::select_filesystem())
|
/* clang-format off */
|
||||||
return;
|
if (!tui::select_filesystem()) { return; }
|
||||||
if (!tui::mount_current_partition())
|
if (!tui::mount_current_partition()) { return; }
|
||||||
return;
|
/* clang-format on */
|
||||||
|
|
||||||
// Extra check if root is on LUKS or lvm
|
// Extra check if root is on LUKS or lvm
|
||||||
// get_cryptroot
|
// get_cryptroot
|
||||||
@ -1984,7 +1986,14 @@ void create_partitions() noexcept {
|
|||||||
const auto& answer = menu_entries[static_cast<std::size_t>(selected)];
|
const auto& answer = menu_entries[static_cast<std::size_t>(selected)];
|
||||||
if (answer != optwipe && answer != optauto) {
|
if (answer != optwipe && answer != optauto) {
|
||||||
screen.Clear();
|
screen.Clear();
|
||||||
|
screen.PostEvent(Event::Custom);
|
||||||
|
screen.ExitLoopClosure()();
|
||||||
|
#ifdef NDEVENV
|
||||||
utils::exec(fmt::format("{} {}", answer, std::get<std::string>(config_data["DEVICE"])), true);
|
utils::exec(fmt::format("{} {}", answer, std::get<std::string>(config_data["DEVICE"])), true);
|
||||||
|
#else
|
||||||
|
spdlog::debug("to be executed: {}", fmt::format("{} {}", answer, std::get<std::string>(config_data["DEVICE"])));
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (answer == optwipe) {
|
if (answer == optwipe) {
|
||||||
@ -1995,31 +2004,7 @@ void create_partitions() noexcept {
|
|||||||
}
|
}
|
||||||
screen.ExitLoopClosure()();
|
screen.ExitLoopClosure()();
|
||||||
};
|
};
|
||||||
|
detail::menu_widget(menu_entries, ok_callback, &selected, &screen);
|
||||||
MenuOption menu_option{.on_enter = ok_callback};
|
|
||||||
auto menu = Menu(&menu_entries, &selected, &menu_option);
|
|
||||||
auto content = Renderer(menu, [&] {
|
|
||||||
return menu->Render() | center | size(HEIGHT, GREATER_THAN, 10) | size(WIDTH, GREATER_THAN, 40);
|
|
||||||
});
|
|
||||||
|
|
||||||
ButtonOption button_option{.border = false};
|
|
||||||
auto controls_container = detail::controls_widget({"OK", "Cancel"}, {ok_callback, screen.ExitLoopClosure()}, &button_option);
|
|
||||||
|
|
||||||
auto controls = Renderer(controls_container, [&] {
|
|
||||||
return controls_container->Render() | hcenter | size(HEIGHT, LESS_THAN, 3) | size(WIDTH, GREATER_THAN, 25);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto global = Container::Vertical({
|
|
||||||
content,
|
|
||||||
Renderer([] { return separator(); }),
|
|
||||||
controls,
|
|
||||||
});
|
|
||||||
|
|
||||||
auto renderer = Renderer(global, [&] {
|
|
||||||
return detail::centered_interative_multi("New CLI Installer", global);
|
|
||||||
});
|
|
||||||
|
|
||||||
screen.Loop(renderer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void install_core_menu() noexcept {
|
void install_core_menu() noexcept {
|
||||||
@ -2192,7 +2177,7 @@ void prep_menu() noexcept {
|
|||||||
detail::menu_widget(menu_entries, ok_callback, &selected, &screen, "", {size(HEIGHT, GREATER_THAN, 15) | size(WIDTH, GREATER_THAN, 50)});
|
detail::menu_widget(menu_entries, ok_callback, &selected, &screen, "", {size(HEIGHT, GREATER_THAN, 15) | size(WIDTH, GREATER_THAN, 50)});
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() noexcept {
|
void menu_advanced() noexcept {
|
||||||
const std::vector<std::string> menu_entries = {
|
const std::vector<std::string> menu_entries = {
|
||||||
"Prepare Installation",
|
"Prepare Installation",
|
||||||
"Install System",
|
"Install System",
|
||||||
@ -2228,4 +2213,60 @@ void init() noexcept {
|
|||||||
detail::menu_widget(menu_entries, ok_callback, &selected, &screen);
|
detail::menu_widget(menu_entries, ok_callback, &selected, &screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menu_simple() noexcept {
|
||||||
|
// some simple ui
|
||||||
|
const std::vector<std::string> menu_entries = {
|
||||||
|
"entry 1",
|
||||||
|
"entry 2",
|
||||||
|
"entry 3",
|
||||||
|
};
|
||||||
|
|
||||||
|
auto screen = ScreenInteractive::Fullscreen();
|
||||||
|
std::int32_t selected{};
|
||||||
|
bool success{};
|
||||||
|
auto ok_callback = [&] {
|
||||||
|
success = true;
|
||||||
|
screen.ExitLoopClosure()();
|
||||||
|
};
|
||||||
|
detail::menu_widget(menu_entries, ok_callback, &selected, &screen);
|
||||||
|
/* clang-format off */
|
||||||
|
if (!success) { return; }
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
fmt::print("Selected element = {}\n", selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() noexcept {
|
||||||
|
#if 0
|
||||||
|
const std::vector<std::string> menu_entries = {
|
||||||
|
"Simple installation",
|
||||||
|
"Advanced installation",
|
||||||
|
};
|
||||||
|
|
||||||
|
auto screen = ScreenInteractive::Fullscreen();
|
||||||
|
std::int32_t selected{};
|
||||||
|
bool success{};
|
||||||
|
auto ok_callback = [&] {
|
||||||
|
success = true;
|
||||||
|
screen.ExitLoopClosure()();
|
||||||
|
};
|
||||||
|
detail::menu_widget(menu_entries, ok_callback, &selected, &screen);
|
||||||
|
/* clang-format off */
|
||||||
|
if (!success) { return; }
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
|
switch (selected) {
|
||||||
|
case 0:
|
||||||
|
tui::menu_simple();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
tui::menu_advanced();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tui::menu_advanced();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tui
|
} // namespace tui
|
||||||
|
@ -340,18 +340,24 @@ void find_partitions() noexcept {
|
|||||||
// for test delete /dev:sda8
|
// for test delete /dev:sda8
|
||||||
// delete_partition_in_list "/dev/sda8"
|
// delete_partition_in_list "/dev/sda8"
|
||||||
|
|
||||||
|
// TODO(vnepogodin): rewatch that part later on..
|
||||||
|
#if 0
|
||||||
const auto& system_info = std::get<std::string>(config_data["SYSTEM"]);
|
const auto& system_info = std::get<std::string>(config_data["SYSTEM"]);
|
||||||
// Deal with partitioning schemes appropriate to mounting, lvm, and/or luks.
|
// Deal with partitioning schemes appropriate to mounting, lvm, and/or luks.
|
||||||
if (include_part == "\'part\\|lvm\\|crypt\'" && (((system_info == "UEFI") && (number_partitions < 2)) || ((system_info == "BIOS") && (number_partitions == 0)))) {
|
if (include_part == "\'part\\|lvm\\|crypt\'" && (((system_info == "UEFI") && (number_partitions < 2)) || ((system_info == "BIOS") && (number_partitions == 0)))) {
|
||||||
// Deal with incorrect partitioning for main mounting function
|
// Deal with incorrect partitioning for main mounting function
|
||||||
tui::create_partitions();
|
tui::create_partitions();
|
||||||
|
return;
|
||||||
} else if (include_part == "\'part\\|crypt\'" && number_partitions == 0) {
|
} else if (include_part == "\'part\\|crypt\'" && number_partitions == 0) {
|
||||||
// Ensure there is at least one partition for LVM
|
// Ensure there is at least one partition for LVM
|
||||||
tui::create_partitions();
|
tui::create_partitions();
|
||||||
|
return;
|
||||||
} else if (include_part == "\'part\\|lvm\'" && number_partitions < 2) {
|
} else if (include_part == "\'part\\|lvm\'" && number_partitions < 2) {
|
||||||
// Ensure there are at least two partitions for LUKS
|
// Ensure there are at least two partitions for LUKS
|
||||||
tui::create_partitions();
|
tui::create_partitions();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// List partitions to be hidden from the mounting menu
|
// List partitions to be hidden from the mounting menu
|
||||||
|
Loading…
Reference in New Issue
Block a user