From 7630bb03aa7371511045923845ae8505554e55df Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Thu, 7 Mar 2019 22:31:33 +0000 Subject: [PATCH 1/3] 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/buildroot.mk | 36 ++++++++++++++++++++++++++++++++ api/opentrons-api-server.service | 11 ++++++++++ api/setup.py | 1 - external.desc | 2 ++ external.mk | 3 +++ 7 files changed, 66 insertions(+), 1 deletion(-) 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/buildroot.mk b/api/buildroot.mk new file mode 100644 index 00000000000..003a67e6540 --- /dev/null +++ b/api/buildroot.mk @@ -0,0 +1,36 @@ +################################################################################ +# +# 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 + +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..02d715e7b6a --- /dev/null +++ b/api/opentrons-api-server.service @@ -0,0 +1,11 @@ +[Unit] +Description=Opentrons API server +Requires=nginx.service +After=nginx.service + +[Service] +Type=exec +ExecStart=python -m opentrons.main -U /run/aiohttp.sock + +[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/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 From 697fdf49672e7cdad5e57e05210a2b6168fa0686 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Fri, 15 Mar 2019 13:50:44 -0400 Subject: [PATCH 2/3] =?UTF-8?q?fixup(api):=20Specify=20smoothie=20id=20and?= =?UTF-8?q?=20don=E2=80=99t=20fail=20in=20udev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Udev isn’t necessary on the new system. --- api/opentrons-api-server.service | 1 + api/src/opentrons/main.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/api/opentrons-api-server.service b/api/opentrons-api-server.service index 02d715e7b6a..6d5e1046846 100644 --- a/api/opentrons-api-server.service +++ b/api/opentrons-api-server.service @@ -6,6 +6,7 @@ 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/src/opentrons/main.py b/api/src/opentrons/main.py index d4810adf0f6..1541c2802ee 100644 --- a/api/src/opentrons/main.py +++ b/api/src/opentrons/main.py @@ -178,7 +178,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() From 54c93a40226047ee3dee0a48041a155e75a55d32 Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Tue, 19 Mar 2019 22:31:40 +0000 Subject: [PATCH 3/3] chore(api): write a version file in buildroot --- api/build_tools.py | 48 ++++++++++++++++++++++++++++++++-------------- api/buildroot.mk | 9 +++++++++ 2 files changed, 43 insertions(+), 14 deletions(-) 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 index 003a67e6540..59215a15134 100644 --- a/api/buildroot.mk +++ b/api/buildroot.mk @@ -16,6 +16,15 @@ 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