2024-10-03 14:40:36 -04:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
cleanup() {
|
2025-02-01 16:44:02 +00:00
|
|
|
rm -rf "$TMP" &
|
2024-10-03 14:40:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
available() {
|
|
|
|
|
command -v "$1" >/dev/null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nvidia_lshw() {
|
|
|
|
|
lshw -c display -numeric -disable network | grep -q 'vendor: .* \[10DE\]'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
amd_lshw() {
|
|
|
|
|
lshw -c display -numeric -disable network | grep -q 'vendor: .* \[1002\]'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
download() {
|
2025-01-31 16:10:42 +00:00
|
|
|
if $local_install; then
|
|
|
|
|
cp "$1" "$2"
|
|
|
|
|
else
|
|
|
|
|
curl --globoff --location --proto-default https -f -o "$2" \
|
2025-03-03 17:23:25 +00:00
|
|
|
--remote-time --retry 10 --retry-max-time 10 -s -S "$1"
|
2025-01-31 16:10:42 +00:00
|
|
|
fi
|
2025-03-03 17:23:25 +00:00
|
|
|
|
|
|
|
|
echo -n "█"
|
2024-10-03 14:40:36 -04:00
|
|
|
}
|
|
|
|
|
|
2025-01-23 15:24:15 +00:00
|
|
|
dnf_install() {
|
2025-02-24 23:19:19 +00:00
|
|
|
$sudo dnf install -y "$1"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dnf_install_podman() {
|
2025-01-23 15:24:15 +00:00
|
|
|
if ! available podman; then
|
2025-02-24 23:19:19 +00:00
|
|
|
dnf_install podman || true
|
2025-01-23 15:24:15 +00:00
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-16 17:20:06 +00:00
|
|
|
apt_install() {
|
|
|
|
|
apt install -y "$1"
|
2025-01-23 13:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
2025-02-16 17:20:06 +00:00
|
|
|
apt_update_install() {
|
2025-01-23 15:24:15 +00:00
|
|
|
if ! available podman; then
|
2025-02-16 17:20:06 +00:00
|
|
|
$sudo apt update || true
|
2025-01-23 15:24:15 +00:00
|
|
|
|
|
|
|
|
# only install docker if podman can't be
|
2025-02-16 17:20:06 +00:00
|
|
|
if ! $sudo apt_install podman; then
|
2025-01-23 15:24:15 +00:00
|
|
|
if ! available docker; then
|
2025-02-16 17:20:06 +00:00
|
|
|
$sudo apt_install docker || true
|
2025-01-23 15:24:15 +00:00
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-31 16:10:42 +00:00
|
|
|
install_mac_dependencies() {
|
|
|
|
|
if [ "$EUID" -eq 0 ]; then
|
|
|
|
|
echo "This script is intended to run as non-root on macOS"
|
|
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! available "brew"; then
|
|
|
|
|
echo "RamaLama requires brew to complete installation. Install brew and add the"
|
|
|
|
|
echo "directory containing brew to the PATH before continuing to install RamaLama"
|
|
|
|
|
|
|
|
|
|
return 2
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
brew install llama.cpp
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-03 14:40:36 -04:00
|
|
|
check_platform() {
|
2025-01-31 16:10:42 +00:00
|
|
|
if $local_install; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2024-10-03 14:40:36 -04:00
|
|
|
|
2025-01-31 16:10:42 +00:00
|
|
|
if [ "$os" = "Darwin" ]; then
|
|
|
|
|
install_mac_dependencies
|
2024-10-03 14:40:36 -04:00
|
|
|
elif [ "$os" = "Linux" ]; then
|
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
2024-12-11 15:50:51 +00:00
|
|
|
if ! available sudo; then
|
|
|
|
|
error "This script is intended to run as root on Linux"
|
2025-01-31 16:10:42 +00:00
|
|
|
|
2024-12-11 15:50:51 +00:00
|
|
|
return 3
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
sudo="sudo"
|
2024-10-03 14:40:36 -04:00
|
|
|
fi
|
2025-01-23 13:46:00 +00:00
|
|
|
|
2025-01-23 15:24:15 +00:00
|
|
|
if available dnf && ! grep -q ostree= /proc/cmdline; then
|
2025-02-24 23:19:19 +00:00
|
|
|
dnf_install_podman
|
2025-02-16 17:20:06 +00:00
|
|
|
elif available apt; then
|
|
|
|
|
apt_update_install
|
2025-01-23 13:46:00 +00:00
|
|
|
fi
|
2024-10-03 14:40:36 -04:00
|
|
|
else
|
|
|
|
|
echo "This script is intended to run on Linux and macOS only"
|
2025-01-31 16:10:42 +00:00
|
|
|
|
2024-10-03 14:40:36 -04:00
|
|
|
return 4
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-03 17:23:25 +00:00
|
|
|
get_sysdir() {
|
|
|
|
|
local bindirs=("/opt/homebrew/bin" "/usr/local/bin" "/usr/bin")
|
|
|
|
|
local bindir
|
|
|
|
|
for bindir in "${bindirs[@]}"; do
|
|
|
|
|
if echo "$PATH" | grep -q "$bindir"; then
|
2025-02-10 13:56:53 +01:00
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
2025-03-03 17:23:25 +00:00
|
|
|
|
|
|
|
|
sysdir="$(dirname "$bindir")"
|
2025-02-10 13:56:53 +01:00
|
|
|
}
|
|
|
|
|
|
2024-10-03 14:40:36 -04:00
|
|
|
setup_ramalama() {
|
|
|
|
|
local binfile="ramalama"
|
|
|
|
|
local from_file="${binfile}"
|
|
|
|
|
local host="https://raw.githubusercontent.com"
|
|
|
|
|
local branch="${BRANCH:-s}"
|
|
|
|
|
local url="${host}/containers/ramalama/${branch}/bin/${from_file}"
|
2025-02-01 16:44:02 +00:00
|
|
|
local to_file="$TMP/${from_file}"
|
2025-03-03 17:23:25 +00:00
|
|
|
local sysdir
|
|
|
|
|
get_sysdir
|
|
|
|
|
|
2025-01-31 16:10:42 +00:00
|
|
|
if $local_install; then
|
|
|
|
|
url="bin/${from_file}"
|
2025-01-23 22:37:50 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
download "$url" "$to_file"
|
2025-03-03 17:23:25 +00:00
|
|
|
local max_jobs
|
|
|
|
|
max_jobs="$(getconf _NPROCESSORS_ONLN)"
|
2025-02-24 23:19:19 +00:00
|
|
|
install_ramalama_bin
|
|
|
|
|
install_ramalama_libs
|
2025-03-03 17:23:25 +00:00
|
|
|
install_ramalama_libexecs
|
|
|
|
|
echo
|
2025-02-24 23:19:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
install_ramalama_bin() {
|
2025-03-03 17:23:25 +00:00
|
|
|
$sudo install -m755 "$to_file" "$sysdir/bin/ramalama"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
install_dirs() {
|
|
|
|
|
local dir="$1"
|
|
|
|
|
$sudo install -m755 -d "$dir"
|
|
|
|
|
dir="$dir/ramalama"
|
|
|
|
|
$sudo install -m755 -d "$dir"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
download_install() {
|
|
|
|
|
local url_dir="$1"
|
|
|
|
|
local dir="$2"
|
|
|
|
|
local file="$3"
|
|
|
|
|
if $local_install; then
|
|
|
|
|
url="$url_dir/$file"
|
|
|
|
|
else
|
|
|
|
|
url="$host/containers/ramalama/$branch/$url_dir/$file"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
mkdir -p "$TMP/$dir"
|
|
|
|
|
download "$url" "$TMP/$dir/$file"
|
|
|
|
|
$sudo install -m755 "$TMP/$dir/$file" "$sysdir/$dir/$file"
|
2025-02-24 23:19:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
install_ramalama_libs() {
|
2025-03-10 22:49:04 +00:00
|
|
|
local sharedir="$sysdir/share/ramalama"
|
2025-03-03 17:23:25 +00:00
|
|
|
install_dirs "$sharedir"
|
|
|
|
|
local python_files=("cli.py" "config.py" "rag.py" "gguf_parser.py" \
|
|
|
|
|
"huggingface.py" "model.py" "model_factory.py" \
|
2025-02-28 14:21:26 +01:00
|
|
|
"model_store.py" "model_inspect.py" "ollama.py" \
|
|
|
|
|
"common.py" "__init__.py" "quadlet.py" "kube.py" \
|
|
|
|
|
"oci.py" "version.py" "shortnames.py" "toml_parser.py" \
|
|
|
|
|
"file.py" "http_client.py" "url.py" "annotations.py" \
|
2025-03-11 16:57:15 +00:00
|
|
|
"console.py" "go2jinja.py")
|
2025-03-03 17:23:25 +00:00
|
|
|
local job_count=0
|
|
|
|
|
local job_queue=()
|
2024-10-03 14:40:36 -04:00
|
|
|
for i in "${python_files[@]}"; do
|
2025-03-10 22:49:04 +00:00
|
|
|
download_install "ramalama" "share/ramalama/ramalama" "$i" &
|
2025-03-03 17:23:25 +00:00
|
|
|
job_queue+=($!)
|
|
|
|
|
((++job_count))
|
|
|
|
|
|
|
|
|
|
if ((job_count > max_jobs)); then
|
|
|
|
|
wait "${job_queue[0]}"
|
|
|
|
|
job_queue=("${job_queue[@]:1}")
|
|
|
|
|
((--job_count))
|
2025-01-31 16:10:42 +00:00
|
|
|
fi
|
2025-03-03 17:23:25 +00:00
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Wait for remaining jobs to finish
|
|
|
|
|
wait
|
2025-01-31 16:10:42 +00:00
|
|
|
|
2025-03-03 17:23:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
install_ramalama_libexecs() {
|
|
|
|
|
local python_files=("client" "serve" "run")
|
|
|
|
|
local libexecdir="$sysdir/libexec"
|
|
|
|
|
install_dirs "$libexecdir"
|
|
|
|
|
local job_count=0
|
|
|
|
|
local job_queue=()
|
|
|
|
|
for i in "${python_files[@]}"; do
|
|
|
|
|
download_install "libexec" "libexec" "ramalama-$i-core" &
|
|
|
|
|
job_queue+=($!)
|
|
|
|
|
((++job_count))
|
|
|
|
|
|
|
|
|
|
if ((job_count > max_jobs)); then
|
|
|
|
|
wait "${job_queue[0]}"
|
|
|
|
|
job_queue=("${job_queue[@]:1}")
|
|
|
|
|
((--job_count))
|
|
|
|
|
fi
|
2024-10-03 14:40:36 -04:00
|
|
|
done
|
2025-03-03 17:23:25 +00:00
|
|
|
|
|
|
|
|
# Wait for remaining jobs to finish
|
|
|
|
|
wait
|
2024-10-03 14:40:36 -04:00
|
|
|
}
|
|
|
|
|
|
2025-02-24 23:19:19 +00:00
|
|
|
parse_arguments() {
|
2025-01-31 16:10:42 +00:00
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
case "$1" in
|
|
|
|
|
-l)
|
|
|
|
|
local_install="true"
|
|
|
|
|
shift
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
break
|
|
|
|
|
esac
|
|
|
|
|
done
|
2025-02-24 23:19:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main() {
|
|
|
|
|
set -e -o pipefail
|
|
|
|
|
|
|
|
|
|
local local_install="false"
|
|
|
|
|
parse_arguments "$@"
|
2025-01-31 16:10:42 +00:00
|
|
|
|
2024-10-03 14:40:36 -04:00
|
|
|
local os
|
|
|
|
|
os="$(uname -s)"
|
2024-12-11 15:50:51 +00:00
|
|
|
local sudo=""
|
2024-10-03 14:40:36 -04:00
|
|
|
check_platform
|
2025-02-24 23:19:19 +00:00
|
|
|
if ! $local_install && [ -z "$BRANCH" ] && available dnf && \
|
|
|
|
|
dnf_install "python3-ramalama"; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2024-10-03 14:40:36 -04:00
|
|
|
|
2025-02-01 16:44:02 +00:00
|
|
|
TMP="$(mktemp -d)"
|
2024-10-03 14:40:36 -04:00
|
|
|
trap cleanup EXIT
|
|
|
|
|
|
2025-03-03 17:23:25 +00:00
|
|
|
setup_ramalama
|
2024-10-03 14:40:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main "$@"
|