mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
221 lines
6.4 KiB
Bash
Executable File
221 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
INSTALL_BIN_DIR=${INSTALL_BIN_DIR:-/usr/local/bin}
|
|
INSTALL_SYSTEMD_DIR=${INSTALL_SYSTEMD_DIR:-/etc/systemd/system}
|
|
UNCLOUD_GITHUB_URL="https://github.com/psviderski/uncloud"
|
|
UNCLOUD_VERSION=${UNCLOUD_VERSION:-latest}
|
|
UNCLOUD_USER="uncloud"
|
|
# Add the specified Linux user to group $UNCLOUD_USER to allow the user to run uncloud commands without sudo.
|
|
UNCLOUD_GROUP_ADD_USER=${UNCLOUD_GROUP_ADD_USER:-}
|
|
UNCLOUD_DATA_DIR=${UNCLOUD_DATA_DIR:-/var/lib/uncloud}
|
|
|
|
log() {
|
|
echo -e "\033[1;32m$1\033[0m"
|
|
}
|
|
|
|
error() {
|
|
echo -e "\033[1;31mERROR: $1\033[0m" >&2
|
|
exit 1
|
|
}
|
|
|
|
command_exists() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
verify_system() {
|
|
if [[ "$(uname -s)" != "Linux" ]]; then
|
|
error "Uncloud machine must be a Linux system. Your system ($(uname -s)) is not supported."
|
|
fi
|
|
|
|
local arch
|
|
arch=$(uname -m)
|
|
if [[ "$arch" != "x86_64" && "$arch" != "aarch64" ]]; then
|
|
error "Uncloud machine must have amd64 (x86_64) or arm64 (aarch64) architecture. \
|
|
Your system architecture ($arch) is not supported."
|
|
fi
|
|
|
|
if [[ ! -d /run/systemd/system ]]; then
|
|
error "Cannot find systemd to use as a service manager for the Uncloud machine daemon. \
|
|
Uncloud supports only systemd-based Linux systems for now."
|
|
fi
|
|
}
|
|
|
|
install_docker() {
|
|
if command_exists docker; then
|
|
log "✓ Docker is already installed."
|
|
docker version
|
|
return
|
|
fi
|
|
|
|
log "⏳ Installing Docker..."
|
|
curl -fsSL https://get.docker.com | sh
|
|
log "✓ Docker installed successfully."
|
|
}
|
|
|
|
create_uncloud_user_and_group() {
|
|
if id "${UNCLOUD_USER}" &> /dev/null; then
|
|
log "✓ Linux user '${UNCLOUD_USER}' already exists."
|
|
else
|
|
# In addition to creating the user, create a group with the same name as the user.
|
|
if ! useradd --system --home-dir /nonexistent --shell /usr/sbin/nologin --user-group "${UNCLOUD_USER}"; then
|
|
error "Failed to create Linux user '${UNCLOUD_USER}'."
|
|
fi
|
|
log "✓ Linux user and group '${UNCLOUD_USER}' created."
|
|
fi
|
|
|
|
if [ -n "${UNCLOUD_GROUP_ADD_USER}" ]; then
|
|
if ! gpasswd --add "${UNCLOUD_GROUP_ADD_USER}" "${UNCLOUD_USER}" > /dev/null; then
|
|
error "Failed to add user '${UNCLOUD_GROUP_ADD_USER}' to group '${UNCLOUD_USER}'."
|
|
fi
|
|
log "✓ Linux user '${UNCLOUD_GROUP_ADD_USER}' added to group '${UNCLOUD_USER}'."
|
|
fi
|
|
}
|
|
|
|
install_uncloud_binaries() {
|
|
local arch
|
|
local file_arch
|
|
|
|
arch=$(uname -m)
|
|
case $arch in
|
|
x86_64)
|
|
file_arch="amd64"
|
|
;;
|
|
aarch64)
|
|
file_arch="arm64"
|
|
;;
|
|
*)
|
|
error "Unsupported architecture: ${arch}"
|
|
;;
|
|
esac
|
|
|
|
local uncloudd_install_path="${INSTALL_BIN_DIR}/uncloudd"
|
|
if [ -f "${uncloudd_install_path}" ]; then
|
|
# TODO: Check the version of the installed uncloudd binary and update if there is a newer stable version.
|
|
log "✓ uncloudd binary is already installed."
|
|
return
|
|
fi
|
|
|
|
log "⏳ Installing Uncloud binaries..."
|
|
|
|
# Create a temporary directory for downloads.
|
|
local tmp_dir
|
|
tmp_dir=$(mktemp -d)
|
|
# Ensure the temporary directory is deleted on script exit.
|
|
# shellcheck disable=SC2064
|
|
trap "rm -rf '$tmp_dir'" EXIT
|
|
|
|
local uncloudd_url
|
|
if [ "${UNCLOUD_VERSION}" == "latest" ]; then
|
|
uncloudd_url="${UNCLOUD_GITHUB_URL}/releases/latest/download/uncloudd_linux_${file_arch}.gz"
|
|
else
|
|
uncloudd_url="${UNCLOUD_GITHUB_URL}/releases/download/${UNCLOUD_VERSION}/uncloudd_linux_${file_arch}.gz"
|
|
fi
|
|
local uncloudd_download_path="${tmp_dir}/uncloudd.gz"
|
|
|
|
log "⏳ Downloading uncloudd binary: ${uncloudd_url}"
|
|
if ! curl -fsSL -o "${uncloudd_download_path}" "${uncloudd_url}"; then
|
|
error "Failed to download uncloudd binary."
|
|
fi
|
|
gzip -d "${uncloudd_download_path}"
|
|
if ! install "${uncloudd_download_path%.gz}" "${uncloudd_install_path}"; then
|
|
error "Failed to install uncloud binary to ${uncloudd_install_path}"
|
|
fi
|
|
log "✓ uncloudd binary installed: ${uncloudd_install_path}"
|
|
|
|
# TODO: install uncloud CLI binary and create a uc alias.
|
|
}
|
|
|
|
install_uncloud_systemd() {
|
|
local uncloud_service_path="${INSTALL_SYSTEMD_DIR}/uncloud.service"
|
|
cat > "${uncloud_service_path}" << EOF
|
|
[Unit]
|
|
Description=Uncloud machine daemon
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=notify
|
|
ExecStart=${INSTALL_BIN_DIR}/uncloudd
|
|
TimeoutStartSec=15
|
|
Restart=always
|
|
RestartSec=2
|
|
|
|
# Hardening options.
|
|
NoNewPrivileges=true
|
|
ProtectSystem=full
|
|
ProtectControlGroups=true
|
|
ProtectHome=true
|
|
ProtectKernelTunables=true
|
|
PrivateTmp=true
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
|
|
RestrictNamespaces=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
log "✓ Systemd unit file created: ${uncloud_service_path}"
|
|
|
|
# Reload systemd to recognize the new or updated unit file.
|
|
systemctl daemon-reload
|
|
systemctl enable uncloud.service
|
|
|
|
log "⏳ Starting Uncloud machine daemon (uncloud.service)..."
|
|
systemctl restart uncloud.service
|
|
log "✓ Uncloud machine daemon started."
|
|
}
|
|
|
|
install_corrosion() {
|
|
# TODO: build corrosion binaries and release them on GitHub.
|
|
# For now, assume /usr/local/bin/uncloud-corrosion exists.
|
|
return
|
|
}
|
|
|
|
install_corrosion_systemd() {
|
|
local corrosion_service_path="${INSTALL_SYSTEMD_DIR}/uncloud-corrosion.service"
|
|
cat > "${corrosion_service_path}" << EOF
|
|
[Unit]
|
|
Description=Uncloud gossip-based distributed store
|
|
PartOf=uncloud.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${INSTALL_BIN_DIR}/uncloud-corrosion agent -c ${UNCLOUD_DATA_DIR}/corrosion/config.toml
|
|
ExecReload=${INSTALL_BIN_DIR}/uncloud-corrosion reload -c ${UNCLOUD_DATA_DIR}/corrosion/config.toml
|
|
Restart=always
|
|
RestartSec=2
|
|
User=${UNCLOUD_USER}
|
|
Group=${UNCLOUD_USER}
|
|
|
|
# Hardening options.
|
|
ProtectSystem=full
|
|
PrivateTmp=true
|
|
NoNewPrivileges=true
|
|
ProtectHome=true
|
|
ProtectControlGroups=true
|
|
ProtectKernelTunables=true
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
EOF
|
|
log "✓ Systemd unit file created: ${corrosion_service_path}"
|
|
|
|
# Reload systemd to recognize the new unit file
|
|
systemctl daemon-reload
|
|
}
|
|
|
|
log "⏳ Running Uncloud install script..."
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
|
error "Please run the install script with sudo or as root."
|
|
fi
|
|
|
|
verify_system
|
|
install_docker
|
|
create_uncloud_user_and_group
|
|
install_uncloud_binaries
|
|
install_uncloud_systemd
|
|
install_corrosion
|
|
install_corrosion_systemd
|
|
|
|
log "✓ Uncloud installed on the machine successfully! 🎉"
|