How to make debian package
from scratch
Thierry GAYET
Example of a directories :
● my-package/ is the top-level directory for your package.
● DEBIAN/ is where you place control files and scripts.
● usr/ is where you place files that will be installed on the target system.
Structure of a debian package
Inside the DEBIAN/ directory, create a control file with package metadata.
For example:
Place the binary or files you want to package into the appropriate directories. In this example, we have an
executable named my-executable in usr/bin/.
You can customize the package further by adding pre-installation and post-installation scripts, defining dependencies, and
more in the DEBIAN/control file.
Help : https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
Structure of a debian package
gayett@DES126 ~ cd /var/cache/apt/archives
gayett@DES126 /var/cache/apt/archives ls -al
total 810980
drwxr-xr-x 3 root root 36 janv. 18 06:25 .
drwxr-xr-x 3 root root 5 janv. 18 14:42 ..
-rw-r--r-- 1 root root 49148 déc. 14 16:41 alacarte_3.44.1-1ubuntu0.1_all.deb
-rw-r--r-- 1 root root 354598 déc. 12 08:27 dnsmasq-base_2.86-1.1ubuntu0.4_amd64.deb
-rw-r--r-- 1 root root 210160 mars 24 2022 gir1.2-gtk-2.0_2.24.33-2ubuntu2_amd64.deb
-rw-r--r-- 1 root root 104953176 déc. 19 22:58 google-chrome-stable_120.0.6099.129-1_amd64.deb
-rw-r--r-- 1 root root 105001444 janv. 3 00:33 google-chrome-stable_120.0.6099.199-1_amd64.deb
-rw-r--r-- 1 root root 105001328 janv. 9 00:39 google-chrome-stable_120.0.6099.216-1_amd64.deb
-rw-r--r-- 1 root root 105000828 janv. 12 21:33 google-chrome-stable_120.0.6099.224-1_amd64.deb
-rw-r--r-- 1 root root 47836 oct. 21 2022 libgdk-pixbuf-2.0-dev_2.42.8+dfsg-1ubuntu0.2_amd64.deb
-rw-r--r-- 1 root root 777594 mars 24 2022 libgtk2.0-dev_2.24.33-2ubuntu2_amd64.deb
-rw-r--r-- 1 root root 1476 avril 8 2022 libjpeg8-dev_8c-2ubuntu10_amd64.deb
-rw-r--r-- 1 root root 1472 avril 8 2022 libjpeg-dev_8c-2ubuntu10_amd64.deb
-rw-r--r-- 1 root root 256872 févr. 21 2022 libjpeg-turbo8-dev_2.1.2-0ubuntu1_amd64.deb
-rw-r--r-- 1 root root 314818 nov. 23 22:04 libtiff-dev_4.3.0-6ubuntu0.7_amd64.deb
-rw-r--r-- 1 root root 1756002 déc. 8 14:33 libvirt0_8.0.0-1ubuntu7.8_amd64.deb
-rw-r--r-- 1 root root 411316 déc. 8 14:33 libvirt-daemon_8.0.0-1ubuntu7.8_amd64.deb
-rw-r--r-- 1 root root 747132 déc. 8 14:33 libvirt-daemon-driver-qemu_8.0.0-1ubuntu7.8_amd64.deb
-rw-r--r-- 1 root root 263051680 déc. 15 16:12 linux-firmware_20220329.git681281e4-0ubuntu3.24_all.deb
gayett@DES126 /var/cache/apt/archives file teamviewer_15.49.2_amd64.deb
teamviewer_15.49.2_amd64.deb: Debian binary package (format 2.0), with control.tar.xz, data compression xz
First way using dpkg-deb
- You must be on a debian/ubuntu Linux distribution of course
- You need to have several packages :
$ sudo apt install dpkg
(ubuntu 22.04 LTS)
Requirements
Generation of a debian package
Navigate to the parent directory containing the my-package folder and run the following dpkg-deb command to build the
package:
This will create a Debian package file named my-package.deb in the current directory.
Manual : https://man7.org/linux/man-pages/man1/dpkg-deb.1.html
Help :
● https://www.iodigital.com/nl/history/intracto/creating-debianubuntu-deb-packages
Installation of a debian package
You can now install the debian package using dpkg:
To execute on the server to update!
MANUAL : https://doc.ubuntu-fr.org/dpkg
In detail …
# Create the my-package (root directory) and the DEBIAN directory (for the
metadata)
$ mkdir -p my-package/DEBIAN
# Create the content’s directory
$ mkdir -p my-package/opt/
“
→ opt” have been selected but we can choose freely any path ; it will installed
into /opt in the final filesystem !
$ tree
└── my-package/ # main folder of the package
├── DEBIAN/ # will contains the package’s metadata
└── opt/ # will contains the content of the package
# Go into the my-package directory
$ cd my-package/opt/
# pull your update at the root of the content’s directory
$ git clone git@your_git_server.git
$ tree
└── my-package/
├── DEBIAN/
└── opt/
└── my-daemon
└── your_executable
# go into the my-package/DEBIAN directory
$ cd my-package/DEBIAN/
# Generate info about package’s metadata
cat <<- EOF > control
Package: foo
Version: 1.0
Section: base
Priority: optional
Architecture: all
Maintainer: Thierry GAYET <thierry.gayet@toto.com>
Description: Source code of the foo appliance
Homepage: https://www.toto.com
EOF
Help : h
ttps://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
# Create PRE and POST script to hook :
$ cat <<- EOF > ./preinst
#
# preinst
#
EOF
$ cat <<- EOF > ./postinst
#
# postinst
#
EOF
$ cat <<- EOF > ./prerm
#
# prerm
#
EOF
$ cat <<- EOF > ./postrm
#
# postrm
#
EOF
→ Customize all script for changing rights,
restarting service(s), updating docker, ….
# Change right to the metadata’s files
$ chmod -R 755 my-package/DEBIAN
$ chmod 755 my-package/
$ tree
└── my-package/
├── DEBIAN/
├── control
├── postinst
├── postrm
├── preinst
└── prerm
└── opt/
└── my-deamon/
└── your_executable
# Go back in the directories :
$ cd ../../
# Generate the debian package :
# Package’s name : my-package-<branch>-<version>.deb
# branch = main
# version = 1.0
$ dpkg-deb --verbose --build ./my-package/ ./my-package-1.0.deb
dpkg-deb: building package in 'my-package-1.0.deb'.
# Enumerate all files :
$ dpkg --contents ./my-package-1.0.deb
drwxr-xr-x tgayet/tgayet 0 2023-10-28 20:06 ./
drwxrwxr-x tgayet/tgayet 0 2023-10-28 20:11 ./opt/
drwxrwxr-x tgayet/tgayet 0 2023-10-28 20:38 ./opt/my-daemon/
-rwxr-xr-x tgayet/tgayet 0 2023-10-28 20:38 ./opt/my-deamon/your_executable
$ dpkg --info ./my-package-1.0.deb
new Debian package, version 2.0.
size 696 bytes: control archive=359 bytes.
213 bytes, 8 lines * control
15 bytes, 2 lines * postinst
13 bytes, 2 lines * postrm
14 bytes, 2 lines * preinst
12 bytes, 2 lines * prerm
Package: foo
Version: 1.0
Section: base
Priority: optional
Architecture: all
Maintainer: Thierry GAYET <thierry.gayet@toto.com>
Description: Source code of the foo appliance
Homepage: https://www.toto.com
$ dpkg --field ./my-package-1.0.deb
Package: foo
Version: 1.0
Section: base
Priority: optional
Architecture: all
Maintainer: Thierry GAYET <thierry.gayet@toto.com>
Description: Source code of the foo appliance
Homepage: https://www.toto.com
Second way using dpkg-
buildpackage
- You must be on a debian/ubuntu Linux distribution of course
- You need to have several packages :
$ sudo apt-get install dpkg-dev debhelper build-essential fakeroot
(ubuntu 22.04 LTS)
Requirements
Create the Package Directory Structure: You need to create a directory structure for your package. Here's a minimal example:
package_name/
├── debian/
│ ├── control
└── source_code/
Replace package_name with the name of your package and source_code with the directory containing your source code.
Create the Control File: Inside the debian directory, create a control file that contains metadata about your package. Here's a basic example:
Source: package_name
Section: misc
Priority: optional
Maintainer: Your Name <your.email@example.com>
Build-Depends: debhelper (>= 12)
Standards-Version: 4.5.0
Package: package_name
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: A brief description of your package.
Customize the fields according to your package's details.
Build the Package: Use the dpkg-buildpackage command to build the Debian package. Ensure you are in the parent directory of the
package_name directory:
$ dpkg-buildpackage -rfakeroot -b
This command will build the Debian package.
Install the Package: After building the package, you can install it using dpkg:
$ sudo dpkg -i ../package_name_1.0-1_all.deb
Replace package_name_1.0-1_all.deb with the actual name of the generated .deb package file.
Verify the Installation: To verify the installation, you can run:
$ dpkg -l | grep package_name
This should list the package as installed.
Clean Up: After you're done, you can remove the package:
$ sudo dpkg -r package_name
Second way using dh_make
- You must be on a debian/ubuntu Linux distribution of course
- You need to have several packages :
$ sudo apt-get install dpkg-dev debhelper build-essential fakeroot dh-make
(ubuntu 22.04 LTS)
Requirements
dh_make is a tool that simplifies the process of creating Debian source packages from upstream source code. It sets up the basic packaging
files and directory structure for you. Here's how to use dh_make to generate a Debian package.
Create a Working Directory: Create a directory to work in, where you'll place the source code and package files. You can create a new
directory, e.g., mypackage :
$ mkdir mypackage
$ cd mypackage
Download or Place Source Code: Download the source code for the software you want to package or place it in the mypackage directory. The
source code should be in a subdirectory within mypackage.
Run dh_make: Run the dh_make tool in the mypackage directory, specifying the type of software you're packaging. For example:
$ dh_make -s -c gpl -f ../source_code.tar.gz
● -s: Use the single-binary option.
● -c gpl: Set the software's license (replace gpl with the appropriate license).
● -f ../source_code.tar.gz: Specify the path to the source code archive.
Follow the prompts, including answering questions about the software's maintainer, email, and any other information required.
Package Configuration: dh_make will generate packaging files and directories. You may need to make some adjustments, such as:
○ Modify the debian/control file to specify package dependencies, architecture, and other package details.
○ Place any additional scripts, patches, or configuration files in the debian directory.
○ Review and edit the debian/rules file if needed to customize the build process.
Build the Package: Use debuild to build the package. This tool will handle the compilation, packaging, and other necessary steps.
$ debuild -us -uc
○ -us: Do not sign the source package.
○ -uc: Do not sign the changes file.
This command will create a .deb package and a source package in the parent directory.
Install and Test: Install the generated Debian package using dpkg:
sudo dpkg -i ../package_name_1.0-1_all.deb
Replace package_name_1.0-1_all.deb with the actual name of the generated package file.
Clean Up: After testing, you can remove the package:
$ sudo dpkg -r package_name
Submit to Debian Repository (Optional): If your package meets Debian's quality standards and licensing requirements, you can consider
submitting it to the Debian repository.
This process simplifies the initial setup for creating Debian packages, but further customization may be required based on the specific software
you are packaging. Additionally, you should follow Debian packaging guidelines to ensure the quality and compatibility of your package.
Demo for the foo appliance
foo
$ clear && ./redo_deb.sh
______ ___________ _____ _____ _ _ ___________ ___ _____ ___________
| _  ___| ___  | __ | ___|  | || ___| ___ / _ _ _| _ | ___ 
| | | | |__ | |_/ / | | /| |__ | | || |__ | |_/ / /_ | | | | | | |_/ /
| | | | __|| ___  | | __ | __|| || __|| /| _ || | | | | | /
| |/ /| |___| |_/ / | |_ | |___| | || |___| | | | | || |  _/ / | 
|___/ ____/____/ ____/____/_| _/____/_| __| |_/_/ ___/_| _|
- Parameters :
SRCDIR = '/home/gayett/Workspace/foo/src'
DESTDIR = '/home/gayett/Workspace/foo/debian/delivery'
PACKAGE_NAME = '/home/gayett/Workspace/foo/debian/my-local-1.0.deb'
ARCHITECTURE = 'amd64'
- METADATA_DIR = '/home/gayett/Workspace/foo/debian/delivery/DEBIAN'
- DATA_DIR = '/home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/'
- Checking '/home/gayett/Workspace/foo/debian/delivery' directory : NOK
- The final directory (/home/gayett/Workspace/foo/debian/delivery) already exist !
--> Do you want to revove it first? (Y/N): Y
- Removing '/home/gayett/Workspace/foo/debian/delivery' directory : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery' directory : OK
- Checking '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' debian package : NOK
- The final debian package (/home/gayett/Workspace/foo/debian/my-local-1.0.deb) already exist !
--> Do you want to revove it first? (Y/N): Y
- Removing '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' debian package : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN' directory : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/control' : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/preinst' : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/postinst' : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/prerm' : OK
- Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/postrm' : OK
/home/gayett/Workspace/foo/debian/delivery/DEBIAN
├── control
├── postinst
├── postrm
├── preinst
└── prerm
0 directories, 5 files
total 7,0K
drwxr-xr-x 2 gayett ug-all 7 févr. 8 13:02 .
drwxr-xr-x 3 gayett ug-all 3 févr. 8 13:02 ..
-rwxr-xr-x 1 gayett ug-all 213 févr. 8 13:02 control
-rwxr-xr-x 1 gayett ug-all 345 févr. 8 13:02 postinst
-rwxr-xr-x 1 gayett ug-all 14 févr. 8 13:02 postrm
-rwxr-xr-x 1 gayett ug-all 196 févr. 8 13:02 preinst
-rwxr-xr-x 1 gayett ug-all 117 févr. 8 13:02 prerm
- Creating '/home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/' directory : OK
total 231K
drwxr-xr-x 3 gayett ug-all 27 févr. 2 13:07 .
drwxr-xr-x 14 gayett ug-all 27 janv. 31 12:42 ..
-rwxr-xr-x 1 gayett ug-all 48K janv. 31 12:39 app.py
-rwxr-xr-x 1 gayett ug-all 18K févr. 2 13:04 config.py
-rwxr-xr-x 1 gayett ug-all 23K févr. 2 13:05 ffmpeg.py
-rwxr-xr-x 1 gayett ug-all 8,0K janv. 22 16:45 gpu.py
-rwxr-xr-x 1 gayett ug-all 5,1K déc. 18 10:55 instance.py
-rwxr-xr-x 1 gayett ug-all 5,4K janv. 10 15:39 logger.py
-rwxr-xr-x 1 gayett ug-all 22K déc. 11 18:02 multicast.py
-rwxr-xr-x 1 gayett ug-all 5,7K nov. 17 16:26 pattern.py
drwxr-xr-x 2 gayett ug-all 3 janv. 10 13:52 __pycache__
-rwxr-xr-x 1 gayett ug-all 7,4K nov. 17 16:26 rabbit.py
-rwxr-xr-x 1 gayett ug-all 574 nov. 17 16:26 requirements.txt
-rwxr-xr-x 1 gayett ug-all 14K nov. 24 18:01 route.py
-rwxr-xr-x 1 gayett ug-all 5,4K janv. 22 11:41 service.py
-rwxr-xr-x 1 gayett ug-all 1,6K nov. 17 16:26 singleton.py
-rwxr-xr-x 1 gayett ug-all 27K janv. 31 12:40 synchro.py
-rwxr-xr-x 1 gayett ug-all 11K déc. 14 16:09 threadManager.py
-rwxr-xr-x 1 gayett ug-all 995 nov. 17 16:26 unittest-critical.sh
-rwxr-xr-x 1 gayett ug-all 1,3K nov. 22 09:12 unittest-debug.sh
-rwxr-xr-x 1 gayett ug-all 1020 nov. 22 09:12 unittest-error.sh
-rwxr-xr-x 1 gayett ug-all 991 nov. 17 16:26 unittest-info.sh
-rwxr-xr-x 1 gayett ug-all 994 nov. 17 16:26 unittest-warning.sh
-rwxr-xr-x 1 gayett ug-all 240 nov. 17 16:26 update-requirements.sh
-rwxr-xr-x 1 gayett ug-all 26K févr. 2 13:06 utils.py
-rw-r--r-- 1 gayett ug-all 2,2K janv. 23 15:15 foo-probe-config.yml
-rwxr-xr-x 1 gayett ug-all 120K févr. 2 13:07 foo.py
- Recopying data source from /home/gayett/Workspace/foo/src/ to
/home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/ OK (0)
- Checking dpkg-deb package : OK
Build directory : '/home/gayett/Workspace/foo/debian/delivery'
Final package : '/home/gayett/Workspace/foo/debian/my-local-1.0.deb'
Content :
/home/gayett/Workspace/foo/debian/delivery
├── DEBIAN
│ ├── control
│ ├── postinst
│ ├── postrm
│ ├── preinst
│ └── prerm
└── opt
└── foo
└── my-deamon
├── app.py
├── config.py
├── ffmpeg.py
├── gpu.py
├── instance.py
├── logger.py
├── multicast.py
├── pattern.py
├── __pycache__
│ └── singleton.cpython-310.pyc
├── rabbit.py
├── requirements.txt
├── route.py
├── service.py
├── singleton.py
├── synchro.py
├── threadManager.py
├── unittest-critical.sh
├── unittest-debug.sh
├── unittest-error.sh
├── unittest-info.sh
├── unittest-warning.sh
├── update-requirements.sh
├── utils.py
5 directories, 30 files
- Creating final debian package :
grep: debian/control: No such file or directory
/usr/bin/pkgsanitychecks: Error: not in source package directory
/usr/bin/pkgstripfiles: Error: not in source package directory
dpkg-deb: building package in '/home/gayett/Workspace/foo/debian/my-foo-local-1.0.deb'.
- Final result : OK (0)
- Debian package :
-rw-r--r-- 1 gayett ug-all 52K févr. 8 13:02 /home/gayett/Workspace/foo/debian/my-local-1.0.deb
/home/gayett/Workspace/foo/debian/my-local-1.0.deb: Debian binary package (format 2.0), with control.tar.zs,
data compression zst
- Dumping metadata :
new Debian package, version 2.0.
size 52340 bytes: control archive=553 bytes.
213 bytes, 8 lines * control
345 bytes, 16 lines * postinst
14 bytes, 2 lines * postrm
196 bytes, 9 lines * preinst
117 bytes, 5 lines * prerm
Package: foo
Version: 1.0
Section: base
Priority: optional
Architecture: all
Maintainer: Thierry GAYET <thierry.gayet@toto.com>
Description: Source code of the foo appliance
Homepage: https://www.toto.com
- Dumping content :
drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./
drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/
drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/
drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/foo/
drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/foo/__pycache__/
-rw-r--r-- gayett/ug-all 659 2024-02-08 13:02 ./opt/toto/foo/__pycache__/singleton.cpython-310.pyc
-rwxr-xr-x gayett/ug-all 48905 2024-02-08 13:02 ./opt/toto/foo/app.py
-rwxr-xr-x gayett/ug-all 18150 2024-02-08 13:02 ./opt/toto/foo/config.py
-rwxr-xr-x gayett/ug-all 23416 2024-02-08 13:02 ./opt/toto/foo/ffmpeg.py
-rwxr-xr-x gayett/ug-all 8148 2024-02-08 13:02 ./opt/toto/foo/gpu.py
-rwxr-xr-x gayett/ug-all 5168 2024-02-08 13:02 ./opt/toto/foo/instance.py
-rwxr-xr-x gayett/ug-all 5470 2024-02-08 13:02 ./opt/toto/foo/logger.py
-rwxr-xr-x gayett/ug-all 21945 2024-02-08 13:02 ./opt/toto/foo/multicast.py
-rwxr-xr-x gayett/ug-all 5789 2024-02-08 13:02 ./opt/toto/foo/pattern.py
-rwxr-xr-x gayett/ug-all 7547 2024-02-08 13:02 ./opt/toto/foo/rabbit.py
-rwxr-xr-x gayett/ug-all 574 2024-02-08 13:02 ./opt/toto/foo/requirements.txt
-rwxr-xr-x gayett/ug-all 14089 2024-02-08 13:02 ./opt/toto/foo/route.py
-rwxr-xr-x gayett/ug-all 5466 2024-02-08 13:02 ./opt/toto/foo/service.py
-rwxr-xr-x gayett/ug-all 1608 2024-02-08 13:02 ./opt/toto/foo/singleton.py
-rwxr-xr-x gayett/ug-all 27434 2024-02-08 13:02 ./opt/toto/foo/synchro.py
-rwxr-xr-x gayett/ug-all 10527 2024-02-08 13:02 ./opt/toto/foo/threadManager.py
-rwxr-xr-x gayett/ug-all 995 2024-02-08 13:02 ./opt/toto/foo/unittest-critical.sh
-rwxr-xr-x gayett/ug-all 1314 2024-02-08 13:02 ./opt/toto/foo/unittest-debug.sh
-rwxr-xr-x gayett/ug-all 1020 2024-02-08 13:02 ./opt/toto/foo/unittest-error.sh
-rwxr-xr-x gayett/ug-all 991 2024-02-08 13:02 ./opt/toto/foo/unittest-info.sh
-rwxr-xr-x gayett/ug-all 994 2024-02-08 13:02 ./opt/toto/foo/unittest-warning.sh
-rwxr-xr-x gayett/ug-all 240 2024-02-08 13:02 ./opt/toto/foo/update-requirements.sh
-rwxr-xr-x gayett/ug-all 26563 2024-02-08 13:02 ./opt/toto/foo/utils.py
-rw-r--r-- gayett/ug-all 2226 2024-02-08 13:02 ./opt/toto/foo/foo-probe-config.yml
-rwxr-xr-x gayett/ug-all 122488 2024-02-08 13:02 ./opt/toto/foo/foo.py
-rw-r--r-- 1 gayett ug-all 42K nov. 20 17:37 /home/gayett/Workspace/foo/debian/my-foo-1.0.deb
-rw-r--r-- 1 gayett ug-all 52K févr. 8 13:02 /home/gayett/Workspace/foo/debian/my-local-1.0.deb
Example of CI script (bitbucket)
#!/bin/bash
# debian/release.sh
# ##############
#
# Package for debian system
# shellcheck disable=SC2039,SC2002,SC2005
current_path=$(dirname "$0")
exit_code=0
# shellcheck source=debian/release.sh
. "${current_path}/../tools/debug.sh"
# shellcheck source=debian/release.sh
. "${current_path}/../tools/color.sh"
##
# Step 0: Define varaible env if not settings
#
if [ -z "${BPL_DEB_PACKAGE_NAME}" ]; then
echo -e "${RED}Missing variable environment BPL_DEB_PACKAGE_NAME !${NC}"
exit_code=1
fi
if [ -z "${BPL_DEB_PACKAGE_PATH}" ]; then
echo -e "${RED}Missing variable environment BPL_DEB_PACKAGE_PATH !${NC}"
exit_code=1
fi
if [ -z "${BPL_DEB_PACKAGE_DESC}" ]; then
BPL_DEB_PACKAGE_DESC="Dazzl debian pacakges."
fi
BRANCH=$(echo "$(echo "${BITBUCKET_BRANCH}" | tr '[:upper:]' '[:lower:]')" | sed -r 's/[/,;]+/-/g')
if [ "${exit_code}" != "0" ]; then
exit ${exit_code}
fi
##
# Step 1: Add system package
##
# apk add --update 
apt update && apt install -y 
dpkg tar jq tree httpie
NUM="$(cat package.json | jq .version)"
VERSION=${NUM//"}
PKG_DEBIAN="pkg-debian"
PACKAGE_DELIVERY="${PKG_DEBIAN}${BPL_DEB_PACKAGE_PATH}"
PACKAGE_DELIVERY_DEBIAN="${PKG_DEBIAN}/DEBIAN"
NAME_PACKAGE=$(echo "${BPL_DEB_PACKAGE_NAME}.${BRANCH}.${VERSION}.deb" | sed -r 's/[/,;]+/_/g')
##
# Step 2: Prepare PACKAGE_DELIVERY output
##
mkdir -p "${PACKAGE_DELIVERY}" "${PACKAGE_DELIVERY_DEBIAN}"
cp -r dist/* "${PACKAGE_DELIVERY}"
##
# Step 3: Generate info about package
##
cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/control
Package: my-${BPL_DEB_PACKAGE_NAME}-${BRANCH}
Version: ${VERSION}
Section: base
Priority: optional
Architecture: all
Maintainer: xxxxx@toto.com
Description: ${BPL_DEB_PACKAGE_DESC}
Homepage: https://dazzl.tv
EOF
##
# Step 4: Create all hooks to package
##
cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/preinst
#
# preinst
#
EOF
cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/postinst
#
# postinst
#
EOF
cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/prerm
#
# prerm
#
EOF
cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/postrm
#
# postrm
#
EOF
##
# Step 5: Change right to files
##
echo "Pacakge Delivery Debian : ${PACKAGE_DELIVERY_DEBIAN}"
chmod 755 "${PACKAGE_DELIVERY_DEBIAN}"
chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/postinst"
chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/postrm"
chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/preinst"
chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/prerm"
chmod 755 "${PACKAGE_DELIVERY}"
if [ "${BPL_DEBUG}" = "true" ]; then
tree $PKG_DEBIAN
fi
##
# Step 6: Create package '.deb'
##
echo "dpkg-deb --verbose --build ${PKG_DEBIAN} ${NAME_PACKAGE}"
dpkg-deb --verbose --build "${PKG_DEBIAN}" "${NAME_PACKAGE}"
##
# Step 7: Remove package to packagecloud.io
##
if [ "${BITBUCKET_BRANCH}" != 'develop' ] && [ "${BITBUCKET_BRANCH}" != 'staging' ] && [ "${BITBUCKET_BRANCH}" != 'master' ] ; then
versions=("xenial" "bionic" "focal")
# Remove actual package
for ver in "${versions[@]}"; do
http DELETE "https://${PACKAGE_CLOUD_TOKEN}:@packagecloud.io/api/v1/repos/dazzltv/debpkg/ubuntu/${ver}/${NAME_PACKAGE}"
done
fi
# Step 8 : upload the new debian package
More tools
The dpkg tools can be used for managing (install, extract content, … ) :
$ dpkg -c ./test_2.0.0_amd64.deb
drwxr-xr-x root/root 0 2015-06-27 19:00 ./
drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/
drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/bin/
-rwxr-xr-x root/root 44790352 2015-06-27 19:00 ./usr/bin/test
drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/
drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/doc/
drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/doc/test/
-rw-r--r-- root/root 148 2015-06-27 18:45 ./usr/share/doc/test/changelog.gz
-rw-r--r-- root/root 33 2015-06-27 18:44 ./usr/share/doc/test/copyright
A debian package is just an ar archive. To extract data from a deb package, use the command ar with the -x flag:
$ ar -x ./test_2.0.0_amd64.deb
$ ls
control.tar.gz data.tar.gz debian-binary test_2.0.0_amd64.deb
$ tar -xzf control.tar.gz
$ tar -xzf data.tar.gz
$ dpkg-deb -x ./path/to/test.deb ./path/to/destination
$ dpkg -x ./test_2.0.0_amd64.deb .
The alien tool can be use to change the format :
Man : https://manpages.ubuntu.com/manpages/trusty/man1/alien.1p.html
$ sudo add-apt-repository universe
$ sudo apt update
$ sudo apt install alien
To convert an RPM package to DEB:
sudo alien --d file.rpm
sudo alien --to-deb file.rpm
DEB to RPM:
sudo alien -r file.deb
sudo alien --to-rpm file.deb
DEB to TAR.GZ:
sudo alien -t file.deb
sudo alien --to-tgz file.deb

how to generate debian package from scratch

  • 1.
    How to makedebian package from scratch Thierry GAYET
  • 2.
    Example of adirectories : ● my-package/ is the top-level directory for your package. ● DEBIAN/ is where you place control files and scripts. ● usr/ is where you place files that will be installed on the target system. Structure of a debian package
  • 3.
    Inside the DEBIAN/directory, create a control file with package metadata. For example: Place the binary or files you want to package into the appropriate directories. In this example, we have an executable named my-executable in usr/bin/. You can customize the package further by adding pre-installation and post-installation scripts, defining dependencies, and more in the DEBIAN/control file. Help : https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles Structure of a debian package
  • 4.
    gayett@DES126 ~ cd/var/cache/apt/archives gayett@DES126 /var/cache/apt/archives ls -al total 810980 drwxr-xr-x 3 root root 36 janv. 18 06:25 . drwxr-xr-x 3 root root 5 janv. 18 14:42 .. -rw-r--r-- 1 root root 49148 déc. 14 16:41 alacarte_3.44.1-1ubuntu0.1_all.deb -rw-r--r-- 1 root root 354598 déc. 12 08:27 dnsmasq-base_2.86-1.1ubuntu0.4_amd64.deb -rw-r--r-- 1 root root 210160 mars 24 2022 gir1.2-gtk-2.0_2.24.33-2ubuntu2_amd64.deb -rw-r--r-- 1 root root 104953176 déc. 19 22:58 google-chrome-stable_120.0.6099.129-1_amd64.deb -rw-r--r-- 1 root root 105001444 janv. 3 00:33 google-chrome-stable_120.0.6099.199-1_amd64.deb -rw-r--r-- 1 root root 105001328 janv. 9 00:39 google-chrome-stable_120.0.6099.216-1_amd64.deb -rw-r--r-- 1 root root 105000828 janv. 12 21:33 google-chrome-stable_120.0.6099.224-1_amd64.deb -rw-r--r-- 1 root root 47836 oct. 21 2022 libgdk-pixbuf-2.0-dev_2.42.8+dfsg-1ubuntu0.2_amd64.deb -rw-r--r-- 1 root root 777594 mars 24 2022 libgtk2.0-dev_2.24.33-2ubuntu2_amd64.deb -rw-r--r-- 1 root root 1476 avril 8 2022 libjpeg8-dev_8c-2ubuntu10_amd64.deb -rw-r--r-- 1 root root 1472 avril 8 2022 libjpeg-dev_8c-2ubuntu10_amd64.deb -rw-r--r-- 1 root root 256872 févr. 21 2022 libjpeg-turbo8-dev_2.1.2-0ubuntu1_amd64.deb -rw-r--r-- 1 root root 314818 nov. 23 22:04 libtiff-dev_4.3.0-6ubuntu0.7_amd64.deb -rw-r--r-- 1 root root 1756002 déc. 8 14:33 libvirt0_8.0.0-1ubuntu7.8_amd64.deb -rw-r--r-- 1 root root 411316 déc. 8 14:33 libvirt-daemon_8.0.0-1ubuntu7.8_amd64.deb -rw-r--r-- 1 root root 747132 déc. 8 14:33 libvirt-daemon-driver-qemu_8.0.0-1ubuntu7.8_amd64.deb -rw-r--r-- 1 root root 263051680 déc. 15 16:12 linux-firmware_20220329.git681281e4-0ubuntu3.24_all.deb gayett@DES126 /var/cache/apt/archives file teamviewer_15.49.2_amd64.deb teamviewer_15.49.2_amd64.deb: Debian binary package (format 2.0), with control.tar.xz, data compression xz
  • 5.
  • 6.
    - You mustbe on a debian/ubuntu Linux distribution of course - You need to have several packages : $ sudo apt install dpkg (ubuntu 22.04 LTS) Requirements
  • 7.
    Generation of adebian package Navigate to the parent directory containing the my-package folder and run the following dpkg-deb command to build the package: This will create a Debian package file named my-package.deb in the current directory. Manual : https://man7.org/linux/man-pages/man1/dpkg-deb.1.html Help : ● https://www.iodigital.com/nl/history/intracto/creating-debianubuntu-deb-packages
  • 8.
    Installation of adebian package You can now install the debian package using dpkg: To execute on the server to update! MANUAL : https://doc.ubuntu-fr.org/dpkg
  • 9.
  • 10.
    # Create themy-package (root directory) and the DEBIAN directory (for the metadata) $ mkdir -p my-package/DEBIAN # Create the content’s directory $ mkdir -p my-package/opt/ “ → opt” have been selected but we can choose freely any path ; it will installed into /opt in the final filesystem ! $ tree └── my-package/ # main folder of the package ├── DEBIAN/ # will contains the package’s metadata └── opt/ # will contains the content of the package
  • 11.
    # Go intothe my-package directory $ cd my-package/opt/ # pull your update at the root of the content’s directory $ git clone git@your_git_server.git $ tree └── my-package/ ├── DEBIAN/ └── opt/ └── my-daemon └── your_executable
  • 12.
    # go intothe my-package/DEBIAN directory $ cd my-package/DEBIAN/ # Generate info about package’s metadata cat <<- EOF > control Package: foo Version: 1.0 Section: base Priority: optional Architecture: all Maintainer: Thierry GAYET <thierry.gayet@toto.com> Description: Source code of the foo appliance Homepage: https://www.toto.com EOF Help : h ttps://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
  • 13.
    # Create PREand POST script to hook : $ cat <<- EOF > ./preinst # # preinst # EOF $ cat <<- EOF > ./postinst # # postinst # EOF $ cat <<- EOF > ./prerm # # prerm # EOF $ cat <<- EOF > ./postrm # # postrm # EOF → Customize all script for changing rights, restarting service(s), updating docker, ….
  • 14.
    # Change rightto the metadata’s files $ chmod -R 755 my-package/DEBIAN $ chmod 755 my-package/ $ tree └── my-package/ ├── DEBIAN/ ├── control ├── postinst ├── postrm ├── preinst └── prerm └── opt/ └── my-deamon/ └── your_executable
  • 15.
    # Go backin the directories : $ cd ../../ # Generate the debian package : # Package’s name : my-package-<branch>-<version>.deb # branch = main # version = 1.0 $ dpkg-deb --verbose --build ./my-package/ ./my-package-1.0.deb dpkg-deb: building package in 'my-package-1.0.deb'. # Enumerate all files : $ dpkg --contents ./my-package-1.0.deb drwxr-xr-x tgayet/tgayet 0 2023-10-28 20:06 ./ drwxrwxr-x tgayet/tgayet 0 2023-10-28 20:11 ./opt/ drwxrwxr-x tgayet/tgayet 0 2023-10-28 20:38 ./opt/my-daemon/ -rwxr-xr-x tgayet/tgayet 0 2023-10-28 20:38 ./opt/my-deamon/your_executable
  • 16.
    $ dpkg --info./my-package-1.0.deb new Debian package, version 2.0. size 696 bytes: control archive=359 bytes. 213 bytes, 8 lines * control 15 bytes, 2 lines * postinst 13 bytes, 2 lines * postrm 14 bytes, 2 lines * preinst 12 bytes, 2 lines * prerm Package: foo Version: 1.0 Section: base Priority: optional Architecture: all Maintainer: Thierry GAYET <thierry.gayet@toto.com> Description: Source code of the foo appliance Homepage: https://www.toto.com
  • 17.
    $ dpkg --field./my-package-1.0.deb Package: foo Version: 1.0 Section: base Priority: optional Architecture: all Maintainer: Thierry GAYET <thierry.gayet@toto.com> Description: Source code of the foo appliance Homepage: https://www.toto.com
  • 18.
    Second way usingdpkg- buildpackage
  • 19.
    - You mustbe on a debian/ubuntu Linux distribution of course - You need to have several packages : $ sudo apt-get install dpkg-dev debhelper build-essential fakeroot (ubuntu 22.04 LTS) Requirements
  • 20.
    Create the PackageDirectory Structure: You need to create a directory structure for your package. Here's a minimal example: package_name/ ├── debian/ │ ├── control └── source_code/ Replace package_name with the name of your package and source_code with the directory containing your source code.
  • 21.
    Create the ControlFile: Inside the debian directory, create a control file that contains metadata about your package. Here's a basic example: Source: package_name Section: misc Priority: optional Maintainer: Your Name <your.email@example.com> Build-Depends: debhelper (>= 12) Standards-Version: 4.5.0 Package: package_name Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A brief description of your package. Customize the fields according to your package's details.
  • 22.
    Build the Package:Use the dpkg-buildpackage command to build the Debian package. Ensure you are in the parent directory of the package_name directory: $ dpkg-buildpackage -rfakeroot -b This command will build the Debian package.
  • 23.
    Install the Package:After building the package, you can install it using dpkg: $ sudo dpkg -i ../package_name_1.0-1_all.deb Replace package_name_1.0-1_all.deb with the actual name of the generated .deb package file.
  • 24.
    Verify the Installation:To verify the installation, you can run: $ dpkg -l | grep package_name This should list the package as installed.
  • 25.
    Clean Up: Afteryou're done, you can remove the package: $ sudo dpkg -r package_name
  • 26.
  • 27.
    - You mustbe on a debian/ubuntu Linux distribution of course - You need to have several packages : $ sudo apt-get install dpkg-dev debhelper build-essential fakeroot dh-make (ubuntu 22.04 LTS) Requirements
  • 28.
    dh_make is atool that simplifies the process of creating Debian source packages from upstream source code. It sets up the basic packaging files and directory structure for you. Here's how to use dh_make to generate a Debian package. Create a Working Directory: Create a directory to work in, where you'll place the source code and package files. You can create a new directory, e.g., mypackage : $ mkdir mypackage $ cd mypackage Download or Place Source Code: Download the source code for the software you want to package or place it in the mypackage directory. The source code should be in a subdirectory within mypackage.
  • 29.
    Run dh_make: Runthe dh_make tool in the mypackage directory, specifying the type of software you're packaging. For example: $ dh_make -s -c gpl -f ../source_code.tar.gz ● -s: Use the single-binary option. ● -c gpl: Set the software's license (replace gpl with the appropriate license). ● -f ../source_code.tar.gz: Specify the path to the source code archive. Follow the prompts, including answering questions about the software's maintainer, email, and any other information required. Package Configuration: dh_make will generate packaging files and directories. You may need to make some adjustments, such as: ○ Modify the debian/control file to specify package dependencies, architecture, and other package details. ○ Place any additional scripts, patches, or configuration files in the debian directory. ○ Review and edit the debian/rules file if needed to customize the build process.
  • 30.
    Build the Package:Use debuild to build the package. This tool will handle the compilation, packaging, and other necessary steps. $ debuild -us -uc ○ -us: Do not sign the source package. ○ -uc: Do not sign the changes file. This command will create a .deb package and a source package in the parent directory. Install and Test: Install the generated Debian package using dpkg: sudo dpkg -i ../package_name_1.0-1_all.deb Replace package_name_1.0-1_all.deb with the actual name of the generated package file. Clean Up: After testing, you can remove the package: $ sudo dpkg -r package_name Submit to Debian Repository (Optional): If your package meets Debian's quality standards and licensing requirements, you can consider submitting it to the Debian repository. This process simplifies the initial setup for creating Debian packages, but further customization may be required based on the specific software you are packaging. Additionally, you should follow Debian packaging guidelines to ensure the quality and compatibility of your package.
  • 31.
    Demo for thefoo appliance
  • 32.
  • 33.
    $ clear &&./redo_deb.sh
  • 34.
    ______ ___________ __________ _ _ ___________ ___ _____ ___________ | _ ___| ___ | __ | ___| | || ___| ___ / _ _ _| _ | ___ | | | | |__ | |_/ / | | /| |__ | | || |__ | |_/ / /_ | | | | | | |_/ / | | | | __|| ___ | | __ | __|| || __|| /| _ || | | | | | / | |/ /| |___| |_/ / | |_ | |___| | || |___| | | | | || | _/ / | |___/ ____/____/ ____/____/_| _/____/_| __| |_/_/ ___/_| _| - Parameters : SRCDIR = '/home/gayett/Workspace/foo/src' DESTDIR = '/home/gayett/Workspace/foo/debian/delivery' PACKAGE_NAME = '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' ARCHITECTURE = 'amd64' - METADATA_DIR = '/home/gayett/Workspace/foo/debian/delivery/DEBIAN' - DATA_DIR = '/home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/' - Checking '/home/gayett/Workspace/foo/debian/delivery' directory : NOK - The final directory (/home/gayett/Workspace/foo/debian/delivery) already exist ! --> Do you want to revove it first? (Y/N): Y - Removing '/home/gayett/Workspace/foo/debian/delivery' directory : OK - Creating '/home/gayett/Workspace/foo/debian/delivery' directory : OK - Checking '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' debian package : NOK - The final debian package (/home/gayett/Workspace/foo/debian/my-local-1.0.deb) already exist !
  • 35.
    --> Do youwant to revove it first? (Y/N): Y - Removing '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' debian package : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN' directory : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/control' : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/preinst' : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/postinst' : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/prerm' : OK - Creating '/home/gayett/Workspace/foo/debian/delivery/DEBIAN/postrm' : OK /home/gayett/Workspace/foo/debian/delivery/DEBIAN ├── control ├── postinst ├── postrm ├── preinst └── prerm 0 directories, 5 files total 7,0K drwxr-xr-x 2 gayett ug-all 7 févr. 8 13:02 . drwxr-xr-x 3 gayett ug-all 3 févr. 8 13:02 .. -rwxr-xr-x 1 gayett ug-all 213 févr. 8 13:02 control -rwxr-xr-x 1 gayett ug-all 345 févr. 8 13:02 postinst -rwxr-xr-x 1 gayett ug-all 14 févr. 8 13:02 postrm -rwxr-xr-x 1 gayett ug-all 196 févr. 8 13:02 preinst
  • 36.
    -rwxr-xr-x 1 gayettug-all 117 févr. 8 13:02 prerm - Creating '/home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/' directory : OK total 231K drwxr-xr-x 3 gayett ug-all 27 févr. 2 13:07 . drwxr-xr-x 14 gayett ug-all 27 janv. 31 12:42 .. -rwxr-xr-x 1 gayett ug-all 48K janv. 31 12:39 app.py -rwxr-xr-x 1 gayett ug-all 18K févr. 2 13:04 config.py -rwxr-xr-x 1 gayett ug-all 23K févr. 2 13:05 ffmpeg.py -rwxr-xr-x 1 gayett ug-all 8,0K janv. 22 16:45 gpu.py -rwxr-xr-x 1 gayett ug-all 5,1K déc. 18 10:55 instance.py -rwxr-xr-x 1 gayett ug-all 5,4K janv. 10 15:39 logger.py -rwxr-xr-x 1 gayett ug-all 22K déc. 11 18:02 multicast.py -rwxr-xr-x 1 gayett ug-all 5,7K nov. 17 16:26 pattern.py drwxr-xr-x 2 gayett ug-all 3 janv. 10 13:52 __pycache__ -rwxr-xr-x 1 gayett ug-all 7,4K nov. 17 16:26 rabbit.py -rwxr-xr-x 1 gayett ug-all 574 nov. 17 16:26 requirements.txt -rwxr-xr-x 1 gayett ug-all 14K nov. 24 18:01 route.py -rwxr-xr-x 1 gayett ug-all 5,4K janv. 22 11:41 service.py -rwxr-xr-x 1 gayett ug-all 1,6K nov. 17 16:26 singleton.py -rwxr-xr-x 1 gayett ug-all 27K janv. 31 12:40 synchro.py -rwxr-xr-x 1 gayett ug-all 11K déc. 14 16:09 threadManager.py -rwxr-xr-x 1 gayett ug-all 995 nov. 17 16:26 unittest-critical.sh
  • 37.
    -rwxr-xr-x 1 gayettug-all 1,3K nov. 22 09:12 unittest-debug.sh -rwxr-xr-x 1 gayett ug-all 1020 nov. 22 09:12 unittest-error.sh -rwxr-xr-x 1 gayett ug-all 991 nov. 17 16:26 unittest-info.sh -rwxr-xr-x 1 gayett ug-all 994 nov. 17 16:26 unittest-warning.sh -rwxr-xr-x 1 gayett ug-all 240 nov. 17 16:26 update-requirements.sh -rwxr-xr-x 1 gayett ug-all 26K févr. 2 13:06 utils.py -rw-r--r-- 1 gayett ug-all 2,2K janv. 23 15:15 foo-probe-config.yml -rwxr-xr-x 1 gayett ug-all 120K févr. 2 13:07 foo.py - Recopying data source from /home/gayett/Workspace/foo/src/ to /home/gayett/Workspace/foo/debian/delivery/opt/toto/foo/ OK (0) - Checking dpkg-deb package : OK Build directory : '/home/gayett/Workspace/foo/debian/delivery' Final package : '/home/gayett/Workspace/foo/debian/my-local-1.0.deb' Content : /home/gayett/Workspace/foo/debian/delivery ├── DEBIAN │ ├── control │ ├── postinst │ ├── postrm │ ├── preinst │ └── prerm └── opt
  • 38.
    └── foo └── my-deamon ├──app.py ├── config.py ├── ffmpeg.py ├── gpu.py ├── instance.py ├── logger.py ├── multicast.py ├── pattern.py ├── __pycache__ │ └── singleton.cpython-310.pyc ├── rabbit.py ├── requirements.txt ├── route.py ├── service.py ├── singleton.py ├── synchro.py ├── threadManager.py ├── unittest-critical.sh ├── unittest-debug.sh ├── unittest-error.sh ├── unittest-info.sh
  • 39.
    ├── unittest-warning.sh ├── update-requirements.sh ├──utils.py 5 directories, 30 files - Creating final debian package : grep: debian/control: No such file or directory /usr/bin/pkgsanitychecks: Error: not in source package directory /usr/bin/pkgstripfiles: Error: not in source package directory dpkg-deb: building package in '/home/gayett/Workspace/foo/debian/my-foo-local-1.0.deb'. - Final result : OK (0) - Debian package : -rw-r--r-- 1 gayett ug-all 52K févr. 8 13:02 /home/gayett/Workspace/foo/debian/my-local-1.0.deb /home/gayett/Workspace/foo/debian/my-local-1.0.deb: Debian binary package (format 2.0), with control.tar.zs, data compression zst - Dumping metadata : new Debian package, version 2.0. size 52340 bytes: control archive=553 bytes. 213 bytes, 8 lines * control
  • 40.
    345 bytes, 16lines * postinst 14 bytes, 2 lines * postrm 196 bytes, 9 lines * preinst 117 bytes, 5 lines * prerm Package: foo Version: 1.0 Section: base Priority: optional Architecture: all Maintainer: Thierry GAYET <thierry.gayet@toto.com> Description: Source code of the foo appliance Homepage: https://www.toto.com - Dumping content : drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./ drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/ drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/ drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/foo/ drwxr-xr-x gayett/ug-all 0 2024-02-08 13:02 ./opt/toto/foo/__pycache__/ -rw-r--r-- gayett/ug-all 659 2024-02-08 13:02 ./opt/toto/foo/__pycache__/singleton.cpython-310.pyc -rwxr-xr-x gayett/ug-all 48905 2024-02-08 13:02 ./opt/toto/foo/app.py -rwxr-xr-x gayett/ug-all 18150 2024-02-08 13:02 ./opt/toto/foo/config.py -rwxr-xr-x gayett/ug-all 23416 2024-02-08 13:02 ./opt/toto/foo/ffmpeg.py
  • 41.
    -rwxr-xr-x gayett/ug-all 81482024-02-08 13:02 ./opt/toto/foo/gpu.py -rwxr-xr-x gayett/ug-all 5168 2024-02-08 13:02 ./opt/toto/foo/instance.py -rwxr-xr-x gayett/ug-all 5470 2024-02-08 13:02 ./opt/toto/foo/logger.py -rwxr-xr-x gayett/ug-all 21945 2024-02-08 13:02 ./opt/toto/foo/multicast.py -rwxr-xr-x gayett/ug-all 5789 2024-02-08 13:02 ./opt/toto/foo/pattern.py -rwxr-xr-x gayett/ug-all 7547 2024-02-08 13:02 ./opt/toto/foo/rabbit.py -rwxr-xr-x gayett/ug-all 574 2024-02-08 13:02 ./opt/toto/foo/requirements.txt -rwxr-xr-x gayett/ug-all 14089 2024-02-08 13:02 ./opt/toto/foo/route.py -rwxr-xr-x gayett/ug-all 5466 2024-02-08 13:02 ./opt/toto/foo/service.py -rwxr-xr-x gayett/ug-all 1608 2024-02-08 13:02 ./opt/toto/foo/singleton.py -rwxr-xr-x gayett/ug-all 27434 2024-02-08 13:02 ./opt/toto/foo/synchro.py -rwxr-xr-x gayett/ug-all 10527 2024-02-08 13:02 ./opt/toto/foo/threadManager.py -rwxr-xr-x gayett/ug-all 995 2024-02-08 13:02 ./opt/toto/foo/unittest-critical.sh -rwxr-xr-x gayett/ug-all 1314 2024-02-08 13:02 ./opt/toto/foo/unittest-debug.sh -rwxr-xr-x gayett/ug-all 1020 2024-02-08 13:02 ./opt/toto/foo/unittest-error.sh -rwxr-xr-x gayett/ug-all 991 2024-02-08 13:02 ./opt/toto/foo/unittest-info.sh -rwxr-xr-x gayett/ug-all 994 2024-02-08 13:02 ./opt/toto/foo/unittest-warning.sh -rwxr-xr-x gayett/ug-all 240 2024-02-08 13:02 ./opt/toto/foo/update-requirements.sh -rwxr-xr-x gayett/ug-all 26563 2024-02-08 13:02 ./opt/toto/foo/utils.py -rw-r--r-- gayett/ug-all 2226 2024-02-08 13:02 ./opt/toto/foo/foo-probe-config.yml -rwxr-xr-x gayett/ug-all 122488 2024-02-08 13:02 ./opt/toto/foo/foo.py -rw-r--r-- 1 gayett ug-all 42K nov. 20 17:37 /home/gayett/Workspace/foo/debian/my-foo-1.0.deb -rw-r--r-- 1 gayett ug-all 52K févr. 8 13:02 /home/gayett/Workspace/foo/debian/my-local-1.0.deb
  • 42.
    Example of CIscript (bitbucket)
  • 43.
    #!/bin/bash # debian/release.sh # ############## # #Package for debian system # shellcheck disable=SC2039,SC2002,SC2005 current_path=$(dirname "$0") exit_code=0 # shellcheck source=debian/release.sh . "${current_path}/../tools/debug.sh" # shellcheck source=debian/release.sh . "${current_path}/../tools/color.sh" ## # Step 0: Define varaible env if not settings # if [ -z "${BPL_DEB_PACKAGE_NAME}" ]; then echo -e "${RED}Missing variable environment BPL_DEB_PACKAGE_NAME !${NC}" exit_code=1 fi if [ -z "${BPL_DEB_PACKAGE_PATH}" ]; then echo -e "${RED}Missing variable environment BPL_DEB_PACKAGE_PATH !${NC}"
  • 44.
    exit_code=1 fi if [ -z"${BPL_DEB_PACKAGE_DESC}" ]; then BPL_DEB_PACKAGE_DESC="Dazzl debian pacakges." fi BRANCH=$(echo "$(echo "${BITBUCKET_BRANCH}" | tr '[:upper:]' '[:lower:]')" | sed -r 's/[/,;]+/-/g') if [ "${exit_code}" != "0" ]; then exit ${exit_code} fi ## # Step 1: Add system package ## # apk add --update apt update && apt install -y dpkg tar jq tree httpie NUM="$(cat package.json | jq .version)" VERSION=${NUM//"} PKG_DEBIAN="pkg-debian" PACKAGE_DELIVERY="${PKG_DEBIAN}${BPL_DEB_PACKAGE_PATH}" PACKAGE_DELIVERY_DEBIAN="${PKG_DEBIAN}/DEBIAN" NAME_PACKAGE=$(echo "${BPL_DEB_PACKAGE_NAME}.${BRANCH}.${VERSION}.deb" | sed -r 's/[/,;]+/_/g')
  • 45.
    ## # Step 2:Prepare PACKAGE_DELIVERY output ## mkdir -p "${PACKAGE_DELIVERY}" "${PACKAGE_DELIVERY_DEBIAN}" cp -r dist/* "${PACKAGE_DELIVERY}" ## # Step 3: Generate info about package ## cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/control Package: my-${BPL_DEB_PACKAGE_NAME}-${BRANCH} Version: ${VERSION} Section: base Priority: optional Architecture: all Maintainer: xxxxx@toto.com Description: ${BPL_DEB_PACKAGE_DESC} Homepage: https://dazzl.tv EOF ## # Step 4: Create all hooks to package ## cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/preinst # # preinst # EOF
  • 46.
    cat <<- EOF> ${PACKAGE_DELIVERY_DEBIAN}/postinst # # postinst # EOF cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/prerm # # prerm # EOF cat <<- EOF > ${PACKAGE_DELIVERY_DEBIAN}/postrm # # postrm # EOF ## # Step 5: Change right to files ## echo "Pacakge Delivery Debian : ${PACKAGE_DELIVERY_DEBIAN}" chmod 755 "${PACKAGE_DELIVERY_DEBIAN}" chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/postinst" chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/postrm" chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/preinst" chmod 755 "${PACKAGE_DELIVERY_DEBIAN}/prerm" chmod 755 "${PACKAGE_DELIVERY}" if [ "${BPL_DEBUG}" = "true" ]; then tree $PKG_DEBIAN fi
  • 47.
    ## # Step 6:Create package '.deb' ## echo "dpkg-deb --verbose --build ${PKG_DEBIAN} ${NAME_PACKAGE}" dpkg-deb --verbose --build "${PKG_DEBIAN}" "${NAME_PACKAGE}" ## # Step 7: Remove package to packagecloud.io ## if [ "${BITBUCKET_BRANCH}" != 'develop' ] && [ "${BITBUCKET_BRANCH}" != 'staging' ] && [ "${BITBUCKET_BRANCH}" != 'master' ] ; then versions=("xenial" "bionic" "focal") # Remove actual package for ver in "${versions[@]}"; do http DELETE "https://${PACKAGE_CLOUD_TOKEN}:@packagecloud.io/api/v1/repos/dazzltv/debpkg/ubuntu/${ver}/${NAME_PACKAGE}" done fi # Step 8 : upload the new debian package
  • 48.
  • 49.
    The dpkg toolscan be used for managing (install, extract content, … ) : $ dpkg -c ./test_2.0.0_amd64.deb drwxr-xr-x root/root 0 2015-06-27 19:00 ./ drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/ drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/bin/ -rwxr-xr-x root/root 44790352 2015-06-27 19:00 ./usr/bin/test drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/ drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/doc/ drwxr-xr-x root/root 0 2015-06-27 19:00 ./usr/share/doc/test/ -rw-r--r-- root/root 148 2015-06-27 18:45 ./usr/share/doc/test/changelog.gz -rw-r--r-- root/root 33 2015-06-27 18:44 ./usr/share/doc/test/copyright A debian package is just an ar archive. To extract data from a deb package, use the command ar with the -x flag: $ ar -x ./test_2.0.0_amd64.deb $ ls control.tar.gz data.tar.gz debian-binary test_2.0.0_amd64.deb $ tar -xzf control.tar.gz $ tar -xzf data.tar.gz $ dpkg-deb -x ./path/to/test.deb ./path/to/destination $ dpkg -x ./test_2.0.0_amd64.deb .
  • 50.
    The alien toolcan be use to change the format : Man : https://manpages.ubuntu.com/manpages/trusty/man1/alien.1p.html $ sudo add-apt-repository universe $ sudo apt update $ sudo apt install alien To convert an RPM package to DEB: sudo alien --d file.rpm sudo alien --to-deb file.rpm DEB to RPM: sudo alien -r file.deb sudo alien --to-rpm file.deb DEB to TAR.GZ: sudo alien -t file.deb sudo alien --to-tgz file.deb