fpm
fpm copied to clipboard
Enable packaging of curl|bash and other wild stuff.
For #1853
References: https://gist.github.com/jordansissel/0e0fc22344a17eadd1a3b9a1bbb7ed60
Attempts that worked out well enough:
- ✅ rustup
- ✅ sdkman
- ✅ sdkman's
sdk install java
I picked Podman to start with because that's what I have right now.
Here's converting rustup's curl|bash to an rpm.
The rustup docs say the following:
Run the following in your terminal, then follow the onscreen instructions.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- I'll run it with
|sh -s -- -yto run the installer non-interactively (accepting "yes" to all questions) - To make it faster/smaller, we'll also use rustup-init's flag,
--profile=minimal - Add
--no-modify-pathso the installer doesn't mess with any .bashrc/.profile - Set a custom install path
RUSTUP_HOME=/usr/local/rustup
% fpm --verbose -f -s curlbash -t rpm -n rustup \
--depends gcc \
--curlbash-setup "apt-get update && apt-get install -y curl" \
"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --profile=minimal --no-modify-path -y"
... [ some time passes ] ...
Created package {:path=>"rustup-1.0-1.x86_64.rpm"}
% rpm -qlp rustup-1.0-1.x86_64.rpm| less
...
/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo
/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-gdb
/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-gdbgui
/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-lldb
/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc
...
🫡 We've got an rpm. Let's try it.
# Start with a fresh fedora 36 container
% podman run -v "$PWD/rustup-1.0-1.x86_64.rpm:/rustup-1.0-1.x86_64.rpm" -it fedora:36
# Install the rpm.
[root@7bcb72eab5fa /]# dnf install rustup-1.0-1.x86_64.rpm
...
Dependencies resolved.
==========================================================================================================
Package Architecture Version Repository Size
==========================================================================================================
Installing:
rustup x86_64 1.0-1 @commandline 146 M
Installing dependencies:
...
gcc x86_64 12.2.1-2.fc36 updates 33 M
glibc-devel x86_64 2.35-20.fc36 updates 70 k
glibc-headers-x86 noarch 2.35-20.fc36 updates 475 k
...
Transaction Summary
==========================================================================================================
Install 19 Packages
Total size: 206 M
Total download size: 59 M
Installed size: 695 M
Is this ok [y/N]:
...
Installed:
binutils-2.37-36.fc36.x86_64 binutils-gold-2.37-36.fc36.x86_64
cpp-12.2.1-2.fc36.x86_64 elfutils-debuginfod-client-0.187-4.fc36.x86_64
gc-8.0.6-3.fc36.x86_64 gcc-12.2.1-2.fc36.x86_64
glibc-devel-2.35-20.fc36.x86_64 glibc-headers-x86-2.35-20.fc36.noarch
guile22-2.2.7-5.fc36.x86_64 kernel-headers-6.0.5-200.fc36.x86_64
libmpc-1.2.1-4.fc36.x86_64 libpkgconf-1.8.0-2.fc36.x86_64
libtool-ltdl-2.4.7-1.fc36.x86_64 libxcrypt-devel-4.4.28-1.fc36.x86_64
make-1:4.3-7.fc36.x86_64 pkgconf-1.8.0-2.fc36.x86_64
pkgconf-m4-1.8.0-2.fc36.noarch pkgconf-pkg-config-1.8.0-2.fc36.x86_64
rustup-1.0-1.x86_64
Cool, eh?
Let's try running rustc?
[root@9b80162d68a3 /]# PATH=/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin:"$PATH"
[root@9b80162d68a3 /]# echo 'fn main() { println!("Hello world!"); }' > hello.rs
[root@9b80162d68a3 /]# rustc hello.rs
[root@9b80162d68a3 /]# ./hello
Hello world!
sdkman --
% bundle exec bin/fpm --verbose -f -s curlbash -t rpm -n sdkman \
--depends zip --depends unzip \
--curlbash-setup "apt-get update" \
--curlbash-setup "apt-get install -y curl unzip zip" 'curl -s "https://get.sdkman.io?rcupdate=false" | bash'
And installing it...
[root@693dc2883f2c /]# dnf install sdkman-1.0-1.x86_64.rpm
...
Installed:
sdkman-1.0-1.x86_64 unzip-6.0-57.fc36.x86_64 zip-3.0-32.fc36.x86_64
Complete!
[root@693dc2883f2c /]# source "$HOME/.sdkman/bin/sdkman-init.sh"
[root@693dc2883f2c /]# sdk install java
Downloading: java 17.0.5-tem
In progress...
############################# 29.3%
Repackaging Java 17.0.5-tem...
Done repackaging...
Installing: java 17.0.5-tem
Done installing!
Setting java 17.0.5-tem as default.
:+1:
Heh, what if we package what sdkman does instead?
% bundle exec bin/fpm --verbose -f -s curlbash -t rpm -n sdkman-java \
--curlbash-setup "apt-get update" \
--curlbash-setup "apt-get install -y curl unzip zip" \
--curlbash-setup 'curl -s "https://get.sdkman.io?rcupdate=false" | bash' \
'bash -c ". $HOME/.sdkman/bin/sdkman-init.sh; sdk install java"'
[root@77d5815e9be6 /]# rpm -Uvh sdkman-java-1.0-1.x86_64.rpm
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:sdkman-java-1.0-1 ################################# [100%]
[root@77d5815e9be6 /]# /root/.sdkman/candidates/java/17.0.5-tem/bin/java --version
openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)
Chef's installer
% bundle exec bin/fpm --verbose -f -s curlbash -t rpm -n chef \
--curlbash-container-image fedora:36 \
'curl -L https://omnitruck.chef.io/install.sh | bash'
% podman run -v "$PWD/chef-1.0-1.x86_64.rpm:/chef-1.0-1.x86_64.rpm" -it fedora:36
[root@3a51dd0abbfc /]# rpm -i chef-1.0-1.x86_64.rpm
[root@3a51dd0abbfc /]# ohai platform
[root@3a51dd0abbfc /]# ohai platform
[
"fedora"
]
Trying ohmyzsh:
% bundle exec bin/fpm --verbose -f -s curlbash -t rpm -n ohmyzsh \
--depends zsh --depends git \
--curlbash-container-image fedora:36 \
--curlbash-setup "dnf install -y zsh git" \
'curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh | sh'
Created package {:path=>"ohmyzsh-1.0-1.x86_64.rpm"}
[root@4a8f07e439b5 /]# dnf install ohmyzsh-1.0-1.x86_64.rpm
Dependencies resolved.
==========================================================================================================
Package Architecture Version Repository Size
==========================================================================================================
Installing:
ohmyzsh x86_64 1.0-1 @commandline 2.1 M
Installing dependencies:
...
Transaction Summary
==========================================================================================================
Install 79 Packages
Total size: 24 M
Total download size: 22 M
Installed size: 94 M
Is this ok [y/N]: y
[root@4a8f07e439b5 /]# zsh -ls
➜ / echo $ZSH_THEME
robbyrussell

Trying nodesource. This script seems to add a apt repository on Ubuntu then offers apt-get install nodejs. Let's capture the result of installing nodejs instead.
% bundle exec bin/fpm --verbose -f -s curlbash -t deb -n nodesource -v 19 \
--curlbash-setup 'apt-get update' \
--curlbash-setup 'apt-get install -y curl' \
--curlbash-setup 'curl -fsSL https://deb.nodesource.com/setup_19.x | bash -' \
'apt-get install -y nodejs'
Created package {:path=>"nodesource_19_amd64.deb"}
This is fun because it actually captures the nodejs install instead of just updating your apt repos.
% podman run -v "$PWD/nodesource_19_amd64.deb:/nodesource_19_amd64.deb" -it ubuntu:latest
root@28e3fc58ef68:/# dpkg -i nodesource_19_amd64.deb
...
root@28e3fc58ef68:/# node
Welcome to Node.js v19.0.1.
Type ".help" for more information.
>
It's not perfect, but it is funny :)
Added Dockerfile/Containerfile support