Self Made Installer Packages
Alex M. Schapelle
Posted on February 19, 2024
Welcome back gentle reader, I am Silent-Mobius, aka Alex M. Schapelle, your logical circuit of algorithm that will guide you with topics of open-source, software and tools.
In today's input log, we'll discuss a tool named makeself.sh
. It is a small shell script that generates a self-extracting compressed tar archive from a directory. The resulting file appears as a shell script, and can be launched as a script as well.
While use cases may vary, the gist of it is, that we may use makeself.sh
to compress an software development projects in tar archive, and by adding any script to automate conditions of setting up dependencies, configurations and services for out project to work.
Some of the examples of publicly available archives made using makeself.sh
are :
- The nVidia drivers for Linux
- The Google Earth installer for the Linux
- The independent VirtualBox installers for Linux
As you may notice, it is mostly for *nix based systems, yet in case you use WSL or Cygwin, makeself.sh
will work as well.
Who needs it ?
As mentioned, my dear reader, cases may vary, yet typical case would be for you to pack your software with KISS (Keep It Simple Stupid) structure in mind, under working directory, while satisfying binary dependencies, configuring environment variables, setting soft-links and so on.
Will it work on complex project with multi environment setup ?
Probably, YES ! mostly depends on your will to write and maintain the install
script
Setup
To start using makeself.sh
we ought to get the executable of makeself.sh
, which is written by Stéphane Peter in pure shell script. Currently the latest version of makeself.sh
stands on 2.5.0 and tool is self installing, meaning that you install it by running the tool itself:
wget https://github.com/megastep/makeself/releases/download/release-2.5.0/makeself-2.5.0.run
chmod +x makeself-2.5.0.run
./makeself-2.5.0.run
This will install the tool in your system.
[!]
Note: you may installmakeself
with your nix based system's package manager, yet from my small test on Debian, Ubuntu, Rockylinux9, Fedora38 and AlmaLinux9, the version on those repositories are little bit older, standing on 2.4.5 which might have either small differences or bugs, I *did not check.
Synopsis
The usage of our tool pretty simple in its core design:
makeself.sh project_folder package.run \
"[+] A label ..." ./install.sh
-
project_folder
: a path to folder where the project is located, usually development environment for developers- Note: usually suggested to use full path to project folder
-
package.run
: a name you wish to give to your packed development environment- Note: preferred to use
-
"[+] A label ..."
: sort of a message that prints out when running thepackage.run
executable -
./install.sh
: a script that you use to setup all required configurations, environment variables and so on.- Note: the
./
is required even if you are not packing the project from the project folder itself
- Note: the
But as nanny Rosie used to say, one example routine is better then 10000000000 explanations
Example
Thus let us setup a scheme, where we create small project with small a minor dependencies. It is not a secret that most of small to medium projects I prefer to do with python3
programming language and this will not be an exception. I'll be using Debian 12 Linux distribution with poetry package manager
We'll start by creating the dev environment:
sudo apt update && sudo apt install python3-poetry
poetry new flask_genie
cd flask_genie
poetry add flask
poetry shell # this will create virtual environment for development
As you may see, there quite a list of commands, to which we may summarize as installing python development environment manager named poetry
and with it install flask
python library for developing our application.
Now lets drop our super magical application:
from random import choice
from flask import Flask
genie_quotes = [ "Tonight, The Part Of Al Will Be Played By A Tall, Dark, And Sinister Ugly Man",
"He's Big. He's Blue. He's BACK",
"Jafar, Jafar, He’s Our Man. If He Can’t Do It, GREAT!",
"Do Not Attempt To Move Or We’ll Be Shooting Ourselves",
"Ten Thousand Years Will Give You Such A Crick In The Neck!",
"Aw Al, I’m Getting Kinda Fond Of You, Kid. Not That I Want To Pick Out Curtains Or Anything",
"Oh, Al, You're Back. And Your Front, You’re Both Here",
"I Can't Believe I'm Losing To A Rug.",
"Yo, Rugman! Haven't Seen You In A Few Millennia. Give Me Some Tassel.",
"I Thought The Earth Wasn’t Supposed To Move Until The Honeymoon",
"No Matter What Anybody Says, You’ll Always Be A Prince To Me",
"Do You Mind If I Kiss The Monkey? Ooh, Hairball",
"You Ain't Never Had A Friend Like Me",
"Once Again, This Whole Broadcast Has Been Brought To You By Sand! It’s Everywhere. Get Used To It",
"Al, You're Not Going To Find Another Girl Like Her In A Million Years. Believe Me, I've Looked",
"I'm History! No, I'm Mythology! Nah, I Don't Care What I Am. I'm Free!",
"To Be My Own Master. Such A Thing Would Be Greater Than All The Magic And All The Treasures In All The World.",
"Phenomenal Cosmic Powers, Itty Bitty Living Space" ]
app = Flask(__name__)
@app.route('/')
@app.route('/index')
def index():
genie_quote = Figlet(font='bubble')
genie_says = genie_quote.renderText(choice(genie_quotes))
return '''<h1> Genie says:\n </h1>
<p>{}</p>
'''.format(genie_says)
app.run()
Small app that prints some of genie's quote from Aladdin cartoon.
Once done it should have a structure of the application that looks like something like below print out:
├── flask_genie
│ ├── app.py
│ └── __init__.py
├── poetry.lock
├── pyproject.toml
├── README.md
└── tests
└── __init__.py
Note: I'd like to remind that the main point he to learn pack the application, thus the idea behind the project does not matter.
Let's pack it up
Once the project is done, what well need is a install script to setup some dependencies and makeself.sh
to pack it up.
Install script
One may use any type of programming language when it comes to makeself.sh
, yet most easy and natural one would be shell
or bash
script.
I am using some of the initial setup commands to automate the setup thus the script will look like this:
#!/usr/bin/env bash
######################################
# Created by: Alex M. Schapele AKA Silent-Mobius
# Purpose: Install script for flask_genie project
# version: 0.0.1
# date: 18.01.2024
set -o errexit
set -o pipefail
#######################################
. /etc/os-release
PROJECT="$HOME/flask_genie"
INSTALLER=$( [[ $ID == 'debian' ]] && echo 'apt-get' || echo 'dnf' )
BUILD_TOOL=$(which poetry)
function main(){
if [[ ! -d $PROJECT ]];then
mkdir -p $PROJECT
fi
if [[ ${#BUILD_TOOL} -eq 0 ]];then
$INSTALLER install -y python3-poertry
fi
$BUILD_TOOL new $PROJECT
cd $PROJECT
$BUILD_TOOL add flask
}
####
# Main
####
main
Script may include anything and can even be separated into multiple files, as long as there is single file that invokes them, in our case install.sh
which we'll place under project folder itself:
├── flask_genie
│ ├── app.py
│ └── __init__.py
├── poetry.lock
├── pyproject.toml
├── install.sh
├── README.md
└── tests
└── __init__.py
Note: remember to add
chmod +x install.sh
for the script to run.
The Final Count Down
We come to final step of our voyage, which is essentially using makeself.sh
to pack the project into run file, and it looks like this:
makeself.sh /home/alex/flask_genie genie.run \
'[#] Installing flask_genie project on your system' ./install.sh
The generated file will be named genie.run
and we'll be able to copy/paste it to any other system and run to install
Fin
Thank you dear reader, for reading though this textual journey with me and I hope you enjoyed and elevated your mind to new technical level, and likes/subscribes/comments are always welcome.
This article and others, would not be possible with out original documentation, this please take a look:
And as always: Please Do Try To Have Some Fun
Ta-Ta
Posted on February 19, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.