Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(brew): Automatically install and maintain brew package list (#347) #348

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/brew/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The brew module installs [Homebrew / Linuxbrew](https://brew.sh/) on your system
- Sets up systemd services to automatically update Brew to the latest version.
- Sets up systemd services to automatically upgrade Brew packages.
- Sets up bash and fish completions for Brew.
- Installs specific Brew packages if specified in the `install` configuration.

## How it works

Expand Down Expand Up @@ -50,6 +51,7 @@ The brew module installs [Homebrew / Linuxbrew](https://brew.sh/) on your system
**Rest of the setup:**
- `brew-update` runs at the specified time to update Brew to the latest version
- `brew-upgrade` runs at the specified time to upgrade Brew packages
- `brew-packages-setup` installs the specified packages if listed in the `install` configuration

## Development
Setting `DEBUG=true` inside `brew.sh` will enable additional output for debugging purposes during development.
Expand Down
65 changes: 65 additions & 0 deletions modules/brew/brew.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ if [[ -z "${BREW_ANALYTICS}" || "${BREW_ANALYTICS}" == "null" ]]; then
BREW_ANALYTICS=true
fi

INSTALL_PACKAGES=$(echo "${1}" | yq -I=0 ".install[]")
if [[ -z "${INSTALL_PACKAGES}" || "${INSTALL_PACKAGES}" == "null" ]]; then
INSTALL_PACKAGES=()
fi

# Create necessary directories
mkdir -p /var/home
mkdir -p /var/roothome
Expand Down Expand Up @@ -277,4 +282,64 @@ if [[ "${BREW_ANALYTICS}" == false ]]; then
fi
fi

# Create directory for brew configuration
mkdir -p /usr/share/bluebuild/brew

# Create repo-info.yml file with install packages if specified
if [[ -n "${INSTALL_PACKAGES}" ]]; then
echo "install:" > /usr/share/bluebuild/brew/repo-info.yml
echo "${INSTALL_PACKAGES}" | sed 's/^/ - /' >> /usr/share/bluebuild/brew/repo-info.yml
echo "The following Brew packages will be installed when the system is live:"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
echo "The following Brew packages will be installed when the system is live:"
echo "The following Brew packages will be installed when system is booted:"

echo "${INSTALL_PACKAGES}" | sed 's/^/ - /'

# Write brew-packages-setup script
cat > /usr/bin/brew-packages-setup <<EOF
Comment on lines +295 to +296
Copy link
Member

Choose a reason for hiding this comment

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

This should be just a file in the module's directory that is cp'd in place. Having it inline doesn't work with syntax highlighting and shellcheck.

#!/usr/bin/env bash

set -euo pipefail

# Source the Brew environment
eval "\$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

# Install the Brew packages
if [[ -n "\${INSTALL_PACKAGES[@]}" ]]; then
echo "Installing Brew packages..."
for package in "\${INSTALL_PACKAGES[@]}"; do
if ! brew list --formula "\$package" &> /dev/null; then
brew install "\$package"
else
fiftydinar marked this conversation as resolved.
Show resolved Hide resolved
echo "Package \$package is already installed."
fi
done
else
echo "No Brew packages specified for installation."
fi
EOF

chmod +x /usr/bin/brew-packages-setup

# Write brew-packages-setup service
cat > /usr/lib/systemd/system/brew-packages-setup.service <<EOF
[Unit]
Description=Setup Brew Packages
After=brew-setup.service
Requires=brew-setup.service
ConditionPathExists=!/var/lib/brew-packages-setup.stamp
Copy link
Collaborator

@fiftydinar fiftydinar Oct 16, 2024

Choose a reason for hiding this comment

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

This condition makes this execute only once.

It should execute every boot, to install packages from updated install list over time. If there are no packages, it will just say Package \$package is already installed.

To make logs more sane in this scenario (when there are no new packages to install),
instead of printing this echo for every package, it should print once: Installed packages are up-to-date with install list, no changes need to be done


[Service]
Type=oneshot
ExecStart=/usr/bin/brew-packages-setup
ExecStartPost=/usr/bin/touch /var/lib/brew-packages-setup.stamp
User=1000

[Install]
WantedBy=multi-user.target
EOF

# Enable the brew-packages-setup service
systemctl enable brew-packages-setup.service
else
echo "No Brew packages specified for installation."
fi

echo "Brew setup completed"
5 changes: 4 additions & 1 deletion modules/brew/brew.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ model BrewModule {
* The Homebrew project uses analytics to anonymously collect the information about Brew usage & your system in order to improve the experience of Brew users.
*/
"brew-analytics"?: boolean = true;
}

/** List of Brew packages to install. */
"install"?: Array<string>;
}