MycroftOS: Mycroft A.I. service package

- Systemd support for Mycroft A.I.
- Remove old init.d system files
- Update start/stop-mycroft.sh files
This commit is contained in:
Peter Steenbergen 2019-02-04 12:55:48 +01:00
parent f0711f0972
commit 032566548a
10 changed files with 157 additions and 113 deletions

View File

@ -1,3 +1,6 @@
menu "Mycroft A.I. Personal Assistant"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-mycroft/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/mycroft-service/Config.in"
menu "Additional drivers, libraries and/or applications"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/fann/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/respeaker/Config.in"
@ -28,7 +31,6 @@ menu "Additional external python modules"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-monotonic/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msk/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-msm/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-mycroft/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-oauth2client/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-olefile/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-padaos/Config.in"
@ -54,3 +56,4 @@ menu "Additional external python modules"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xmlrunner/Config.in"
source "$BR2_EXTERNAL_MYCROFTOS_PATH/package/python-xxhash/Config.in"
endmenu
endmenu

View File

@ -184,6 +184,8 @@ BR2_PACKAGE_HOST_PYTHON_CYTHON=y
BR2_PACKAGE_HOST_PYTHON_LXML=y
BR2_PACKAGE_HOST_PYTHON_SIX=y
BR2_PACKAGE_HOST_PYTHON_XLRD=y
BR2_PACKAGE_PYTHON_MYCROFT=y
BR2_PACKAGE_MYCROFT_SERVICE=y
BR2_PACKAGE_FANN=y
BR2_PACKAGE_RESPEAKER=y
BR2_PACKAGE_PYTHON_ADAPT_PARSER=y
@ -198,7 +200,6 @@ BR2_PACKAGE_PYTHON_GTTS=y
BR2_PACKAGE_PYTHON_HUMANHASH3=y
BR2_PACKAGE_PYTHON_INFLECTION=y
BR2_PACKAGE_PYTHON_MSK=y
BR2_PACKAGE_PYTHON_MYCROFT=y
BR2_PACKAGE_PYTHON_OAUTH2CLIENT=y
BR2_PACKAGE_PYTHON_OLEFILE=y
BR2_PACKAGE_PYTHON_PADATIOUS=y

View File

@ -0,0 +1,6 @@
config BR2_PACKAGE_MYCROFT_SERVICE
bool "mycroft-service"
help
Start the Mycroft A.I. software as service.
https://mycroft.ai/

View File

@ -0,0 +1,27 @@
################################################################################
#
# mycroft-service
#
################################################################################
MYCROFT_SERVICE_VERSION = 0.1.0
MYCROFT_SERVICE_SITE = $(BR2_EXTERNAL_MYCROFTOS_PATH)/package/mycroft-service
MYCROFT_SERVICE_SITE_METHOD = local
MYCROFT_SERVICE_LICENSE = Apache License 2.0
MYCROFT_SERVICE_LICENSE_FILES = LICENSE
define MYCROFT_SERVICE_USERS
mycroft -1 mycroft -1 mycroft /home/mycroft /bin/bash audio,pulse,pulse-access
endef
define MYCROFT_SERVICE_INSTALL_TARGET_CMDS
$(INSTALL) -m 0755 $(@D)/start-mycroft.sh $(TARGET_DIR)/usr/bin/
$(INSTALL) -m 0755 $(@D)/stop-mycroft.sh $(TARGET_DIR)/usr/bin/
$(INSTALL) -D -m 644 $(@D)/mycroft.service \
$(TARGET_DIR)/usr/lib/systemd/system/mycroft.service
mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants
ln -fs ../../../../usr/lib/systemd/system/mycroft.service \
$(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/mycroft.service
endef
$(eval $(generic-package))

View File

@ -0,0 +1,15 @@
[Unit]
Description=Mycroft AI
After=pulseaudio.service
[Service]
User=mycroft
WorkingDirectory=/home/mycroft
ExecStart=start-mycroft.sh all
ExecStop=stop-mycroft.sh all
Type=forking
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target

View File

@ -23,31 +23,34 @@ DIR="$( pwd )"
function help() {
echo "${script}: Mycroft command/service launcher"
echo "usage: ${script} [command] [params]"
echo "usage: ${script} [COMMAND] [restart] [params]"
echo
echo "Services:"
echo "Services COMMANDs:"
echo " all runs core services: bus, audio, skills, voice"
echo " debug runs core services, then starts the CLI"
echo
echo "Services:"
echo " audio the audio playback service"
echo " bus the messagebus service"
echo " skills the skill service"
echo " voice voice capture service"
# echo " wifi wifi setup service"
echo " enclosure mark_1 enclosure service"
echo
echo "Tools:"
echo "Tool COMMANDs:"
echo " cli the Command Line Interface"
echo " unittest run mycroft-core unit tests (requires pytest)"
echo " skillstest run the skill autotests for all skills (requires pytest)"
echo
echo "Utils:"
echo "Util COMMANDs:"
echo " audiotest attempt simple audio validation"
echo " audioaccuracytest more complex audio validation"
echo " sdkdoc generate sdk documentation"
echo
echo "Options:"
echo " restart (optional) Force the service to restart if running"
echo
echo "Examples:"
echo " ${script} all"
echo " ${script} all restart"
echo " ${script} cli"
echo " ${script} unittest"
@ -72,7 +75,32 @@ function name-to-script-path() {
esac
}
first_time=true
# set the right locale / language settings
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
function init-once() {
if ($first_time) ; then
echo "Initializing..."
# Check if Mycroft log folders are present and if not
# create those logging folders
if [[ ! -w /var/log/mycroft/ ]] ; then
# Creating needed folders
printf "Creating /var/log/mycroft/ directory"
if [[ ! -d /var/log/mycroft/ ]] ; then
mkdir /var/log/mycroft/
fi
fi
first_time=false
fi
}
function launch-process() {
init-once
name-to-script-path ${1}
# Launch process in foreground
@ -80,12 +108,28 @@ function launch-process() {
python3 -m ${_module} $_params
}
function require-process() {
# Launch process if not found
name-to-script-path ${1}
if ! pgrep -f "python3 -m ${_module}" > /dev/null ; then
# Start required process
launch-background ${1}
fi
}
function launch-background() {
init-once
# Check if given module is running and start (or restart if running)
name-to-script-path ${1}
if pgrep -f "python3 -m ${_module}" > /dev/null ; then
echo "Restarting: ${1}"
"${DIR}/stop-mycroft.sh" ${1}
if ($_force_restart) ; then
echo "Restarting: ${1}"
"${DIR}/stop-mycroft.sh" ${1}
else
# Already running, no need to restart
return
fi
else
echo "Starting background service $1"
fi
@ -107,25 +151,27 @@ function launch-all() {
launch-background skills
launch-background audio
launch-background voice
# Determine platform type
if [[ -r /etc/mycroft/mycroft.conf ]] ; then
mycroft_platform=$( jq -r ".enclosure.platform" < /etc/mycroft/mycroft.conf )
if [[ $mycroft_platform = "mycroft_mark_1" ]] ; then
# running on a Mark 1, start enclosure service
launch-background enclosure
fi
fi
launch-background enclosure
}
_opt=$1
_force_restart=false
shift
if [[ "${1}" == "restart" ]] || [[ "${_opt}" == "restart" ]] ; then
_force_restart=true
if [[ "${_opt}" == "restart" ]] ; then
# Support "start-mycroft.sh restart all" as well as "start-mycroft.sh all restart"
_opt=$1
fi
shift
fi
_params=$@
case ${_opt} in
"all")
launch-all
;;
"bus")
launch-background ${_opt}
;;
@ -138,24 +184,51 @@ case ${_opt} in
"voice")
launch-background ${_opt}
;;
"debug")
launch-all
launch-process cli
;;
"cli")
require-process bus
require-process skills
launch-process ${_opt}
;;
# TODO: Restore support for Wifi Setup on a Picroft, etc.
# "wifi")
# launch-background ${_opt}
# ;;
"unittest")
source-venv
pytest test/unittests/ --cov=mycroft "$@"
;;
"singleunittest")
source-venv
pytest "$@"
;;
"skillstest")
source-venv
pytest test/integrationtests/skills/discover_tests.py "$@"
;;
"audiotest")
launch-process ${_opt}
;;
"audioaccuracytest")
launch-process ${_opt}
;;
"sdkdoc")
source-venv
cd doc
make ${opt}
cd ..
;;
"enclosure")
launch-background ${_opt}
;;
*)
help
;;
esac

View File

@ -31,7 +31,7 @@ function help() {
echo " audio stop the audio playback service"
echo " skills stop the skill service"
echo " voice stop voice capture service"
echo " enclosure stop mark_1 enclosure service"
echo " enclosure stop enclosure (hardware/gui interface) service"
echo
echo "Examples:"
echo " ${script}"
@ -50,8 +50,9 @@ function process-running() {
function end-process() {
if process-running $1 ; then
echo -n "Stopping $1..."
pid=$( pgrep -f "python3 -m mycroft.*${1}" )
# Find the process by name, only returning the oldest if it has children
pid=$( pgrep -o -f "python3 -m mycroft.*${1}" )
echo -n "Stopping $1 (${pid})..."
kill -SIGINT ${pid}
# Wait up to 5 seconds (50 * 0.1) for process to stop
@ -67,7 +68,8 @@ function end-process() {
if process-running $1 ; then
echo "failed to stop."
echo -n " Killing $1..."
pid=$( pgrep -o -f "python3 -m mycroft.*${1}" )
echo -n " Killing $1 (${pid})..."
kill -9 ${pid}
echo "killed."
result=120
@ -80,8 +82,10 @@ function end-process() {
fi
}
result=0 # default, no change
OPT=$1
shift
@ -94,15 +98,7 @@ case ${OPT} in
end-process skills
end-process audio
end-process speech
# determine platform type
if [[ -r /etc/mycroft/mycroft.conf ]] ; then
mycroft_platform=$( jq -r ".enclosure.platform" < /etc/mycroft/mycroft.conf )
if [[ $mycroft_platform == "mycroft_mark_1" ]] ; then
# running on a Mark 1, stop enclosure service
end-process enclosure
fi
fi
end-process enclosure
;;
"bus")
end-process messagebus.service
@ -119,6 +115,7 @@ case ${OPT} in
"enclosure")
end-process enclosure
;;
*)
help
;;
@ -128,4 +125,4 @@ esac
# 0 if nothing changed (e.g. --help or no process was running)
# 100 at least one process was stopped
# 120 if any process had to be killed
exit $result
exit $result

View File

@ -7,6 +7,6 @@
PYTHON_MYCROFT_VERSION = v18.8.12
PYTHON_MYCROFT_SITE = $(call github,MycroftAI,mycroft-core,release/$(PYTHON_MYCROFT_VERSION))
PYTHON_MYCROFT_SETUP_TYPE = setuptools
PYTHON_MYCROFT_LICENSE_FILES =
PYTHON_MYCROFT_LICENSE_FILES = LICENSE
$(eval $(python-package))

View File

@ -1,41 +0,0 @@
#!/bin/sh
#
# Prepare Mycroft software stack.
#
start() {
# set the right locale / language settings
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
# Check if Mycroft log folders are present and if not
# create those logging folders
if [[ ! -w /var/log/mycroft/ ]] ; then
# Creating needed folders
printf "Creating /var/log/mycroft/ directory"
if [[ ! -d /var/log/mycroft/ ]] ; then
mkdir /var/log/mycroft/
fi
fi
# Check if /.mycroft exist already and if not
# create a symbolic link to /root/.mycroft
if [[ ! -w /.mycroft/ ]] ; then
# Creating .mycroft symlink
printf "Creating /.mycroft/ symlink"
if [[ ! -d /.mycroft/ ]] ; then
ln -s /root/.mycroft /.mycroft
fi
fi
}
case "$1" in
start)
start
;;
*)
echo "Usage: $0 {start}"
exit 1
esac
exit $?

View File

@ -1,37 +0,0 @@
#!/bin/sh
#
# Starts Mycroft services.
#
start() {
printf "Starting Mycroft services: "
umask 077
bash /usr/bin/start-mycroft.sh all
echo "OK"
}
stop() {
printf "Stopping Mycroft services: "
bash /usr/bin/stop-mycroft.sh all
echo "OK"
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?