Debian packaging; Fix crash when templating multiple tokens

This commit is contained in:
s3lph 2019-11-26 14:24:53 +01:00
parent a8d04afb01
commit e65d8ddc5c
18 changed files with 181 additions and 17 deletions

View file

@ -1,5 +1,5 @@
--- ---
image: python:3.8 image: s3lph/spaceapi-server-ci:20191126-01
stages: stages:
- test - test
@ -8,7 +8,6 @@ stages:
before_script: before_script:
- pip3 install coverage pycodestyle
- export SPACEAPI_SERVER_VERSION=$(python -c 'import spaceapi_server; print(spaceapi_server.__version__)') - export SPACEAPI_SERVER_VERSION=$(python -c 'import spaceapi_server; print(spaceapi_server.__version__)')
@ -41,3 +40,65 @@ build_wheel:
- dist/SHA256SUMS - dist/SHA256SUMS
only: only:
- tags - tags
build_debian:
stage: build
script:
- find package/debian -name .gitkeep -delete
# Copy example plugin
- install -m0644 examples/plugins/example.py package/debian/spaceapi-server/etc/spaceapi-server/plugins/example.py
# Create control
- |
cat > package/debian/spaceapi-server/DEBIAN/control <<EOF
Package: spaceapi-server
Version: ${SPACEAPI_SERVER_VERSION}
Maintainer: s3lph <account-gitlab-ideynizv@kernelpanic.lol>
Section: web
Priority: optional
Architecture: all
Depends: python3 (>= 3.6), python3-jinja2, python3-bottle
Description: Lightweight SpaceAPI endpoint server
Lightweight server for SpaceAPI endpoints. Includes support for pluggable
templating, so dynamic content, like sensor values, can be added.
EOF
- chmod 0644 package/debian/spaceapi-server/DEBIAN/control
# Create changelog
- |
for version in "$(cat CHANGELOG.md | grep '<!-- BEGIN CHANGES' | cut -d ' ' -f 4)"; do
echo "spaceapi-server (${version}-1); urgency=medium\n" >> package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog
cat CHANGELOG.md | grep -A 1000 "<"'!'"-- BEGIN CHANGES ${version} -->" | grep -B 1000 "<"'!'"-- END CHANGES ${version} -->" | tail -n +2 | head -n -1 | sed -re 's/^-/ */g' >> package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog
echo "\n -- s3lph <account-gitlab-ideynizv@kernelpanic.lol> $(date -R)\n" >> package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog
done
- gzip -9n package/debian/spaceapi-server/usr/share/doc/spaceapi-server/changelog
# Copy license
- install -m0644 LICENSE package/debian/spaceapi-server/usr/share/doc/spaceapi-server/copyright
# Install spaceapi-server into package root
- python3 setup.py egg_info install --root=package/debian/spaceapi-server/ --prefix=/usr --optimize=1
- cd package/debian/spaceapi-server
- mkdir -p usr/lib/python3/dist-packages/
- rsync -a usr/lib/python3.8/site-packages/spaceapi_server usr/lib/python3/dist-packages/spaceapi_server
- rm -rf usr/lib/python3.8/
# Remove compiled Python files
- find usr/lib/python3/dist-packages -name __pycache__ -exec rm -r {} \; 2>/dev/null || true
- find usr/lib/python3/dist-packages -name '*.pyc' -exec rm {} \;
# Move spaceapi-server binary to /usr/lib
- mv usr/bin/spaceapi-server usr/lib/spaceapi-server/spaceapi-server
- sed -re 's$#!/usr/local/bin/python3.*$#!/usr/bin/python3$' -i usr/lib/spaceapi-server/spaceapi-server
# Fix file permissions
- find . -type f -exec chmod 0644 {} \;
- find . -type d -exec chmod 755 {} \;
- chmod 0755 usr/lib/spaceapi-server/spaceapi-server DEBIAN/postinst DEBIAN/prerm DEBIAN/postrm
# Build the package
- cd ..
- dpkg-deb --build spaceapi-server
- mv spaceapi-server.deb "spaceapi-server_${SPACEAPI_SERVER_VERSION}-1_all.deb"
# Run lintian
- sudo -u nobody lintian --fail-on-warnings "spaceapi-server_${SPACEAPI_SERVER_VERSION}-1_all.deb"
# Generate checksum
- sha256sum *.deb > SHA256SUMS
artifacts:
paths:
- "package/debian/*.deb"
- package/debian/SHA256SUMS
only:
- tags

14
CHANGELOG.md Normal file
View file

@ -0,0 +1,14 @@
# SpaceAPI Server Changelog
<!-- BEGIN RELEASE v0.1 -->
## Version 0.1
First release.
### Changes
<!-- BEGIN CHANGES 0.1 -->
- First somewhat stable version.
<!-- END CHANGES 0.1 -->
<!-- END RELEASE v0.1 -->

View file

@ -91,7 +91,8 @@ its existence.
``` ```
Although the value for the `state` key is a string containing the Jinja2 template, the return value of your template Although the value for the `state` key is a string containing the Jinja2 template, the return value of your template
function is a complex data type, which will be inserted into the result as such. function is a complex data type, which will be inserted into the result as such. Please be aware that only the
first token of a templated string is used in the result. This limitation is caused by the way Jinja2 is (ab-) used.
3. Configure the server: 3. Configure the server:

View file

@ -12,7 +12,7 @@
}, },
"issue_report_channels": [ "issue_report_channels": [
"email" "email"
] ],
"state": "{#- You can write your own plugins for retrieving dynamic information -#} {{ our_space_state() }}", "state": "{#- You can write your own plugins for retrieving dynamic information -#} {{ our_space_state() }}",
"sensors": { "sensors": {
"people_now_present": "{{ our_sensor_backend('people_count') }}" "people_now_present": "{{ our_sensor_backend('people_count') }}"

6
package/Dockerfile Normal file
View file

@ -0,0 +1,6 @@
FROM python:3.8-buster as python
RUN apt update \
&& apt install -y --no-install-recommends \
python3-coverage python3-pycodestyle lintian rsync sudo \
&& rm -rf /var/cache/apt

View file

@ -0,0 +1,3 @@
/etc/spaceapi-server/config.json
/etc/spaceapi-server/template.json
/etc/spaceapi-server/plugins/example.py

View file

@ -0,0 +1,21 @@
#!/bin/sh
set -e
if [ "$1" = "configure" ]; then
if ! getent group spaceapi-server >/dev/null; then
groupadd --system spaceapi-server
fi
if ! getent passwd spaceapi-server >/dev/null; then
useradd --system --create-home --gid spaceapi-server --home-dir /var/lib/spaceapi-server \
--shell /usr/sbin/nologin spaceapi-server
fi
chown root:spaceapi-server /etc/spaceapi-server
chmod 0750 /etc/spaceapi-server
systemctl daemon-reload || true
fi

View file

@ -0,0 +1,9 @@
#!/bin/sh
set -e
if [ "$1" = "remove" ]; then
systemctl daemon-reload || true
fi

View file

@ -0,0 +1,9 @@
#!/bin/sh
set -e
if [ "$1" = "remove" ]; then
userdel spaceapi-server
fi

View file

@ -0,0 +1,7 @@
{
"address": "::",
"port": 8080,
"template": "/etc/spaceapi-server/template.json",
"plugins_dir": "/etc/spaceapi-server/plugins",
"plugins": {}
}

View file

@ -0,0 +1,19 @@
{
"api": "0.13",
"space": "Example Space",
"logo": "https://example.org/logo.png",
"url": "https://example.org",
"location": {
"lat": 0.0,
"lon": 0.0
},
"state": {
"open": null
},
"contact": {
"email": "example@example.org"
},
"issue_report_channels": [
"email"
]
}

View file

@ -0,0 +1,10 @@
[Unit]
Description=Lightweight SpaceAPI Endpoint Server
[Service]
ExecStart=/usr/lib/spaceapi-server/spaceapi-server /etc/spaceapi-server/config.json
ExecReload=/usr/bin/kill -HUP $MAINPID
User=spaceapi-server
[Install]
WantedBy=network-online.target

View file

@ -8,13 +8,13 @@ setup(
name='spaceapi_server', name='spaceapi_server',
version=__version__, version=__version__,
author='s3lph', author='s3lph',
author_email='', author_email='account-gitlab-ideynizv@kernelpanic.lol',
description='A lightweight SpaceAPI (spaceapi.io) endpoint server', description='Lightweight SpaceAPI (spaceapi.io) endpoint server',
license='MIT', license='MIT',
keywords='spaceapi', keywords='spaceapi',
url='https://gitlab.com/s3lph/spaceapi-server', url='https://gitlab.com/s3lph/spaceapi-server',
packages=find_packages(exclude=['*.test']), packages=find_packages(exclude=['*.test']),
long_description='A lightweight server for SpaceAPI endpoints. Includes support for pluggable templating, ' long_description='Lightweight server for SpaceAPI endpoints. Includes support for pluggable templating, '
'so dynamic content, like sensor values, can be added.', 'so dynamic content, like sensor values, can be added.',
python_requires='>=3.6', python_requires='>=3.6',
install_requires=[ install_requires=[

View file

@ -28,8 +28,11 @@ def render(template: str):
env = _env_init() env = _env_init()
# Create a Jinja2 template from the input string # Create a Jinja2 template from the input string
t = env.from_string(template) t = env.from_string(template)
decoder = json.JSONDecoder()
# Render the template and turn the JSON dump back into complex data structures # Render the template and turn the JSON dump back into complex data structures
return json.loads(t.render()) # Only parse the first JSON object in the string, ignore the rest
obj, i = decoder.raw_decode(t.render())
return obj
def render_traverse(obj): def render_traverse(obj):

View file

@ -36,6 +36,7 @@ class TemplateTest(unittest.TestCase):
self.assertEqual(42, render('{{ 42 }}')) self.assertEqual(42, render('{{ 42 }}'))
self.assertEqual(['foo'], render('{{ [ "foo" ] }}')) self.assertEqual(['foo'], render('{{ [ "foo" ] }}'))
self.assertEqual({'foo': ['bar']}, render('{{ { "foo": [ "bar" ] } }}')) self.assertEqual({'foo': ['bar']}, render('{{ { "foo": [ "bar" ] } }}'))
self.assertEqual('foo', render('foo{{ "bar" }}'))
def test_render_traverse(self): def test_render_traverse(self):
template = { template = {