Install Convert deb to pkg.tar.zst
One could consider the topic title clickbait but the question surfaces from time to time
The short answer is You cannot!
Keep reading for the longer answer. If you reach the bottom of this thread - you also get an idea of how much work there is for a package maintainer to keep up with upstream changes.
Think of the work if the package is compiled from source β¦
Perhaps then you will appreciate the work done by the team voluntering their free time to maintain the current packages and you will also know why requests for added packages is often rejected.
There is a lot of work involved β¦ and if you continue reading you also have some insight into the work of a package maintainer.
Why you cannot install .deb packages
.deb packages are created for Debian and derivatives and there is a major difference in what is provided inside a package or in dependencies.
Therefore you cannot install .deb packages as it is - it must be mogrified to match an Arch based system.
Content of a Arch package
The native package manager is called pacman.
pacman uses a native package format which is a compressed archive providing the complete folder/file structure and some simple instructions instructions used by pacman.
pacman uses these instructions to execute various actions when installing or removing a package and to keep track of files and their locations, thereby knowing precisely which file belongs to what package and where it resides.
This is used to ensure that the system - the distribution part - is kept in a manageable manner.
When pacman - during the initial processing of a package - encounters a file in filesystem - which is not known to exist as recorded by pacman - the package manager will refuse to continue.
The file(s) may be owned by another package or it has been placed there by a user, perhaps as a result of a local make and the subsequent sudo make install and as such they are legit but pacman needs you to resolve the conflict.
libraries and dependencies
Complicated applications often depends on functionality provided in libraries which are then provided by a dependency package.
Debian and Arch does not provide the libraries in packages with the same name and therefore some leg-work must be done in order to correctly identify the Arch counterparts of Debian packages.
That leg-work may not be as easy as you think - but the process of collecting the information gives you an invaluable insight into how simple and straight forward Arch package management is compared to Debian.
Debian may provide installation of multiple versions of the same library due to their philosophy whereas Arch only has one version - the latest.
A PKGBUILD providing content of .deb package
Yes - this is possible.
The google-chrome PKGBUILD in AUR is an example of a .deb package converted to fit the Arch eco-system.
Lookup the PKGBUILD on AUR and take a look inside - it is very educating.
get dirty
The mention and the Debian package used in this example does not mean any endorsement or recommendation of AtlasVPN.
I have seen a couple of attempts to use AtlasVPN on Arch and since it doesnβt exist in AUR - let us have some fun. I do not care anything for AtlasVPN as the only use I have for them is to showcase how to make something useful from a .deb package.
The mention and the Debian package used in this example does not mean any endorsement or recommendation of AtlasVPN.
Information gathering
They have a download for they Linux app - but as it turns out - the download is only to install the required keyrings and source.list identifying the servers hosting the final client application.
Downloading will provide you with a file named atlasvpn-repo.deb - a file we need to unpack to extract the info inside the archive.
Create a work folder and save the file in it - e.g. a folder named workdir in your home.
Everything will be terminal - it is the best way of learning your way around a Linux system.
mkdir ~/workdir
Change directory into the folder
cd ~/workdir
I copied the link you see below from their web @2023-03-10 18:16 - just in case they change it.
You can download the file using your web browser - just be sure to either save the file in the work folder or move it there after download.
Or you can use curl or wget to fetch the file using the url
wget https://downloads.atlasvpn.com/apps/linux/atlasvpn-repo.deb
Now we need to extract the content
ar x atlasvpn-repo.deb
Let us see what we got
$ ls
atlasvpn-repo.deb control.tar.xz data.tar.xz debian-binary
The file we are interested in is data.tar.xz which is yet an archive to unpack
tar -x data.tar.xz
Again let us see what new we have
$ ls
atlasvpn-repo.deb control.tar.xz data.tar.xz debian-binary etc
This time we got a folder named etc - let us look inside - this time using the command tree - because we need to know where to go. tree is likely not available - so install it
sudo pacman -Syu tree
You should get a similar output
$ tree
.
βββ atlasvpn-repo.deb
βββ control.tar.xz
βββ data.tar.xz
βββ debian-binary
βββ etc
βββ apt
βββ keyrings
β βββ atlasvpn.gpg
βββ sources.list.d
βββ atlasvpn.list
We are not interested in the keyring but the content of the atlasvpn.list file
$ cat etc/apt/sources.list.d/atlasvpn.list
deb [signed-by=/etc/apt/keyrings/atlasvpn.gpg] http://repo.atlasvpn.com/debian stable main
From the content we the url http://repo.atlasvpn.com/debian
as the location from which to install the app.
Now that we know this - we can clean the folder
rm -r ~/workdir/*
Open a browser and navigat to http://repo.atlasvpn.com/debian - you can browse around to see if you can figure out what you need.
Let me help - you need to go down the pool road - you eventually end at
http://repo.atlasvpn.com/debian/pool/main/a/atlasvpn/
Click the newest file - at time of writing it is atlasvpn_1.0.3_amd64.deb - save the file in our work folder.
Or you can use wget one more time - do remember - the filename may not be the same in a month from now - or a year β¦
wget https://repo.atlasvpn.com/debian/pool/main/a/atlasvpn/atlasvpn_1.0.3_amd64.deb
We learned above that a .deb file can be unpacked using ar and the files we are interested in is inside data.tar.xz - so let us unpack and see what we got
ar x atlasvpn_2.0.3_amd64.deb
tar -xf data.tar.xz
$ tree
.
βββ atlasvpn_1.0.3_amd64.deb
βββ control.tar.xz
βββ data.tar.xz
βββ debian-binary
βββ usr
βββ bin
β βββ atlasvpn
βββ lib
β βββ systemd
β βββ system
β βββ atlasvpnd.service
β βββ atlasvpnd.socket
βββ sbin
βββ atlasvpnd
That looks simple enough.
Hold your horse - not so fast - perhaps you have noted the structure is familiar - and yes - the data part of deb files are packaged using the same structure as Arch - files are located where they are supposed to go - so one could think - hey - we just sudo cp the whole #! and be done with it - and you can - you can stop right here and be done with it.
But where is the challenge in that?
And do you know what to do with the files?
What if you decide the freebie VPN was a bummer - in couple of month from now - how do you uninstall - can you even remember the files? Can you reverse the steps needed so you do not accidently break your system?
On Debian the archive control.tar.xz contains the package manager instructions and to satisfy our inner student we need to know what instructions could be applicable for this app.
After all - our intention is to create a PKGBUILD so you can update with ease when the next release lands.
So let us unpack that archive as well
tar -xf control.tar.xz
$ tree
.
βββ atlasvpn_1.0.3_amd64.deb
βββ control
βββ control.tar.xz
βββ data.tar.xz
βββ debian-binary
βββ postinst
βββ postrm
βββ prerm
βββ usr
βββ bin
β βββ atlasvpn
βββ lib
β βββ systemd
β βββ system
β βββ atlasvpnd.service
β βββ atlasvpnd.socket
βββ sbin
βββ atlasvpnd
We now have three extra files and their names correspond to the processes
post install
$ cat postinst
#!/usr/bin/env bash
LOG_DIR="/var/log/atlasvpn"
ENV=$(ps --no-headers -o comm 1)
installSuccess="AtlasVPN for Linux successfully installed!"
case "$1" in
configure)
update-desktop-database 2> /dev/null
mkdir -m 0750 -p "$LOG_DIR"
case "$ENV" in
systemd)
systemctl daemon-reload &>/dev/null || :
systemctl enable atlasvpnd.socket &>/dev/null || :
systemctl enable atlasvpnd.service &>/dev/null || :
systemctl start atlasvpnd.socket &>/dev/null || :
systemctl start atlasvpnd.service &>/dev/null || :
;;
esac
if [[ ! "$2" ]]; then
echo "${installSuccess}"
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "[ERROR] postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0
pre remove
$ cat prerm
#!/usr/bin/env bash
ENV=$(ps --no-headers -o comm 1)
case "$1" in
remove|upgrade|deconfigure)
case "$ENV" in
*sh) # executed in docker
;;
systemd)
systemctl stop atlasvpnd.service &>/dev/null || :
systemctl stop atlasvpnd.socket &>/dev/null || :
systemctl disable atlasvpnd.service &>/dev/null || :
systemctl disable atlasvpnd.socket &>/dev/null || :
systemctl daemon-reload &>/dev/null || :
;;
*)
echo "[ERROR] Unknown environment \`$ENV'"
;;
esac
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0
post remove
$ cat postrm
#!/usr/bin/env bash
case "$1" in
remove|purge)
rm -f /usr/share/applications/atlasvpn.desktop
update-desktop-database 2> /dev/null
rm -f /usr/share/zsh/functions/Completion/Unix/_atlasvpn
rm -f /usr/share/bash-completion/completions/atlasvpn
rm -f /usr/lib/systemd/system/atlasvpnd.*
rm -f /usr/lib/systemd/tmpfiles.d/atlasvpn.conf
rm -f /etc/init.d/atlasvpn
rm -rf /root/.config/atlasvpn
rm -rf /usr/share/doc/atlasvpn
rm -rf /var/lib/atlasvpn
rm -rf /var/log/atlasvpn
rm -rf /run/atlasvpn
;;
disappear|upgrade|failed-upgrade|abort-install|abort-upgrade)
;;
*)
echo "$0: didn't understand being called with \`$1'" 1>&2
exit 0
;;
esac
exit 0
The file is used by the Debian package manager - so what really interest us is what is done and when.
On installation the service and socket is enabled and started
systemctl daemon-reload &>/dev/null || :
systemctl enable atlasvpnd.socket &>/dev/null || :
systemctl enable atlasvpnd.service &>/dev/null || :
systemctl start atlasvpnd.socket &>/dev/null || :
systemctl start atlasvpnd.service &>/dev/null || :
Before we remove the app we stop and disable the service and socket
systemctl stop atlasvpnd.service &>/dev/null || :
systemctl stop atlasvpnd.socket &>/dev/null || :
systemctl disable atlasvpnd.service &>/dev/null || :
systemctl disable atlasvpnd.socket &>/dev/null || :
systemctl daemon-reload &>/dev/null || :
The actual removal involve these steps on a Debian system
rm -f /usr/share/applications/atlasvpn.desktop
update-desktop-database 2> /dev/null
rm -f /usr/share/zsh/functions/Completion/Unix/_atlasvpn
rm -f /usr/share/bash-completion/completions/atlasvpn
rm -f /usr/lib/systemd/system/atlasvpnd.*
rm -f /usr/lib/systemd/tmpfiles.d/atlasvpn.conf
rm -f /etc/init.d/atlasvpn
rm -rf /root/.config/atlasvpn
rm -rf /usr/share/doc/atlasvpn
rm -rf /var/lib/atlasvpn
rm -rf /var/log/atlasvpn
rm -rf /run/atlasvpn
the satisfaction of satisfying the pacman
We present the PKGBUILD - the most overlooked file in the Arch universe - yet responsible for so much in the hands of the very capable pacman.
In this section will take a closer look following the coverage in https://wiki.archlinux.org/title/Arch_package_guidelines
In the pacman shared folder we find template files (and the default keyrings) - ignore the keyrings please
$ tree /usr/share/pacman
/usr/share/pacman
βββ keyrings
β βββ archlinux.gpg
β βββ archlinux-revoked
β βββ archlinux-trusted
β βββ Arch.gpg
β βββ Arch-revoked
β βββ Arch-trusted
βββ PKGBUILD.proto
βββ PKGBUILD-split.proto
βββ PKGBUILD-vcs.proto
βββ proto.install
Creating the PKGBUILD
Now create the final folder to hold our build script and copy the prototypes into it
The PKGBUILD is the heart of our package and the install file is defining the actions during the transaction pacman invokes.
mkdir ~/atlasvpn
cd atlasvpn
cp /usr/share/pacman/PKGBUILD.proto ~/atlasvpn/PKGBUILD
cp /usr/share/pacman/proto.install ~/atlasvpn/atlasvpn.install
Open the PKGBUILD file in your favorite editor.
The file consist of two sections, a properties (variables) section and a functions section.
Which properties are used depends on the targeted application so the below list is with reference to our test subject atlasvpn and which functions also depends on what needs to be done.
How to decide which properties to use
- pkgname is atlasvpn
- pkgver is the version we downloaded earlier 1.0.3
- pkgrel is 1 - since it is our first time around - pkgrel is incremented when you have installed the package but then discover an error in the package and need to rebuild it - perhaps a file was misplaced or entirely missing any change in the packaging which is not a pkgver increment.
- epoch we do not use - remove the line
- pkgdesc is a short text describing what the package provides and itβs usage
- in this case it could be My port of atlasvpn installer to Arch
- arch is the architecture for which this package has been created. As the downloaded archive specifically state it is for amd64 we can assume it will not work for arm based device - so we add x86_64 to the array.
- url is the url containing the source
https://atlasvpn.com
- it could be your Codeberg repo - license is tricky in this case because there is no reference on their web site - so we follow the guidelines and add βunknownβ to the array
- groups is not used
- depends is not known. It is an vpn we could assume openvpn - perhaps wireguard-tools if they support wireguard - but as we do not know we will have to test before we can decide. Use something like ldd to detemine which libraries the binary has been linked with.
- makedepends is not used
- checkdepends is not used
- optdepends is not used
- provides is implicit by the package name - donβt use
- conflicts is not used
- replaces is not used
- backup is not used
- options is not used
- install this is our install script - which we created as atlasvpn.install
- changelog this is string describing what changed with this particular build not needed
- source is an array of sources needed to build this package - in this case it is the url where the upstream installer is located
https://repo.atlasvpn.com/debian/pool/main/a/atlasvpn/atlasvpn_1.0.3_amd64.deb
- here we will use variable expansion as we have seen both the pkgname and pkgver is part of the filename
- noextract is not needed
- md5sums or sha256sums or sha512sums is a control mechanism to ensure the file downloaded is complete compared to the time of creating the PKGBUILD. It should not be taken as verification the download is legit.
- The checksum is added to the PKGBUILD by using the updpkgsums command in the folder containing the PKGBUILD.
- The new default checksum is sha256 and updpkgsums will update to this
- validpgpkeys is the seal that verifies the downloaded package is legit but for that we need the signature and since there is no signature - we cannot compare - therefore we cannot use this property
A PKGBUILD is sourced by makepkg which is a bash script and therefore it is important to know the difference between using βstringβ and βstringβ. The first usage defines a literal string - the second usage allows for embedding properties e.g. β${pkgname}_${pkgver}_amd64.debβ which at runtime is replace with the value in the PKGBUILDβs pkgver property.
The populated property list
The properties we do not use we remove and when done the properties section of the file should look like this.
# Maintainer: Your Name <youremail@domain.com>
pkgname=atlasvpn
pkgver=1.0.3
pkgrel=1
pkgdesc="My port of atlasvpn installer to Arch"
arch=('x86_64')
url='https://atlasvpn.com'
license=('unknown')
depends=()
install=$pkgname.install
source=("https://repo.atlasvpn.com/debian/pool/main/a/atlasvpn/"$pkgname"_"$pkgver"_amd64.deb")
sha256sums=()
The packaging instructions
Let us look at the functions section and decide what we need
- prepare() function - no - remove it
- build() function - no - remove it
- check() function - no - remove it
- package() function - yes - always
Now we need to tell the package function what to do with the content of unpacked archive - remember the tree when we unpacked the archive manually?
βββ usr
βββ bin
β βββ atlasvpn
βββ lib
β βββ systemd
β βββ system
β βββ atlasvpnd.service
β βββ atlasvpnd.socket
βββ sbin
βββ atlasvpnd
The populated instruction
Modify the PKGBUILD package() function as follows and save the file
package() {
echo " -> Extracting the data.tar.xz"
bsdtar -xf data.tar.xz -C "$pkgdir/"
mv "$pkgdir"/usr/sbin/atlasvpnd "$pkgdir"/usr/bin
# ensure correct permission on usr tree
chmod 755 "$pkgdir"/usr -R
# remove execute permissions on service files
chmod 644 "$pkgdir"/usr/lib/systemd/system/*
# remove unused folder (symlink on Arch)
rm -r "$pkgdir"/usr/sbin
}
Then populate the checksums - this will download the file if it is not present.
updpkgsums
Building the package
When you build the package the following happens
- makepkg downloads the file if it is not present
- makepkg creates two work folders pkg and src and unpacks the deb file into the src folder
- The package() instructs makepkg to unpack the data.tar.xz and place it in the pkg folder
- Ensure correct directory permissions inside the package 755
- Remove execute permissions for unit files
- As Arch does not use the /usr/sbin folder we follow the guide lines and move the content to the /usr/bin folder.
- Then we remove the /usr/sbin from the pkg folder.
- makepkg packages the work folder and creates the necessary information that enables pacman to keep track of the installed files
Excute makepkg
Now run the the makepkg script
makepkg
When you dive into this be prepared to run makepkg numerous times - until you get it right.
Take a look at the folder using tree
$ tree
.
βββ atlasvpn-1.0.3-1-x86_64.pkg.tar.zst
βββ atlasvpn_1.0.3_amd64.deb
βββ atlasvpn.install
βββ pkg
β βββ atlasvpn
β βββ usr
β βββ bin
β β βββ atlasvpn
β β βββ atlasvpnd
β βββ lib
β βββ systemd
β βββ system
β βββ atlasvpnd.service
β βββ atlasvpnd.socket
βββ PKGBUILD
βββ src
βββ atlasvpn_1.0.3_amd64.deb -> /home/$USER/atlasvpn/atlasvpn_1.0.3_amd64.deb
βββ control.tar.xz
βββ data.tar.xz
βββ debian-binary
βββ usr
βββ bin
β βββ atlasvpn
βββ lib
β βββ systemd
β βββ system
β βββ atlasvpnd.service
β βββ atlasvpnd.socket
βββ sbin
βββ atlasvpnd
Now you have built a package atlasvpn-1.0.3-1-x86_64.pkg.tar.zst.
Verify content of package file
Check the content of the archive to see the files has been placed correct according to source and guidelines.
pacman -Qlp atlasvpn-1.0.3-1-x86_64.pkg.tar.zst
The install script
We still need to implement the activation of socket and service - let us do that in minute - first we will check our installtion.
Open the file atlasvpn.install next to the PKGBUILD.
The available functions is listed and we need to decide which we need to use.
- pre_install() - no - remove
- post_install() - yes - enable and start service and socket
- pre_upgrade() - yes - it is likely a good idea to stop the service and socket
- inform user that service will be disconnected
- post_upgrade() - yes - re-enable service and socket
- pre_remove() - yes - we donβt want dangling symlinks - so we disable the service and socket
- post_remove() - yes - display message
The populated install script
The final install file could look like this.
Remember the debβs postrm - it removed several files not installed - so they have to be generated by the application when it is in use.
post_install() {
echo " -> Starting services ...."
systemctl enable --now atlasvpnd.service > /dev/null 2>&1
systemctl enable --now atlasvpnd.socket > /dev/null 2>&1
}
pre_upgrade() {
echo " -> If connection is active it will now disconnect ...."
atlasvpn disconnect > /dev/null 2>&1
echo " -> Stopping services ...."
systemctl stop atlasvpnd.service > /dev/null 2>&1
systemctl stop atlasvpnd.socket > /dev/null 2>&1
}
post_upgrade() {
echo " -> Starting services ...."
echo " -> Remember to reconnect to VPN service ...."
systemctl enable --now atlasvpnd.service > /dev/null 2>&1
systemctl enable --now atlasvpnd.socket > /dev/null 2>&1
}
pre_remove() {
echo " -> Attempt to disconnect vpn service ...."
atlasvpn disconnect> /dev/null 2>&1
echo " -> Disable and remove services ...."
systemctl disable --now atlasvpnd.service > /dev/null 2>&1
systemctl disable --now atlasvpnd.socket > /dev/null 2>&1
# assuming they are creating at runtime
echo " -> Removing files"
rm -f /usr/share/applications/atlasvpn.desktop > /dev/null 2>&1
rm -f /usr/share/zsh/functions/Completion/Unix/_atlasvpn > /dev/null 2>&1
rm -f /usr/share/bash-completion/completions/atlasvpn > /dev/null 2>&1
rm -f /usr/lib/systemd/system/atlasvpnd.* > /dev/null 2>&1
rm -f /usr/lib/systemd/tmpfiles.d/atlasvpn.conf > /dev/null 2>&1
rm -f /etc/init.d/atlasvpn > /dev/null 2>&1
rm -rf /root/.config/atlasvpn > /dev/null 2>&1
rm -rf /usr/share/doc/atlasvpn > /dev/null 2>&1
rm -rf /var/lib/atlasvpn > /dev/null 2>&1
rm -rf /var/log/atlasvpn > /dev/null 2>&1
rm -rf /run/atlasvpn > /dev/null 2>&1
}
post_remove() {
echo " -> atlasvpn has been removed!"
}
Install your package
- Using makepkg
makepkg -i
- Using pacman
sudo pacman -U atlasvpn-1.0.3-1-x86_64.pkg.tar.zst
- Using pamac
pamac install atlasvpn-1.0.3-1-x86_64.pkg.tar.zst
- Using yay
yay -U atlasvpn-1.0.3-1-x86_64.pkg.tar.zst
Conclusion
If you hoped the AtlasVPN was usable - you may be disappointed.
You can create an account and login - but you need a paid account to be able to connect to the servers. At least I wasnβt able to find anything on how to connect using the advertised free-wheeling servers.
Note: you will need a premium Atlas VPN subscription to connect to the VPN on Linux. To get a premium subscription, go to our pricing page and pick the deal that suits you best!
help.atlasvpn.com/hc/en-us/articles/7301882184082-Installing-Atlas-VPN-on-Linux