From 60d796826f26638057a403d95d9f967e6c5180d7 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Tue, 26 Mar 2019 18:11:53 -0400 Subject: [PATCH] chore(api): Add infrastructure for a br2-external tree for buildroot (#3217) * chore(api): Add infrastructure for a br2-external tree for buildroot More information can be found in https://buildroot.org/downloads/manual/manual.html. This change doesn't alter the normal build infrastructure; it's only used when included by buildroot externally. This tooling provides definitions for our api server and a unit file to bring it up using systemd. --- Config.in | 3 ++ api/Config.in | 11 ++++++++ api/build_tools.py | 48 ++++++++++++++++++++++---------- api/buildroot.mk | 45 ++++++++++++++++++++++++++++++ api/opentrons-api-server.service | 12 ++++++++ api/setup.py | 1 - api/src/opentrons/main.py | 6 +++- external.desc | 2 ++ external.mk | 3 ++ 9 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 Config.in create mode 100644 api/Config.in create mode 100644 api/buildroot.mk create mode 100644 api/opentrons-api-server.service create mode 100644 external.desc create mode 100644 external.mk diff --git a/Config.in b/Config.in new file mode 100644 index 00000000000..356fcab11fb --- /dev/null +++ b/Config.in @@ -0,0 +1,3 @@ +# Configuration for Buildroot integration +source "$BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH/api/Config.in" +# source "$BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH/update-server/Config.in" \ No newline at end of file diff --git a/api/Config.in b/api/Config.in new file mode 100644 index 00000000000..8dc7d5de428 --- /dev/null +++ b/api/Config.in @@ -0,0 +1,11 @@ +config BR2_PACKAGE_PYTHON_OPENTRONS_API + bool "python-opentrons-api" + depends on BR2_PACKAGE_PYTHON3 + select BR2_PACKAGE_PYTHON_NUMPY # runtime + select BR2_PACKAGE_PYTHON_SERIAL # runtime + select BR2_PACKAGE_PYTHON_URWID # runtime + select BR2_PACKAGE_PYTHON_AIOHTTP # runtime + help + Opentrons API server. Controls an OT2 robot. + + https://opentrons.com \ No newline at end of file diff --git a/api/build_tools.py b/api/build_tools.py index c3ae18a193d..0a9b55653d9 100644 --- a/api/build_tools.py +++ b/api/build_tools.py @@ -5,30 +5,50 @@ import argparse import json import os +import subprocess -# Pipenv requires setuptools >= 36.2.1. Since 36.2.1, setuptools changed -# the way they vendor dependencies, like the packaging module that -# provides the way to normalize version numbers for wheel file names. So -# we try all the possible ways to find it. -try: - # new way - from setuptools.extern import packaging -except ImportError: - # old way - from pkg_resources.extern import packaging + +HERE = os.path.dirname(__file__) + + +def get_version(): + pkg_json_path = os.path.join(HERE, 'src', 'opentrons', 'package.json') + return json.load(open(pkg_json_path))['version'] def normalize_version(): - pkg_json_path = os.path.join('src', 'opentrons', 'package.json') - old_ver = json.load(open(pkg_json_path))['version'] - vers_obj = packaging.version.Version(old_ver) + # Pipenv requires setuptools >= 36.2.1. Since 36.2.1, setuptools changed + # the way they vendor dependencies, like the packaging module that + # provides the way to normalize version numbers for wheel file names. So + # we try all the possible ways to find it. + try: + # new way + from setuptools.extern import packaging + except ImportError: + # old way + from pkg_resources.extern import packaging + vers_obj = packaging.version.Version(get_version()) return str(vers_obj) +def dump_br_version(): + """ Dump an enhanced version json including + - The version from package.json + - The current branch (if it can be found) + - The current sha + """ + normalized = get_version() + sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=HERE).strip() + branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=HERE).strip() + return json.dumps({'opentrons_api_version': normalized, + 'opentrons_api_sha': sha, + 'opentrons_api_branch': branch}) + + if __name__ == '__main__': parser = argparse.ArgumentParser( description='Perform one of several build-time tasks') parser.add_argument(dest='task', metavar='TASK', type=str, - choices=['normalize_version']) + choices=['normalize_version', 'dump_br_version']) args = parser.parse_args() print(locals()[args.task]()) diff --git a/api/buildroot.mk b/api/buildroot.mk new file mode 100644 index 00000000000..59215a15134 --- /dev/null +++ b/api/buildroot.mk @@ -0,0 +1,45 @@ +################################################################################ +# +# python-opentrons-api +# +################################################################################ + +# Get a key from package.json (like version) +define get_pkg_json_key + $(shell python -c "import json; print(json.load(open('$(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/api/src/opentrons/package.json'))[\"$(1)\"])") +endef + +PYTHON_OPENTRONS_API_VERSION = $(call get_pkg_json_key,version) +PYTHON_OPENTRONS_API_LICENSE = $(call get_pkg_json_key,license) +PYTHON_OPENTRONS_API_LICENSE_FILES = $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/LICENSE +PYTHON_OPENTRONS_API_SETUP_TYPE = setuptools +PYTHON_OPENTRONS_API_SITE_METHOD = local +PYTHON_OPENTRONS_API_SITE = $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH) +PYTHON_OPENTRONS_API_SUBDIR = api +PYTHON_OPENTRONS_API_POST_INSTALL_TARGET_HOOKS = PYTHON_OPENTRONS_API_INSTALL_VERSION + +define DUMP_BR_VERSION +$(shell python 2>&1 $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/api/build_tools.py dump_br_version) +endef + +define PYTHON_OPENTRONS_API_INSTALL_VERSION + echo '$(call DUMP_BR_VERSION)' > $(BINARIES_DIR)/opentrons-api-version.json +endef + +ot_api_name := python-opentrons-api + +define PYTHON_OPENTRONS_API_INSTALL_INIT_SYSTEMD + $(INSTALL) -D -m 0644 $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/api/opentrons-api-server.service \ + $(TARGET_DIR)/etc/systemd/system/opentrons-api-server.service + + mkdir -p $(TARGET_DIR)/etc/systemd/system/opentrons.target.wants + + ln -sf ../opentrons-api-server.service \ + $(TARGET_DIR)/etc/systemd/system/opentrons.target.wants/opentrons-api-server.service +endef + +# Calling inner-python-package directly instead of using python-package macro +# because our directory layout doesn’t conform to buildroot’s expectation of +# having the directory name be the package name +$(eval $(call inner-python-package,python-opentrons-api,$(call UPPERCASE,$(ot_api_name)),$(call UPPERCASE,$(ot_api_name)),target)) + diff --git a/api/opentrons-api-server.service b/api/opentrons-api-server.service new file mode 100644 index 00000000000..6d5e1046846 --- /dev/null +++ b/api/opentrons-api-server.service @@ -0,0 +1,12 @@ +[Unit] +Description=Opentrons API server +Requires=nginx.service +After=nginx.service + +[Service] +Type=exec +ExecStart=python -m opentrons.main -U /run/aiohttp.sock +Environment=OT_SMOOTHIE_ID=AMA + +[Install] +WantedBy=opentrons.target \ No newline at end of file diff --git a/api/setup.py b/api/setup.py index b4f2d928063..2337a63cc1f 100755 --- a/api/setup.py +++ b/api/setup.py @@ -136,7 +136,6 @@ def read(*parts): zip_safe=False, classifiers=CLASSIFIERS, install_requires=INSTALL_REQUIRES, - setup_requires=['pytest-runner'], tests_require=['pytest'], include_package_data=True, package_dir={'': 'src'}, diff --git a/api/src/opentrons/main.py b/api/src/opentrons/main.py index 315ebb3e07a..03e279ee772 100644 --- a/api/src/opentrons/main.py +++ b/api/src/opentrons/main.py @@ -182,7 +182,11 @@ def run(**kwargs): loop.run_until_complete(hardware.home_z()) else: hardware.home_z() - udev.setup_rules_file() + try: + udev.setup_rules_file() + except Exception: + log.exception( + "Could not setup udev rules, modules may not be detected") # Explicitly unlock resin updates in case a prior server left them locked resin.unlock_updates() diff --git a/external.desc b/external.desc new file mode 100644 index 00000000000..59e69e8adba --- /dev/null +++ b/external.desc @@ -0,0 +1,2 @@ +name: OPENTRONS_MONOREPO +desc: Tree containing Opentrons API and update infrastructure \ No newline at end of file diff --git a/external.mk b/external.mk new file mode 100644 index 00000000000..18a6ba01963 --- /dev/null +++ b/external.mk @@ -0,0 +1,3 @@ +# Makefile inclusions for buildroot integration +include $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/api/buildroot.mk +# include $(BR2_EXTERNAL_OPENTRONS_MONOREPO_PATH)/update-server/buildroot.mk