Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions func-mapper-deb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

# shell variables
SHELL := /bin/bash # use this instead of /bin/sh
DATE := $(shell date -u +"%Y-%m-%d")
PWD := $(shell pwd)
DISTRO := $(shell lsb_release -cs)

# Development only variables
DEV_VENV_PATH := ~/funcmapper/venv


# Get the build/release version
ifdef PKG_VERSION
PKG_VERSION := $(PKG_VERSION)
else
PKG_VERSION := 0.0.1-0
endif

# program name
PERIODIC_PRINTER = periodicprinter

# directory containing the final debian file (this can be relative or absolute, default is '..')
DEB_OUT_DIR = dist

# Package Info
PKG_USER = funkuser
PKG_NAME = funkpkg

# Install locations
PATH_PKG_LOGS = /var/log/funcmapper
PKG_USER = funcmapper # note: this same as debian/funkpkg.sysuser
PKG_SERVICE = funcmapper
PY_INSTALL_SUFFIX = funcmapper

# exports
export DEB_OUT_DIR
export PATH_PKG_LOGS
export PKG_SERVICE
export PKG_USER
export PY_INSTALL_SUFFIX

# Makefile
.PHONY: all test clean deb-clean format lint deb install dev-setup
all: clean ${PERIODIC_PRINTER}

clean: deb-clean wheel-clean
-rm -rf .tox

# setup a development virtualenv
dev-setup:
# setup a virtualenv
python3 -m venv ${DEV_VENV_PATH}
${DEV_VENV_PATH}/bin/pip3 install -r ${MKFILE_DIR}/requirements.txt
${DEV_VENV_PATH}/bin/pip3 install -r ${MKFILE_DIR}/test_requirements.txt

# test the code
test:
tox --recreate

# wheel
wheel: wheel-clean wheel-build wheel-inspect

wheel-clean:
-rm -rf dist/*.whl

wheel-build:
python3 setup.py -q bdist_wheel

wheel-inspect:
echo WHEELCONTENTS:START
cp -v dist/${PKG_NAME}*.whl dist/package.zip
unzip -l dist/package.zip
echo WHEELCONTENTS:END


# debian building
# note: we create a deb changelog here because it's an example. Ideally, the changelog file should be only incremented with `dch -i`
deb: deb-clean deb-changelog-create deb-build

deb-clean:
-rm -f dist/*.deb
-rm -fv dist/*
-rm -rf debian/${PKG_NAME}
-rm -rf debian/.debhelper/

deb-clean-changelog:
-rm -f debian/changelog

deb-changelog-create: deb-clean-changelog
dch --create --package ${PKG_NAME} -D ${DISTRO} -v ${PKG_VERSION} "Release: ${PKG_VERSION}"

deb-build:
# check build deps
dpkg-checkbuilddeps
# build
# --buildinfo-option is passed to dpkg-genbuildinfo
# --changes-option is passed to dpkg-genchanges
# dpkg-buildpackage --unsigned-source --unsigned-changes --buildinfo-option="-u${DEB_OUT_DIR}" --changes-option="-u${DEB_OUT_DIR}"
dpkg-buildpackage --unsigned-source --unsigned-changes

buildcontainer:
docker build -t ppbuilder .
docker run --rm --volume "${PWD}:/pkgbuilddir" --workdir="/pkgbuilddir" -it ppbuilder
29 changes: 29 additions & 0 deletions func-mapper-deb/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Simple Debian Packaging

A basic example of debian packaging with dh-sysuser (to create a user).

```sh
# Use docker to build container (it contains all build dependencies)
# (for ease of use, it's a make command shortcut)
make buildcontainer

# make the debian
make deb

# check the contents of the debian
dpkg --contents ../*.deb
dpkg -I ../*.deb

# install the deb on the target machine (example)
apt install -y ../periodicprinterpkg_0.0.1-0_amd64.deb
```

## Note for Windows Docker users
Please make sure that you are using `LF` line ending and not `CRLF` for *all* files in `debian/` directory, otherwise, you will run into errors.

Example error (or `postinst` failures):
```
: No such file or directory
cc -o .o
cc: fatal error: no input files
```
1 change: 1 addition & 0 deletions func-mapper-deb/debian/compat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
13
12 changes: 12 additions & 0 deletions func-mapper-deb/debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Source: funkpkg
Section: unknown
Maintainer: Muzammil Abdul Rehman <example.email@foo.com>
Build-Depends: debhelper (>=13), dh-sysuser
Standards-Version: 4.0.0
Homepage: github.com/muzammilar

Package: funkpkg
Architecture: any
Pre-Depends: ${misc:Pre-Depends}
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: funcmapper is an example python project
9 changes: 9 additions & 0 deletions func-mapper-deb/debian/funkpkg.funcmapper.logrotate
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/var/log/funcmapper/*.log
{
maxsize 5M
weekly
rotate 5
compress
notifempty
missingok
}
21 changes: 21 additions & 0 deletions func-mapper-deb/debian/funkpkg.funcmapper.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[Unit]
Description=Sample Mapping Function.
ConditionPathExists=/opt/venv/funcmapper/bin/funk
# make sure we have network connectivity (not that this program needs it)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# user and group
User=funkuser
Group=funkuser
TimeoutStartSec=45
TimeoutStopSec=75
ExecStart=/opt/venv/funcmapper/bin/funk
# restart service on failures
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target
19 changes: 19 additions & 0 deletions func-mapper-deb/debian/funkpkg.postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
set -xe

# Add the marker for postinst scripts generated by debhelpers (i.e. systemd and sysuser in this case).
# See the following for state diagrams of pre/postinst scripts: https://wiki.debian.org/MaintainerScripts
# See the manpages of dh_installdeb for details: https://manpages.ubuntu.com/manpages/jammy/en/man1/dh_installdeb.1.html

#DEBHELPER#

# Add user-defined postinst script.
# Change ownership of the logs directory to the user

if [ "$1" = "configure" ] || [ "$1" = "abort-remove" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] ; then

# create a logs directory (and set ownership)
mkdir -p #ENV.PATH_PKG_LOGS#
chown -R #ENV.PKG_USER# #ENV.PATH_PKG_LOGS#

fi
1 change: 1 addition & 0 deletions func-mapper-deb/debian/funkpkg.sysuser
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
funkuser
36 changes: 36 additions & 0 deletions func-mapper-deb/debian/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/make -f

# We check distribution here because Makefile can contain linting and tests which don't need distro name
DISTRO := $(shell lsb_release -cs)

ifndef DISTRO
$(error DISTRO is not set, make sure you have `lsb-release` package installed)
endif

ifndef PKG_NAME
$(error PKG_NAME is not set, should be exported by project Makefile)
endif

# use verbose logging to easily debug builds
DH_VERBOSE = 1

# set the root path for dh-virtualenv
export DH_VIRTUALENV_INSTALL_ROOT=/opt/venv

# dh-sysuser for creating a user (when package is installed)
# dh-virtualenv creates a debian package for python
%:
dh $@ --with sysuser,python-virtualenv --python=/usr/bin/python3 --install-suffix ${PY_INSTALL_SUFFIX}

# override the output directory of the binary to be `dist` instead of `..`
# Note that providing an explicit filename doesn't work when there are more than one debs
override_dh_builddeb:
dh_builddeb --destdir=dist/ --filename=${PKG_NAME}

# install systemd service file. Use a different name from the package itself
override_dh_installsystemd:
dh_installsystemd --name=${PKG_SERVICE}

# add logrotate support to the package
override_dh_installlogrotate:
dh_installlogrotate --name=${PKG_SERVICE}
10 changes: 10 additions & 0 deletions func-mapper-deb/dev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/path/to/funcmapper/virtualenv/bin/python
"""
An entry point for testing funcmapper in local development setup.
"""

import funcmapper

# This function is mostly used for local testing of the funcmapper code
if __name__ == "__main__":
funcmapper.funk.main()
2 changes: 2 additions & 0 deletions func-mapper-deb/funcmapper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

from . import funk
11 changes: 11 additions & 0 deletions func-mapper-deb/funcmapper/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""A list of functions to be mapped"""


def rails(name: str, length: str) -> str:
pass

def cylinders(name: str, length: str, diamter: str = None) -> str:
pass

def oranges(**kwargs):
pass
10 changes: 10 additions & 0 deletions func-mapper-deb/funcmapper/funk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import funcmapper.maps as funkmap

def main():
mappers = [
("rails", "inter-gelactic", "62 inches", "", "other")
]

for func, first, second, *_ in mappers:
print(funkmap.maps[func](first, second))
40 changes: 40 additions & 0 deletions func-mapper-deb/funcmapper/logger/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Setup handlers for basic logging"""

import logging


def get_logger(loggername: str) -> logging.Logger:
"""Either create a new logger or gets an existing logger for a given name

:param str loggername: user defined unique ID of the logger
:return logging.Logger: logging handler
"""
return logging.getLogger(loggername)


def configure_file_logging(loggername: str, loglevel: str = "debug",
logfilepath: str = "/tmp/funkmapper.log"):
"""Sets up a basic logging configuration using a watched file handler

:param str loggername: user defined unique ID of the logger
:param str loglevel: user defined logging level, defaults to "debug"
:param str logfilepath: the absolute path of the logfile, defaults to "/tmp/funkmapper.log"
"""
formatter = logging.Formatter("%(asctime)s {%(pathname)s:%(lineno)d} "
"[%(funcName)s] %(levelname)s - %(message)s")

# get/get a logger
logger = get_logger(loggername)

# remove logger if it already exits to prevent dual write
for handler in logger.handlers:
logger.removeHandler(handler)
handler.close() # remove the handler (and the files)

# Write to file
logfile_handler = logging.handlers.WatchedFileHandler(logfilepath)
logfile_handler.setFormatter(formatter)

# set logging level
logger.setLevel(logging.getLevelName(loglevel.upper()))
logger.addHandler(logfile_handler)
8 changes: 8 additions & 0 deletions func-mapper-deb/funcmapper/maps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

from funcmapper import functions as funks

maps = {
"rails": funks.rails,
"cylinders": funks.cylinders,
"oranges": funks.oranges,
}
5 changes: 5 additions & 0 deletions func-mapper-deb/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[pytest]
markers =
unit: mark a test as a unit test.
integration: mark a test as an integration.
dev: mark a test for development testing.
1 change: 1 addition & 0 deletions func-mapper-deb/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests>2.18,<3.0 # python requests library
41 changes: 41 additions & 0 deletions func-mapper-deb/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os
from setuptools import find_packages
from setuptools import setup

#NOTE: Using setup.py is the legacy format. It's better to use setup.ini
# since that avoids the circular dependency issue for wheel building

PACKAGE_NAME = "funkpkg"
LICENSE_NAME = "MIT"

def version():
if "PKG_VERSION" in os.environ and os.environ["PKG_VERSION"]:
return os.environ["PKG_VERSION"]
return "0.0.1-0"

setup(
name=PACKAGE_NAME,
version=version(),
description="Function Mapping Example",
long_description="""Fake Long Description.""",
url="https://example.com",
author="Muzammil Abdul Rehman",
author_email="foo@bar.com",
license=LICENSE_NAME,
classifiers=[
"Development Status :: 1",
"Programming Language :: Python :: 3",
],
install_requires=[
"requests>2.18,<3.0"
],
package_dir={"funcmapper": "funcmapper"},
packages=find_packages(),
include_package_data=True,
data_files=[],
entry_points={
"console_scripts": [
"funk=funcmapper.funk:main",
]
},
)
1 change: 1 addition & 0 deletions func-mapper-deb/test_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest~=7.2
10 changes: 10 additions & 0 deletions func-mapper-deb/tests/test_funk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Test Fuction Mapping"""

import pytest

# Mark this file as unit testing only
mark = pytest.mark.unit

def test_funk():
"""Basic Funk Testing"""
pass