diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml index b0651d72..3c2674d4 100644 --- a/.github/workflows/pre-release.yaml +++ b/.github/workflows/pre-release.yaml @@ -6,6 +6,10 @@ permissions: on: workflow_dispatch: # Manual trigger added + workflow_run: + workflows: ["LinUtil Release"] + types: + - completed jobs: build-runspace: @@ -31,9 +35,8 @@ jobs: append_body: false files: | ./build/linutil - ./build/linutil-aarch64 prerelease: true generate_release_notes: true env: version: ${{ env.version }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9990317a..5a76af0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,54 +2,60 @@ Thank you for considering contributing to Linutil! We appreciate your effort in helping improve this project. To ensure that your contributions align with the goals and quality standards of Linutil, please follow these guidelines: -## 1. Setting Up Your Development Environment +## 1. **Install Rust**: -1. **Clone the repo**: Start by cloning the Linutil repository to your local machine. - ```bash - git clone https://github.com/christitustech/linutil.git - cd linutil +Make sure you have Rust installed on your machine. You can install it by following the instructions at [rust-lang.org](https://www.rust-lang.org/tools/install). + +## 2. **Fork and Clone the repo** + +1. Make a fork of the repo in GitHub +2. Clone the fork +```bash +git clone https://github.com/YOUR_USERNAME_HERE/linutil.git +cd linutil ``` -2. **Install Rust**: Make sure you have Rust installed on your machine. If you don't, you can install it by following the instructions at [rust-lang.org](https://www.rust-lang.org/tools/install). -3. **Edit the files you want to change**: Make your changes to the relevant files. -4. **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected. -## 2. Make Meaningful Changes +## 3. Make your changes +- **Edit the files you want to change**: Make your changes to the relevant files. +- **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected. + +## 4. Understand the existing code - **Have a clear reason**: Don’t change the way things are done without a valid reason. If you propose an alteration, be prepared to explain why it’s necessary and how it improves the project. - **Respect existing conventions**: Changes should align with the existing code style, design patterns, and overall project philosophy. If you want to introduce a new way of doing things, justify it clearly. -## 3. Learn from Past Pull Requests (PRs) +## 5. Learn from Past Pull Requests (PRs) - **Check merged PRs**: Reviewing merged pull requests can give you an idea of what kind of contributions are accepted and how they are implemented. - **Study rejected PRs**: This is especially important as it helps you avoid making similar mistakes or proposing changes that have already been considered and declined. -## 4. Write Clean, Descriptive Commit Messages +## 6. Write Clean, Descriptive Commit Messages - **Be descriptive**: Your commit messages should clearly describe what the change does and why it was made. - **Use the imperative mood**: For example, "Add feature X" or "Fix bug in Y", rather than "Added feature X" or "Fixed bug in Y". - **Keep commits clean**: Avoid committing a change and then immediately following it with a fix for that change. Instead, amend your commit or squash it if needed. -## 5. Keep Your Pull Requests (PRs) Small and Focused +## 7. Keep Your Pull Requests (PRs) Small and Focused - **Make small, targeted PRs**: Focus on one feature or fix per pull request. This makes it easier to review and increases the likelihood of acceptance. - **Avoid combining unrelated changes**: PRs that tackle multiple unrelated issues are harder to review and might be rejected because of a single problem. -## 6. Code Review and Feedback +## 8. Code Review and Feedback - **Expect feedback**: PRs will undergo code review. Be open to feedback and willing to make adjustments as needed. - **Participate in reviews**: If you feel comfortable, review other contributors' PRs as well. Peer review is a great way to learn and ensure high-quality contributions. -## 7. Contributing Is More Than Just Code +## 9. Contributing Is More Than Just Code - **Test the tool**: Running tests and providing feedback on how the tool works in different environments is a valuable contribution. - **Write well-formed issues**: Clearly describe bugs or problems you encounter, providing as much detail as possible, including steps to reproduce the issue. - **Propose reasonable feature requests**: When suggesting new features, ensure they fit within the scope, style, and design of the project. Provide clear reasoning and use cases. -## 8. Documentation +## 10. Documentation - **Update the documentation**: If your change affects the functionality, please update the relevant documentation files to reflect this. -## 9. License +## 11. License - **Agree to the license**: By contributing to Linutil, you agree that your contributions will be licensed under the project's MIT license. diff --git a/Cargo.lock b/Cargo.lock index dc59c8e6..7bf16b61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -163,9 +163,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.13" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -173,9 +173,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.13" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -1121,9 +1121,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "which" -version = "6.0.2" +version = "6.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" dependencies = [ "either", "home", diff --git a/Cargo.toml b/Cargo.toml index 8c06863d..a2c33b32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] chrono = "0.4.33" -clap = { version = "4.5.13", features = ["derive"] } +clap = { version = "4.5.16", features = ["derive"] } crossterm = "0.27.0" ego-tree = "0.6.2" oneshot = "0.1.8" @@ -16,7 +16,7 @@ include_dir = "0.7.4" tempdir = "0.3.7" serde = { version = "1.0.205", features = ["derive"] } toml = "0.8.19" -which = "6.0.2" +which = "6.0.3" unicode-width = "0.1.13" [[bin]] diff --git a/README.md b/README.md index a2978c3c..54d2f21b 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,19 @@ **Linutil** is a distro-agnostic toolbox designed to simplify everyday Linux tasks. It helps you set up applications and optimize your system for specific use cases. The utility is actively developed in Rust πŸ¦€, providing performance and reliability. -*Note:* Since the project is still in active development, you may encounter some issues. Please consider [submitting feedback](https://github.com/ChrisTitusTech/linutil/issues) if you do. +> [!NOTE] +> Since the project is still in active development, you may encounter some issues. Please consider [submitting feedback](https://github.com/ChrisTitusTech/linutil/issues) if you do. ## πŸ’‘ Usage - -To get started, open your terminal and run the following command: +To get started, pick which branch you would like to use, then run the command in your terminal: +### Stable Branch (Recommended) ```bash curl -fsSL https://christitus.com/linux | sh ``` +### Dev branch +```bash +curl -fsSL https://christitus.com/linuxdev | sh +``` ## πŸ’– Support If you find Linutil helpful, please consider giving it a ⭐️ to show your support! diff --git a/build/linutil b/build/linutil index 39a0d589..1c4c97ea 100755 Binary files a/build/linutil and b/build/linutil differ diff --git a/docs/assets/preview.png b/docs/assets/preview.png index e06e3ecd..de4b54e3 100644 Binary files a/docs/assets/preview.png and b/docs/assets/preview.png differ diff --git a/src/commands/applications-setup/alacritty-setup.sh b/src/commands/applications-setup/alacritty-setup.sh index 6911fd3c..a26b78f8 100755 --- a/src/commands/applications-setup/alacritty-setup.sh +++ b/src/commands/applications-setup/alacritty-setup.sh @@ -7,10 +7,10 @@ setupAlacritty() { if ! command_exists alacritty; then case ${PACKAGER} in pacman) - sudo ${PACKAGER} -S --needed --noconfirm alacritty + $ESCALATION_TOOL ${PACKAGER} -S --needed --noconfirm alacritty ;; *) - sudo ${PACKAGER} install -y alacritty + $ESCALATION_TOOL ${PACKAGER} install -y alacritty ;; esac else @@ -26,4 +26,5 @@ setupAlacritty() { } checkEnv +checkEscalationTool setupAlacritty diff --git a/src/commands/applications-setup/dwmtitus-setup.sh b/src/commands/applications-setup/dwmtitus-setup.sh index d8543fc7..548d9073 100644 --- a/src/commands/applications-setup/dwmtitus-setup.sh +++ b/src/commands/applications-setup/dwmtitus-setup.sh @@ -1,27 +1,27 @@ #!/bin/sh -e . ../common-script.sh -makeDWM(){ - cd $HOME && git clone https://github.com/ChrisTitusTech/dwm-titus.git # CD to Home directory to install dwm-titus - # This path can be changed (e.g. to linux-toolbox directory) - cd dwm-titus/ # Hardcoded path, maybe not the best. - sudo ./setup.sh # Run setup - sudo make clean install # Run make clean install +makeDWM() { + cd "$HOME" && git clone https://github.com/ChrisTitusTech/dwm-titus.git # CD to Home directory to install dwm-titus + # This path can be changed (e.g. to linux-toolbox directory) + cd dwm-titus/ # Hardcoded path, maybe not the best. + $ESCALATION_TOOL ./setup.sh # Run setup + $ESCALATION_TOOL make clean install # Run make clean install } setupDWM() { echo "Installing DWM-Titus if not already installed" case "$PACKAGER" in # Install pre-Requisites pacman) - sudo "$PACKAGER" -S --needed --noconfirm base-devel libx11 libxinerama libxft imlib2 + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel libx11 libxinerama libxft imlib2 ;; *) - sudo "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev + $ESCALATION_TOOL "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev ;; esac - } checkEnv +checkEscalationTool setupDWM makeDWM diff --git a/src/commands/applications-setup/kitty-setup.sh b/src/commands/applications-setup/kitty-setup.sh index 8088f594..a9d26293 100755 --- a/src/commands/applications-setup/kitty-setup.sh +++ b/src/commands/applications-setup/kitty-setup.sh @@ -7,10 +7,10 @@ setupKitty() { if ! command_exists kitty; then case ${PACKAGER} in pacman) - sudo "${PACKAGER}" -S --needed --noconfirm kitty + $ESCALATION_TOOL "${PACKAGER}" -S --needed --noconfirm kitty ;; *) - sudo "${PACKAGER}" install -y kitty + $ESCALATION_TOOL "${PACKAGER}" install -y kitty ;; esac else @@ -18,12 +18,13 @@ setupKitty() { fi echo "Copy Kitty config files" if [ -d "${HOME}/.config/kitty" ]; then - cp -r "${HOME}"/.config/kitty "${HOME}"/.config/kitty-bak + cp -r "${HOME}/.config/kitty" "${HOME}/.config/kitty-bak" fi - mkdir -p "${HOME}"/.config/kitty/ - wget -O "${HOME}"/.config/kitty/kitty.conf https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/kitty.conf - wget -O "${HOME}"/.config/kitty/nord.conf https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/nord.conf + mkdir -p "${HOME}/.config/kitty/" + wget -O "${HOME}/.config/kitty/kitty.conf" https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/kitty.conf + wget -O "${HOME}/.config/kitty/nord.conf" https://github.com/ChrisTitusTech/dwm-titus/raw/main/config/kitty/nord.conf } checkEnv +checkEscalationTool setupKitty diff --git a/src/commands/applications-setup/rofi-setup.sh b/src/commands/applications-setup/rofi-setup.sh index 236e42e2..9c06f953 100755 --- a/src/commands/applications-setup/rofi-setup.sh +++ b/src/commands/applications-setup/rofi-setup.sh @@ -7,10 +7,10 @@ setupRofi() { if ! command_exists rofi; then case "$PACKAGER" in pacman) - sudo "$PACKAGER" -S --needed --noconfirm rofi + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm rofi ;; *) - sudo "$PACKAGER" install -y rofi + $ESCALATION_TOOL "$PACKAGER" install -y rofi ;; esac else @@ -31,4 +31,5 @@ setupRofi() { } checkEnv +checkEscalationTool setupRofi diff --git a/src/commands/applications-setup/zsh-setup.sh b/src/commands/applications-setup/zsh-setup.sh index f3e7d0c1..eaa608b5 100644 --- a/src/commands/applications-setup/zsh-setup.sh +++ b/src/commands/applications-setup/zsh-setup.sh @@ -8,10 +8,10 @@ install_zsh() { if ! command_exists zsh; then case "$PACKAGER" in pacman) - sudo "$PACKAGER" -S --needed --noconfirm zsh + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm zsh ;; *) - sudo "$PACKAGER" install -y zsh + $ESCALATION_TOOL "$PACKAGER" install -y zsh ;; esac else @@ -43,9 +43,10 @@ RPROMPT='%F{15}(%F{166}%D{%H:%M}%F{15})%f' EOL # Ensure /etc/zsh/zshenv sets ZDOTDIR to the user's config directory - echo 'export ZDOTDIR="$HOME/.config/zsh"' | sudo tee -a /etc/zsh/zshenv + echo 'export ZDOTDIR="$HOME/.config/zsh"' | $ESCALATION_TOOL tee -a /etc/zsh/zshenv } checkEnv -setup_zsh_config +checkEscalationTool install_zsh +setup_zsh_config diff --git a/src/commands/common-script.sh b/src/commands/common-script.sh index 064bf3c9..bfea62f4 100644 --- a/src/commands/common-script.sh +++ b/src/commands/common-script.sh @@ -11,6 +11,23 @@ command_exists() { which "$1" >/dev/null 2>&1 } +checkEscalationTool() { + ## Check for escalation tools. + if [ -z "$ESCALATION_TOOL_CHECKED" ]; then + ESCALATION_TOOLS='sudo doas' + for tool in ${ESCALATION_TOOLS}; do + if command_exists "${tool}"; then + ESCALATION_TOOL=${tool} + echo "Using ${tool} for privilege escalation" + ESCALATION_TOOL_CHECKED=true + return 0 + fi + done + + echo -e "${RED}Can't find a supported escalation tool${RC}" + exit 1 + fi +} checkCommandRequirements() { ## Check for requirements. @@ -82,4 +99,5 @@ checkEnv() { checkCurrentDirectoryWritable checkSuperUser checkDistro + checkEscalationTool } diff --git a/src/commands/security/firewall-baselines.sh b/src/commands/security/firewall-baselines.sh index 69963083..ee0441b6 100644 --- a/src/commands/security/firewall-baselines.sh +++ b/src/commands/security/firewall-baselines.sh @@ -7,10 +7,10 @@ installPkg() { if ! command_exists ufw; then case ${PACKAGER} in pacman) - sudo "${PACKAGER}" -S --needed --noconfirm ufw + $ESCALATION_TOOL "${PACKAGER}" -S --needed --noconfirm ufw ;; *) - sudo "${PACKAGER}" install -y ufw + $ESCALATION_TOOL "${PACKAGER}" install -y ufw ;; esac else @@ -22,27 +22,28 @@ configureUFW() { echo -e "${GREEN}Using Chris Titus Recommended Firewall Rules${RC}" echo "Disabling UFW" - sudo ufw disable + $ESCALATION_TOOL ufw disable echo "Limiting port 22/tcp (UFW)" - sudo ufw limit 22/tcp + $ESCALATION_TOOL ufw limit 22/tcp echo "Allowing port 80/tcp (UFW)" - sudo ufw allow 80/tcp + $ESCALATION_TOOL ufw allow 80/tcp echo "Allowing port 443/tcp (UFW)" - sudo ufw allow 443/tcp + $ESCALATION_TOOL ufw allow 443/tcp echo "Denying Incoming Packets by Default(UFW)" - sudo ufw default deny incoming + $ESCALATION_TOOL ufw default deny incoming echo "Allowing Outcoming Packets by Default(UFW)" - sudo ufw default allow outgoing + $ESCALATION_TOOL ufw default allow outgoing - sudo ufw enable + $ESCALATION_TOOL ufw enable echo -e "${GREEN}Enabled Firewall with Baselines!${RC}" } checkEnv +checkEscalationTool installPkg configureUFW diff --git a/src/commands/system-setup/1-compile-setup.sh b/src/commands/system-setup/1-compile-setup.sh index 1130cee1..2e1f644f 100755 --- a/src/commands/system-setup/1-compile-setup.sh +++ b/src/commands/system-setup/1-compile-setup.sh @@ -2,28 +2,6 @@ . ../common-script.sh -# Check if the home directory and linuxtoolbox folder exist, create them if they don't -LINUXTOOLBOXDIR="$HOME/linuxtoolbox" - -if [ ! -d "$LINUXTOOLBOXDIR" ]; then - echo -e "${YELLOW}Creating linuxtoolbox directory: $LINUXTOOLBOXDIR${RC}" - mkdir -p "$LINUXTOOLBOXDIR" - echo -e "${GREEN}linuxtoolbox directory created: $LINUXTOOLBOXDIR${RC}" -fi - -if [ ! -d "$LINUXTOOLBOXDIR/linutil" ]; then - echo -e "${YELLOW}Cloning linutil repository into: $LINUXTOOLBOXDIR/linutil${RC}" - git clone https://github.com/ChrisTitusTech/linutil "$LINUXTOOLBOXDIR/linutil" - if [ $? -eq 0 ]; then - echo -e "${GREEN}Successfully cloned linutil repository${RC}" - else - echo -e "${RED}Failed to clone linutil repository${RC}" - exit 1 - fi -fi - -cd "$LINUXTOOLBOXDIR/linutil" || exit - installDepend() { ## Check for dependencies. DEPENDENCIES='tar tree multitail tldr trash-cli unzip cmake make jq' @@ -31,16 +9,16 @@ installDepend() { case $PACKAGER in pacman) if ! grep -q "^\s*\[multilib\]" /etc/pacman.conf; then - echo "[multilib]" | sudo tee -a /etc/pacman.conf - echo "Include = /etc/pacman.d/mirrorlist" | sudo tee -a /etc/pacman.conf - sudo "$PACKAGER" -Syu + echo "[multilib]" | $ESCALATION_TOOL tee -a /etc/pacman.conf + echo "Include = /etc/pacman.d/mirrorlist" | $ESCALATION_TOOL tee -a /etc/pacman.conf + $ESCALATION_TOOL "$PACKAGER" -Syu else echo "Multilib is already enabled." fi if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo "$PACKAGER" -S --needed --noconfirm base-devel - cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R "$USER":"$USER" ./yay-git + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R "$USER":"$USER" ./yay-git cd yay-git && makepkg --noconfirm -si else echo "Aur helper already installed" @@ -53,30 +31,30 @@ installDepend() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - "$AUR_HELPER" -S --needed --noconfirm "$DEPENDENCIES" + $AUR_HELPER -S --needed --noconfirm "$DEPENDENCIES" ;; apt-get|nala) COMPILEDEPS='build-essential' - sudo "$PACKAGER" update - sudo dpkg --add-architecture i386 - sudo "$PACKAGER" update - sudo "$PACKAGER" install -y $DEPENDENCIES $COMPILEDEPS + $ESCALATION_TOOL "$PACKAGER" update + $ESCALATION_TOOL dpkg --add-architecture i386 + $ESCALATION_TOOL "$PACKAGER" update + $ESCALATION_TOOL "$PACKAGER" install -y $DEPENDENCIES $COMPILEDEPS ;; dnf) COMPILEDEPS='@development-tools' - sudo "$PACKAGER" update - sudo "$PACKAGER" config-manager --set-enabled powertools - sudo "$PACKAGER" install -y "$DEPENDENCIES" $COMPILEDEPS - sudo "$PACKAGER" install -y glibc-devel.i686 libgcc.i686 + $ESCALATION_TOOL "$PACKAGER" update + $ESCALATION_TOOL "$PACKAGER" config-manager --set-enabled powertools + $ESCALATION_TOOL "$PACKAGER" install -y "$DEPENDENCIES" $COMPILEDEPS + $ESCALATION_TOOL "$PACKAGER" install -y glibc-devel.i686 libgcc.i686 ;; zypper) COMPILEDEPS='patterns-devel-base-devel_basis' - sudo "$PACKAGER" refresh - sudo "$PACKAGER" --non-interactive install "$DEPENDENCIES" $COMPILEDEPS - sudo "$PACKAGER" --non-interactive install libgcc_s1-gcc7-32bit glibc-devel-32bit + $ESCALATION_TOOL "$PACKAGER" refresh + $ESCALATION_TOOL "$PACKAGER" --non-interactive install "$DEPENDENCIES" $COMPILEDEPS + $ESCALATION_TOOL "$PACKAGER" --non-interactive install libgcc_s1-gcc7-32bit glibc-devel-32bit ;; *) - sudo "$PACKAGER" install -y $DEPENDENCIES # Fixed bug where no packages found on debian-based + $ESCALATION_TOOL "$PACKAGER" install -y $DEPENDENCIES # Fixed bug where no packages found on debian-based ;; esac } @@ -102,5 +80,6 @@ install_additional_dependencies() { } checkEnv +checkEscalationTool installDepend install_additional_dependencies diff --git a/src/commands/system-setup/2-gaming-setup.sh b/src/commands/system-setup/2-gaming-setup.sh index 4393b0b0..207d7817 100755 --- a/src/commands/system-setup/2-gaming-setup.sh +++ b/src/commands/system-setup/2-gaming-setup.sh @@ -7,16 +7,16 @@ installDepend() { echo -e "${YELLOW}Installing dependencies...${RC}" if [ "$PACKAGER" = "pacman" ]; then if ! grep -q "^\s*\[multilib\]" /etc/pacman.conf; then - echo "[multilib]" | sudo tee -a /etc/pacman.conf - echo "Include = /etc/pacman.d/mirrorlist" | sudo tee -a /etc/pacman.conf - sudo ${PACKAGER} -Syu + echo "[multilib]" | $ESCALATION_TOOL tee -a /etc/pacman.conf + echo "Include = /etc/pacman.d/mirrorlist" | $ESCALATION_TOOL tee -a /etc/pacman.conf + $ESCALATION_TOOL ${PACKAGER} -Syu else echo "Multilib is already enabled." fi if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo ${PACKAGER} -S --needed --noconfirm base-devel - cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R ${USER}:${USER} ./yay-git + $ESCALATION_TOOL ${PACKAGER} -S --needed --noconfirm base-devel + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R ${USER}:${USER} ./yay-git cd yay-git && makepkg --noconfirm -si else echo "Aur helper already installed" @@ -29,24 +29,24 @@ installDepend() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - ${AUR_HELPER} -S --needed --noconfirm wine giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls \ + $AUR_HELPER -S --needed --noconfirm wine giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls \ mpg123 lib32-mpg123 openal lib32-openal v4l-utils lib32-v4l-utils libpulse lib32-libpulse libgpg-error \ lib32-libgpg-error alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib libjpeg-turbo lib32-libjpeg-turbo \ sqlite lib32-sqlite libxcomposite lib32-libxcomposite libxinerama lib32-libgcrypt libgcrypt lib32-libxinerama \ ncurses lib32-ncurses ocl-icd lib32-ocl-icd libxslt lib32-libxslt libva lib32-libva gtk3 \ lib32-gtk3 gst-plugins-base-libs lib32-gst-plugins-base-libs vulkan-icd-loader lib32-vulkan-icd-loader elif [ "$PACKAGER" = "apt-get" ]; then - sudo ${PACKAGER} update - sudo ${PACKAGER} install -y wine64 wine32 libasound2-plugins:i386 libsdl2-2.0-0:i386 libdbus-1-3:i386 libsqlite3-0:i386 + $ESCALATION_TOOL ${PACKAGER} update + $ESCALATION_TOOL ${PACKAGER} install -y wine64 wine32 libasound2-plugins:i386 libsdl2-2.0-0:i386 libdbus-1-3:i386 libsqlite3-0:i386 elif [ "$PACKAGER" = "dnf" ] || [ "$PACKAGER" = "zypper" ]; then - sudo ${PACKAGER} install -y wine + $ESCALATION_TOOL ${PACKAGER} install -y wine else - sudo ${PACKAGER} install -y ${DEPENDENCIES} + $ESCALATION_TOOL ${PACKAGER} install -y ${DEPENDENCIES} fi } install_additional_dependencies() { - case $(which apt-get || which zypper || which dnf || which pacman) in + case $(command -v apt-get || command -v zypper || command -v dnf || command -v pacman) in *apt-get) version=$(git -c 'versionsort.suffix=-' ls-remote --tags --sort='v:refname' https://github.com/lutris/lutris | grep -v 'beta' | @@ -58,8 +58,8 @@ install_additional_dependencies() { # Install the downloaded .deb package using apt-get echo "Installing lutris_${version_no_v}_all.deb" - sudo apt-get update - sudo apt-get install ./lutris_${version_no_v}_all.deb + $ESCALATION_TOOL apt-get update + $ESCALATION_TOOL apt-get install ./lutris_${version_no_v}_all.deb # Clean up the downloaded .deb file rm lutris_${version_no_v}_all.deb @@ -70,34 +70,45 @@ install_additional_dependencies() { #Install steam on Debian if (lsb_release -i | grep -qi Debian); then #Enable i386 repos - sudo dpkg --add-architecture i386 + $ESCALATION_TOOL dpkg --add-architecture i386 # Install software-properties-common to be able to add repos - sudo apt-get install -y software-properties-common + $ESCALATION_TOOL apt-get install -y software-properties-common # Add repos necessary for installing steam - sudo apt-add-repository contrib -y - sudo apt-add-repository non-free -y + $ESCALATION_TOOL apt-add-repository contrib -y + $ESCALATION_TOOL apt-add-repository non-free -y #Install steam - sudo apt-get install steam-installer -y + $ESCALATION_TOOL apt-get install steam-installer -y else #Install steam on Ubuntu - sudo apt-get install -y steam + $ESCALATION_TOOL apt-get install -y steam fi ;; *zypper) - + ;; *dnf) - + ;; *pacman) + echo "Installing Steam for Arch Linux..." + $ESCALATION_TOOL pacman -S --needed --noconfirm steam + echo "Steam installation complete." + echo "Installing Lutris for Arch Linux..." + $ESCALATION_TOOL pacman -S --needed --noconfirm lutris + echo "Lutris installation complete." + + echo "Installing GOverlay for Arch Linux..." + $ESCALATION_TOOL pacman -S --needed --noconfirm goverlay + echo "GOverlay installation complete." ;; *) - - ;; + + ;; esac } checkEnv +checkEscalationTool installDepend install_additional_dependencies diff --git a/src/commands/system-setup/3-global-theme.sh b/src/commands/system-setup/3-global-theme.sh index e255ea76..1f9c7cce 100644 --- a/src/commands/system-setup/3-global-theme.sh +++ b/src/commands/system-setup/3-global-theme.sh @@ -2,34 +2,23 @@ . ../common-script.sh -# Check if the home directory and linuxtoolbox folder exist, create them if they don't -LINUXTOOLBOXDIR="$HOME/linuxtoolbox" - -if [ ! -d "$LINUXTOOLBOXDIR" ]; then - printf "${YELLOW}Creating linuxtoolbox directory: %s${RC}\n" "$LINUXTOOLBOXDIR" - mkdir -p "$LINUXTOOLBOXDIR" - printf "${GREEN}linuxtoolbox directory created: %s${RC}\n" "$LINUXTOOLBOXDIR" -fi - -cd "$LINUXTOOLBOXDIR" || exit - install_theme_tools() { printf "${YELLOW}Installing theme tools (qt6ct and kvantum)...${RC}\n" case $PACKAGER in apt-get) - sudo apt-get update - sudo apt-get install -y qt6ct kvantum + $ESCALATION_TOOL apt-get update + $ESCALATION_TOOL apt-get install -y qt6ct kvantum ;; zypper) - sudo zypper refresh - sudo zypper --non-interactive install qt6ct kvantum + $ESCALATION_TOOL zypper refresh + $ESCALATION_TOOL zypper --non-interactive install qt6ct kvantum ;; dnf) - sudo dnf update - sudo dnf install -y qt6ct kvantum + $ESCALATION_TOOL dnf update + $ESCALATION_TOOL dnf install -y qt6ct kvantum ;; pacman) - sudo pacman -S --needed --noconfirm qt6ct kvantum + $ESCALATION_TOOL pacman -S --needed --noconfirm qt6ct kvantum ;; *) printf "${RED}Unsupported package manager. Please install qt6ct and kvantum manually.${RC}\n" @@ -52,7 +41,7 @@ EOF # Add QT_QPA_PLATFORMTHEME to /etc/environment if ! grep -q "QT_QPA_PLATFORMTHEME=qt6ct" /etc/environment; then printf "${YELLOW}Adding QT_QPA_PLATFORMTHEME to /etc/environment...${RC}\n" - echo "QT_QPA_PLATFORMTHEME=qt6ct" | sudo tee -a /etc/environment > /dev/null + echo "QT_QPA_PLATFORMTHEME=qt6ct" | $ESCALATION_TOOL tee -a /etc/environment > /dev/null printf "${GREEN}QT_QPA_PLATFORMTHEME added to /etc/environment.${RC}\n" else printf "${GREEN}QT_QPA_PLATFORMTHEME already set in /etc/environment.${RC}\n" @@ -70,6 +59,7 @@ EOF } checkEnv +checkEscalationTool install_theme_tools configure_qt6ct configure_kvantum diff --git a/src/commands/system-setup/4-remove-snaps.sh b/src/commands/system-setup/4-remove-snaps.sh index 26a115f3..f804aa5b 100644 --- a/src/commands/system-setup/4-remove-snaps.sh +++ b/src/commands/system-setup/4-remove-snaps.sh @@ -5,24 +5,26 @@ removeSnaps() { case $PACKAGER in pacman) - sudo ${PACKAGER} -Rns snapd + $ESCALATION_TOOL ${PACKAGER} -Rns snapd ;; apt-get|nala) - sudo ${PACKAGER} autoremove --purge snapd + $ESCALATION_TOOL ${PACKAGER} autoremove --purge snapd if [ "$ID" = ubuntu ]; then - sudo apt-mark hold snapd + $ESCALATION_TOOL apt-mark hold snapd fi ;; dnf) - sudo ${PACKAGER} remove snapd + $ESCALATION_TOOL ${PACKAGER} remove snapd ;; zypper) - sudo ${PACKAGER} remove snapd + $ESCALATION_TOOL ${PACKAGER} remove snapd ;; *) - echo "removing snapd not implemented for this package manager" + echo "Removing snapd not implemented for this package manager" + ;; esac } checkEnv +checkEscalationTool removeSnaps diff --git a/src/commands/system-setup/arch/paru-setup.sh b/src/commands/system-setup/arch/paru-setup.sh old mode 100644 new mode 100755 index f0b53ae1..8b9f388d --- a/src/commands/system-setup/arch/paru-setup.sh +++ b/src/commands/system-setup/arch/paru-setup.sh @@ -7,8 +7,8 @@ installDepend() { pacman) if ! command_exists paru; then echo "Installing paru as AUR helper..." - sudo "$PACKAGER" -S --needed --noconfirm base-devel - cd /opt && sudo git clone https://aur.archlinux.org/paru.git && sudo chown -R "$USER": ./paru + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/paru.git && $ESCALATION_TOOL chown -R "$USER": ./paru cd paru && makepkg --noconfirm -si echo "Paru installed" else @@ -22,4 +22,5 @@ installDepend() { } checkEnv -installDepend \ No newline at end of file +checkEscalationTool +installDepend diff --git a/src/commands/system-setup/arch/server-setup.sh b/src/commands/system-setup/arch/server-setup.sh new file mode 100755 index 00000000..e907ccaa --- /dev/null +++ b/src/commands/system-setup/arch/server-setup.sh @@ -0,0 +1,676 @@ +#!/bin/bash + +# Redirect stdout and stderr to archsetup.txt and still output to console +exec > >(tee -i archsetup.txt) +exec 2>&1 + +echo -ne " +------------------------------------------------------------------------- + β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β• +β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘ +β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ +β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β• +------------------------------------------------------------------------- + Automated Arch Linux Installer +------------------------------------------------------------------------- + +Verifying Arch Linux ISO is Booted + +" +if [ ! -f /usr/bin/pacstrap ]; then + echo "This script must be run from an Arch Linux ISO environment." + exit 1 +fi + +root_check() { + if [[ "$(id -u)" != "0" ]]; then + echo -ne "ERROR! This script must be run under the 'root' user!\n" + exit 0 + fi +} + +docker_check() { + if awk -F/ '$2 == "docker"' /proc/self/cgroup | read -r; then + echo -ne "ERROR! Docker container is not supported (at the moment)\n" + exit 0 + elif [[ -f /.dockerenv ]]; then + echo -ne "ERROR! Docker container is not supported (at the moment)\n" + exit 0 + fi +} + +arch_check() { + if [[ ! -e /etc/arch-release ]]; then + echo -ne "ERROR! This script must be run in Arch Linux!\n" + exit 0 + fi +} + +pacman_check() { + if [[ -f /var/lib/pacman/db.lck ]]; then + echo "ERROR! Pacman is blocked." + echo -ne "If not running remove /var/lib/pacman/db.lck.\n" + exit 0 + fi +} + +background_checks() { + root_check + arch_check + pacman_check + docker_check +} + +select_option() { + local options=("$@") + local num_options=${#options[@]} + local selected=0 + local last_selected=-1 + + while true; do + # Move cursor up to the start of the menu + if [ $last_selected -ne -1 ]; then + echo -ne "\033[${num_options}A" + fi + + if [ $last_selected -eq -1 ]; then + echo "Please select an option using the arrow keys and Enter:" + fi + for i in "${!options[@]}"; do + if [ $i -eq $selected ]; then + echo "> ${options[$i]}" + else + echo " ${options[$i]}" + fi + done + + last_selected=$selected + + # Read user input + read -rsn1 key + case $key in + $'\x1b') # ESC sequence + read -rsn2 -t 0.1 key + case $key in + '[A') # Up arrow + ((selected--)) + if [ $selected -lt 0 ]; then + selected=$((num_options - 1)) + fi + ;; + '[B') # Down arrow + ((selected++)) + if [ $selected -ge $num_options ]; then + selected=0 + fi + ;; + esac + ;; + '') # Enter key + break + ;; + esac + done + + return $selected +} + +# @description Displays ArchTitus logo +# @noargs +logo () { +# This will be shown on every set as user is progressing +echo -ne " +------------------------------------------------------------------------- + β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β• +β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘ +β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ +β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β• +------------------------------------------------------------------------ + Please select presetup settings for your system +------------------------------------------------------------------------ +" +} +# @description This function will handle file systems. At this movement we are handling only +# btrfs and ext4. Others will be added in future. +filesystem () { + echo -ne " + Please Select your file system for both boot and root + " + options=("btrfs" "ext4" "luks" "exit") + select_option "${options[@]}" + + case $? in + 0) export FS=btrfs;; + 1) export FS=ext4;; + 2) + set_password "LUKS_PASSWORD" + export FS=luks + ;; + 3) exit ;; + *) echo "Wrong option please select again"; filesystem;; + esac +} +# @description Detects and sets timezone. +timezone () { + # Added this from arch wiki https://wiki.archlinux.org/title/System_time + time_zone="$(curl --fail https://ipapi.co/timezone)" + echo -ne " + System detected your timezone to be '$time_zone' \n" + echo -ne "Is this correct? + " + options=("Yes" "No") + select_option "${options[@]}" + + case ${options[$?]} in + y|Y|yes|Yes|YES) + echo "${time_zone} set as timezone" + export TIMEZONE=$time_zone;; + n|N|no|NO|No) + echo "Please enter your desired timezone e.g. Europe/London :" + read new_timezone + echo "${new_timezone} set as timezone" + export TIMEZONE=$new_timezone;; + *) echo "Wrong option. Try again";timezone;; + esac +} +# @description Set user's keyboard mapping. +keymap () { + echo -ne " + Please select key board layout from this list" + # These are default key maps as presented in official arch repo archinstall + options=(us by ca cf cz de dk es et fa fi fr gr hu il it lt lv mk nl no pl ro ru sg ua uk) + + select_option "${options[@]}" + keymap=${options[$?]} + + echo -ne "Your key boards layout: ${keymap} \n" + export KEYMAP=$keymap +} + +# @description Choose whether drive is SSD or not. +drivessd () { + echo -ne " + Is this an ssd? yes/no: + " + + options=("Yes" "No") + select_option "${options[@]}" + + case ${options[$?]} in + y|Y|yes|Yes|YES) + export MOUNT_OPTIONS="noatime,compress=zstd,ssd,commit=120";; + n|N|no|NO|No) + export MOUNT_OPTIONS="noatime,compress=zstd,commit=120";; + *) echo "Wrong option. Try again";drivessd;; + esac +} + +# @description Disk selection for drive to be used with installation. +diskpart () { +echo -ne " +------------------------------------------------------------------------ + THIS WILL FORMAT AND DELETE ALL DATA ON THE DISK + Please make sure you know what you are doing because + after formating your disk there is no way to get data back + *****BACKUP YOUR DATA BEFORE CONTINUING***** + ***I AM NOT RESPONSIBLE FOR ANY DATA LOSS*** +------------------------------------------------------------------------ + +" + + PS3=' + Select the disk to install on: ' + options=($(lsblk -n --output TYPE,KNAME,SIZE | awk '$1=="disk"{print "/dev/"$2"|"$3}')) + + select_option "${options[@]}" + disk=${options[$?]%|*} + + echo -e "\n${disk%|*} selected \n" + export DISK=${disk%|*} + + drivessd +} + +# @description Gather username and password to be used for installation. +userinfo () { + # Loop through user input until the user gives a valid username + while true + do + read -p "Please enter username:" username + if [[ "${username,,}" =~ ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$ ]] + then + break + fi + echo "Incorrect username." + done + export USERNAME=$username + + while true + do + read -rs -p "Please enter password: " PASSWORD1 + echo -ne "\n" + read -rs -p "Please re-enter password: " PASSWORD2 + echo -ne "\n" + if [[ "$PASSWORD1" == "$PASSWORD2" ]]; then + break + else + echo -ne "ERROR! Passwords do not match. \n" + fi + done + export PASSWORD=$PASSWORD1 + + # Loop through user input until the user gives a valid hostname, but allow the user to force save + while true + do + read -p "Please name your machine:" name_of_machine + # hostname regex (!!couldn't find spec for computer name!!) + if [[ "${name_of_machine,,}" =~ ^[a-z][a-z0-9_.-]{0,62}[a-z0-9]$ ]] + then + break + fi + # if validation fails allow the user to force saving of the hostname + read -p "Hostname doesn't seem correct. Do you still want to save it? (y/n)" force + if [[ "${force,,}" = "y" ]] + then + break + fi + done + export NAME_OF_MACHINE=$name_of_machine +} + +# Starting functions +background_checks +clear +logo +userinfo +clear +logo +diskpart +clear +logo +filesystem +clear +logo +timezone +clear +logo +keymap + +echo "Setting up mirrors for optimal download" +iso=$(curl -4 ifconfig.co/country-iso) +timedatectl set-ntp true +pacman -S --noconfirm archlinux-keyring #update keyrings to latest to prevent packages failing to install +pacman -S --noconfirm --needed pacman-contrib terminus-font +setfont ter-v18b +sed -i 's/^#ParallelDownloads/ParallelDownloads/' /etc/pacman.conf +pacman -S --noconfirm --needed reflector rsync grub +cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup +echo -ne " +------------------------------------------------------------------------- + Setting up $iso mirrors for faster downloads +------------------------------------------------------------------------- +" +reflector -a 48 -c $iso -f 5 -l 20 --sort rate --save /etc/pacman.d/mirrorlist +if [ ! -d "/mnt" ]; then + mkdir /mnt +fi +echo -ne " +------------------------------------------------------------------------- + Installing Prerequisites +------------------------------------------------------------------------- +" +pacman -S --noconfirm --needed gptfdisk btrfs-progs glibc +echo -ne " +------------------------------------------------------------------------- + Formating Disk +------------------------------------------------------------------------- +" +umount -A --recursive /mnt # make sure everything is unmounted before we start +# disk prep +sgdisk -Z ${DISK} # zap all on disk +sgdisk -a 2048 -o ${DISK} # new gpt disk 2048 alignment + +# create partitions +sgdisk -n 1::+1M --typecode=1:ef02 --change-name=1:'BIOSBOOT' ${DISK} # partition 1 (BIOS Boot Partition) +sgdisk -n 2::+300M --typecode=2:ef00 --change-name=2:'EFIBOOT' ${DISK} # partition 2 (UEFI Boot Partition) +sgdisk -n 3::-0 --typecode=3:8300 --change-name=3:'ROOT' ${DISK} # partition 3 (Root), default start, remaining +if [[ ! -d "/sys/firmware/efi" ]]; then # Checking for bios system + sgdisk -A 1:set:2 ${DISK} +fi +partprobe ${DISK} # reread partition table to ensure it is correct + +# make filesystems +echo -ne " +------------------------------------------------------------------------- + Creating Filesystems +------------------------------------------------------------------------- +" +# @description Creates the btrfs subvolumes. +createsubvolumes () { + btrfs subvolume create /mnt/@ + btrfs subvolume create /mnt/@home + btrfs subvolume create /mnt/@var + btrfs subvolume create /mnt/@tmp + btrfs subvolume create /mnt/@.snapshots +} + +# @description Mount all btrfs subvolumes after root has been mounted. +mountallsubvol () { + mount -o ${MOUNT_OPTIONS},subvol=@home ${partition3} /mnt/home + mount -o ${MOUNT_OPTIONS},subvol=@tmp ${partition3} /mnt/tmp + mount -o ${MOUNT_OPTIONS},subvol=@var ${partition3} /mnt/var + mount -o ${MOUNT_OPTIONS},subvol=@.snapshots ${partition3} /mnt/.snapshots +} + +# @description BTRFS subvolulme creation and mounting. +subvolumesetup () { +# create nonroot subvolumes + createsubvolumes +# unmount root to remount with subvolume + umount /mnt +# mount @ subvolume + mount -o ${MOUNT_OPTIONS},subvol=@ ${partition3} /mnt +# make directories home, .snapshots, var, tmp + mkdir -p /mnt/{home,var,tmp,.snapshots} +# mount subvolumes + mountallsubvol +} + +if [[ "${DISK}" =~ "nvme" ]]; then + partition2=${DISK}p2 + partition3=${DISK}p3 +else + partition2=${DISK}2 + partition3=${DISK}3 +fi + +if [[ "${FS}" == "btrfs" ]]; then + mkfs.vfat -F32 -n "EFIBOOT" ${partition2} + mkfs.btrfs -L ROOT ${partition3} -f + mount -t btrfs ${partition3} /mnt + subvolumesetup +elif [[ "${FS}" == "ext4" ]]; then + mkfs.vfat -F32 -n "EFIBOOT" ${partition2} + mkfs.ext4 -L ROOT ${partition3} + mount -t ext4 ${partition3} /mnt +elif [[ "${FS}" == "luks" ]]; then + mkfs.vfat -F32 -n "EFIBOOT" ${partition2} +# enter luks password to cryptsetup and format root partition + echo -n "${LUKS_PASSWORD}" | cryptsetup -y -v luksFormat ${partition3} - +# open luks container and ROOT will be place holder + echo -n "${LUKS_PASSWORD}" | cryptsetup open ${partition3} ROOT - +# now format that container + mkfs.btrfs -L ROOT ${partition3} +# create subvolumes for btrfs + mount -t btrfs ${partition3} /mnt + subvolumesetup +fi + +sync +if ! mountpoint -q /mnt; then + echo "ERROR! Failed to mount ${partition3} to /mnt after multiple attempts." + exit 1 +fi +mkdir -p /mnt/boot/efi +mount -t vfat -L EFIBOOT /mnt/boot/ + +if ! grep -qs '/mnt' /proc/mounts; then + echo "Drive is not mounted can not continue" + echo "Rebooting in 3 Seconds ..." && sleep 1 + echo "Rebooting in 2 Seconds ..." && sleep 1 + echo "Rebooting in 1 Second ..." && sleep 1 + reboot now +fi +echo -ne " +------------------------------------------------------------------------- + Arch Install on Main Drive +------------------------------------------------------------------------- +" +if [[ ! -d "/sys/firmware/efi" ]]; then + pacstrap /mnt base base-devel linux-lts linux-firmware --noconfirm --needed +else + pacstrap /mnt base base-devel linux-lts linux-firmware efibootmgr --noconfirm --needed +fi +echo "keyserver hkp://keyserver.ubuntu.com" >> /mnt/etc/pacman.d/gnupg/gpg.conf +cp /etc/pacman.d/mirrorlist /mnt/etc/pacman.d/mirrorlist + +genfstab -L /mnt >> /mnt/etc/fstab +echo " + Generated /etc/fstab: +" +cat /mnt/etc/fstab +echo -ne " +------------------------------------------------------------------------- + GRUB BIOS Bootloader Install & Check +------------------------------------------------------------------------- +" +if [[ ! -d "/sys/firmware/efi" ]]; then + grub-install --boot-directory=/mnt/boot ${DISK} +fi +echo -ne " +------------------------------------------------------------------------- + Checking for low memory systems <8G +------------------------------------------------------------------------- +" +TOTAL_MEM=$(cat /proc/meminfo | grep -i 'memtotal' | grep -o '[[:digit:]]*') +if [[ $TOTAL_MEM -lt 8000000 ]]; then + # Put swap into the actual system, not into RAM disk, otherwise there is no point in it, it'll cache RAM into RAM. So, /mnt/ everything. + mkdir -p /mnt/opt/swap # make a dir that we can apply NOCOW to to make it btrfs-friendly. + if findmnt -n -o FSTYPE /mnt | grep -q btrfs; then + chattr +C /mnt/opt/swap # apply NOCOW, btrfs needs that. + fi + dd if=/dev/zero of=/mnt/opt/swap/swapfile bs=1M count=2048 status=progress + chmod 600 /mnt/opt/swap/swapfile # set permissions. + chown root /mnt/opt/swap/swapfile + mkswap /mnt/opt/swap/swapfile + swapon /mnt/opt/swap/swapfile + # The line below is written to /mnt/ but doesn't contain /mnt/, since it's just / for the system itself. + echo "/opt/swap/swapfile none swap sw 0 0" >> /mnt/etc/fstab # Add swap to fstab, so it KEEPS working after installation. +fi + +gpu_type=$(lspci | grep -E "VGA|3D|Display") + +arch-chroot /mnt /bin/bash < /etc/hostname + +if [[ ${FS} == "luks" ]]; then +# Making sure to edit mkinitcpio conf if luks is selected +# add encrypt in mkinitcpio.conf before filesystems in hooks + sed -i 's/filesystems/encrypt filesystems/g' /etc/mkinitcpio.conf +# making mkinitcpio with linux kernel + mkinitcpio -p linux-lts +fi + +echo -ne " +------------------------------------------------------------------------- + β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β• +β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘ +β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ +β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β• +------------------------------------------------------------------------- + Automated Arch Linux Installer +------------------------------------------------------------------------- + +Final Setup and Configurations +GRUB EFI Bootloader Install & Check +" + +if [[ -d "/sys/firmware/efi" ]]; then + grub-install --efi-directory=/boot ${DISK} +fi + +echo -ne " +------------------------------------------------------------------------- + Creating (and Theming) Grub Boot Menu +------------------------------------------------------------------------- +" +# set kernel parameter for decrypting the drive +if [[ "${FS}" == "luks" ]]; then +sed -i "s%GRUB_CMDLINE_LINUX_DEFAULT=\"%GRUB_CMDLINE_LINUX_DEFAULT=\"cryptdevice=UUID=${ENCRYPTED_PARTITION_UUID}:ROOT root=/dev/mapper/ROOT %g" /etc/default/grub +fi +# set kernel parameter for adding splash screen +sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& splash /' /etc/default/grub + +echo -e "Installing CyberRe Grub theme..." +THEME_DIR="/boot/grub/themes/CyberRe" +echo -e "Creating the theme directory..." +mkdir -p "${THEME_DIR}" + +# Clone the theme +cd "${THEME_DIR}" || exit +git init +git remote add -f origin https://github.com/ChrisTitusTech/Top-5-Bootloader-Themes.git +git config core.sparseCheckout true +echo "themes/CyberRe/*" >> .git/info/sparse-checkout +git pull origin main +mv themes/CyberRe/* . +rm -rf themes +rm -rf .git + +echo "CyberRe theme has been cloned to ${THEME_DIR}" +echo -e "Backing up Grub config..." +cp -an /etc/default/grub /etc/default/grub.bak +echo -e "Setting the theme as the default..." +grep "GRUB_THEME=" /etc/default/grub 2>&1 >/dev/null && sed -i '/GRUB_THEME=/d' /etc/default/grub +echo "GRUB_THEME=\"${THEME_DIR}/theme.txt\"" >> /etc/default/grub +echo -e "Updating grub..." +grub-mkconfig -o /boot/grub/grub.cfg +echo -e "All set!" + +echo -ne " +------------------------------------------------------------------------- + Enabling Essential Services +------------------------------------------------------------------------- +" +ntpd -qg +systemctl enable ntpd.service +echo " NTP enabled" +systemctl disable dhcpcd.service +echo " DHCP disabled" +systemctl stop dhcpcd.service +echo " DHCP stopped" +systemctl enable NetworkManager.service +echo " NetworkManager enabled" + +echo -ne " +------------------------------------------------------------------------- + Cleaning +------------------------------------------------------------------------- +" +# Remove no password sudo rights +sed -i 's/^%wheel ALL=(ALL) NOPASSWD: ALL/# %wheel ALL=(ALL) NOPASSWD: ALL/' /etc/sudoers +sed -i 's/^%wheel ALL=(ALL:ALL) NOPASSWD: ALL/# %wheel ALL=(ALL:ALL) NOPASSWD: ALL/' /etc/sudoers +# Add sudo rights +sed -i 's/^# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/' /etc/sudoers +sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers + +# Replace in the same state +cd "$(pwd)" || exit +EOF \ No newline at end of file diff --git a/src/commands/system-setup/arch/yay-setup.sh b/src/commands/system-setup/arch/yay-setup.sh old mode 100644 new mode 100755 index f29ecc3f..b248ef51 --- a/src/commands/system-setup/arch/yay-setup.sh +++ b/src/commands/system-setup/arch/yay-setup.sh @@ -7,8 +7,8 @@ installDepend() { pacman) if ! command_exists yay; then echo "Installing yay as AUR helper..." - sudo "$PACKAGER" -S --needed --noconfirm base-devel - cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R "$USER": ./yay-git + $ESCALATION_TOOL "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R "$USER": ./yay-git cd yay-git && makepkg --noconfirm -si echo "Yay installed" else @@ -22,4 +22,5 @@ installDepend() { } checkEnv -installDepend \ No newline at end of file +checkEscalationTool +installDepend diff --git a/src/commands/system-setup/system-update.sh b/src/commands/system-setup/system-update.sh index 1277143a..eef21bb1 100755 --- a/src/commands/system-setup/system-update.sh +++ b/src/commands/system-setup/system-update.sh @@ -7,8 +7,8 @@ fastUpdate() { pacman) if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo ${PACKAGER} -S --needed --noconfirm base-devel || { echo -e "${RED}Failed to install base-devel${RC}"; exit 1; } - cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R ${USER}:${USER} ./yay-git + $ESCALATION_TOOL ${PACKAGER} -S --needed --noconfirm base-devel || { echo -e "${RED}Failed to install base-devel${RC}"; exit 1; } + cd /opt && $ESCALATION_TOOL git clone https://aur.archlinux.org/yay-git.git && $ESCALATION_TOOL chown -R ${USER}:${USER} ./yay-git cd yay-git && makepkg --noconfirm -si || { echo -e "${RED}Failed to install yay${RC}"; exit 1; } else echo "Aur helper already installed" @@ -21,9 +21,9 @@ fastUpdate() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - ${AUR_HELPER} -S --needed --noconfirm rate-mirrors-bin + $AUR_HELPER -S --needed --noconfirm rate-mirrors-bin if [ -s /etc/pacman.d/mirrorlist ]; then - sudo cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak + $ESCALATION_TOOL cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak fi # If for some reason DTYPE is still unknown use always arch so the rate-mirrors does not fail @@ -31,33 +31,33 @@ fastUpdate() { if [ "${DTYPE}" = "unknown" ]; then dtype_local="arch" fi - sudo rate-mirrors --top-mirrors-number-to-retest=5 --disable-comments --save /etc/pacman.d/mirrorlist --allow-root ${dtype_local} + $ESCALATION_TOOL rate-mirrors --top-mirrors-number-to-retest=5 --disable-comments --save /etc/pacman.d/mirrorlist --allow-root ${dtype_local} ;; apt-get|nala) - sudo apt-get update + $ESCALATION_TOOL apt-get update if ! command_exists nala; then - sudo apt-get install -y nala || { echo -e "${YELLOW}Falling back to apt-get${RC}"; PACKAGER="apt-get"; } + $ESCALATION_TOOL apt-get install -y nala || { echo -e "${YELLOW}Falling back to apt-get${RC}"; PACKAGER="apt-get"; } fi if [ "${PACKAGER}" = "nala" ]; then - sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak - sudo nala update + $ESCALATION_TOOL cp /etc/apt/sources.list /etc/apt/sources.list.bak + $ESCALATION_TOOL nala update PACKAGER="nala" fi - sudo ${PACKAGER} upgrade -y + $ESCALATION_TOOL ${PACKAGER} upgrade -y ;; dnf) - sudo ${PACKAGER} update -y + $ESCALATION_TOOL ${PACKAGER} update -y ;; zypper) - sudo ${PACKAGER} ref - sudo ${PACKAGER} --non-interactive dup + $ESCALATION_TOOL ${PACKAGER} ref + $ESCALATION_TOOL ${PACKAGER} --non-interactive dup ;; yum) - sudo ${PACKAGER} update -y - sudo ${PACKAGER} upgrade -y + $ESCALATION_TOOL ${PACKAGER} update -y + $ESCALATION_TOOL ${PACKAGER} upgrade -y ;; xbps-install) - sudo ${PACKAGER} -Syu + $ESCALATION_TOOL ${PACKAGER} -Syu ;; *) echo -e "${RED}Unsupported package manager: $PACKAGER${RC}" @@ -70,23 +70,23 @@ updateSystem() { echo -e "${GREEN}Updating system${RC}" case ${PACKAGER} in nala|apt-get) - sudo "${PACKAGER}" update -y - sudo "${PACKAGER}" upgrade -y + $ESCALATION_TOOL "${PACKAGER}" update -y + $ESCALATION_TOOL "${PACKAGER}" upgrade -y ;; yum|dnf) - sudo "${PACKAGER}" update -y - sudo "${PACKAGER}" upgrade -y + $ESCALATION_TOOL "${PACKAGER}" update -y + $ESCALATION_TOOL "${PACKAGER}" upgrade -y ;; pacman) - sudo "${PACKAGER}" -Sy --noconfirm --needed archlinux-keyring - sudo "${PACKAGER}" -Su --noconfirm + $ESCALATION_TOOL "${PACKAGER}" -Sy --noconfirm --needed archlinux-keyring + $ESCALATION_TOOL "${PACKAGER}" -Su --noconfirm ;; zypper) - sudo ${PACKAGER} ref - sudo ${PACKAGER} --non-interactive dup + $ESCALATION_TOOL ${PACKAGER} ref + $ESCALATION_TOOL ${PACKAGER} --non-interactive dup ;; xbps-install) - sudo ${PACKAGER} -Syu + $ESCALATION_TOOL ${PACKAGER} -Syu ;; *) echo -e "${RED}Unsupported package manager: ${PACKAGER}${RC}" @@ -102,6 +102,7 @@ updateFlatpaks() { } checkEnv +checkEscalationTool fastUpdate updateSystem updateFlatpaks diff --git a/src/commands/system-setup/tab_data.toml b/src/commands/system-setup/tab_data.toml index 53ec55cd..7551e884 100644 --- a/src/commands/system-setup/tab_data.toml +++ b/src/commands/system-setup/tab_data.toml @@ -9,13 +9,17 @@ data = "command_exists" values = ["pacman"] [[data.entries]] -name = "Yay AUR Helper" -script = "arch/yay-setup.sh" +name = "Arch Server Setup" +script = "arch/server-setup.sh" [[data.entries]] name = "Paru AUR Helper" script = "arch/paru-setup.sh" +[[data.entries]] +name = "Yay AUR Helper" +script = "arch/yay-setup.sh" + [[data]] name = "Full System Update" script = "system-update.sh" diff --git a/src/commands/utils/numlock.sh b/src/commands/utils/numlock.sh new file mode 100755 index 00000000..b1ac782a --- /dev/null +++ b/src/commands/utils/numlock.sh @@ -0,0 +1,60 @@ +#!/bin/sh -e + +# setleds can be used in all distros +# This method works by calling a script using systemd service + +# Create a script to toggle numlock +create_file() { + echo "Creating script..." + sudo tee "/usr/local/bin/numlock" >/dev/null <<'EOF' +#!/bin/bash + +for tty in /dev/tty{1..6} +do + /usr/bin/setleds -D +num < "$tty"; +done +EOF + + sudo chmod +x /usr/local/bin/numlock +} + +# Create a systemd service to run the script on boot +create_service() { + echo "Creating service..." + sudo tee "/etc/systemd/system/numlock.service" >/dev/null <<'EOF' +[Unit] +Description=numlock + +[Service] +ExecStart=/usr/local/bin/numlock +StandardInput=tty +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target +EOF +} + +main() { + # Check if the script and service files exists + if [ ! -f "/usr/local/bin/numlock" ]; then + create_file + fi + + if [ ! -f "/etc/systemd/system/numlock.service" ]; then + create_service + fi + + printf "Do you want to enable Numlock on boot? (y/n): " + read -r confirm + if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then + sudo systemctl enable numlock.service --quiet + echo "Numlock will be enabled on boot" + else + sudo systemctl disable numlock.service --quiet + echo "Numlock will not be enabled on boot" + + fi +} + +main diff --git a/src/commands/utils/tab_data.toml b/src/commands/utils/tab_data.toml index 41490334..2e5e1283 100644 --- a/src/commands/utils/tab_data.toml +++ b/src/commands/utils/tab_data.toml @@ -8,6 +8,10 @@ script = "wifi-control.sh" name = "Bluetooth Manager" script = "bluetooth-control.sh" +[[data]] +name = "Numlock on Startup" +script = "numlock.sh" + [[data]] name = "Monitor Control"