-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #624 from usc-isi-i2/windows-service-git-action
Windows service git action
- Loading branch information
Showing
7 changed files
with
322 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
name: Create Windows Service | ||
on: | ||
push: | ||
tags: | ||
- v* | ||
|
||
# For Code Signing please make sure the following secrets are defined in the repository: | ||
# WINDOWS_CERTIFICATE_BASE64 - The Windows code signing certificate, base64 encoded | ||
# WINDOWS_CERTIFICATE_PASSWORD - The password for Windows the certificate | ||
|
||
jobs: | ||
windows: | ||
name: Create the Windows Service | ||
runs-on: windows-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
- name: Setup Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.8' | ||
- name: Set backend environment | ||
working-directory: backend | ||
run: | | ||
pip install --upgrade setuptools pip wheel | ||
pip install t2wml-api | ||
pip install -r requirements.txt | ||
pip install pyinstaller pywin32 semver requests | ||
pip uninstall -y typing typing-extensions | ||
pip install waitress | ||
- name: Create installer | ||
working-directory: backend | ||
env: # Replace unicode characters with ? | ||
PYTHONIOENCODING: :replace | ||
PYTHONLEGACYWINDOWSIOENCODING: true | ||
CI: false # Otherwise React stops on warnings | ||
CSC_KEY_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} | ||
run: | | ||
pyinstaller --clean --noupx t2wml-service.spec | ||
- name: Get the version | ||
id: get_version | ||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} | ||
shell: bash | ||
- name: Upload to Release | ||
id: upload-release-asset | ||
uses: svenstaro/upload-release-action@v2 | ||
with: | ||
repo_token: ${{ secrets.GITHUB_TOKEN }} | ||
file: backend/dist/t2wml-service.exe | ||
asset_name: t2wml-service-${{ steps.get_version.outputs.VERSION }}.exe | ||
tag: ${{ github.ref }} | ||
overwrite: true | ||
body: "Windows Setup" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
""" | ||
# Prerequisites: | ||
cd backend | ||
virtualenv env-service | ||
(activate virtual env) | ||
pip install -r requirements.txt | ||
pip install --upgrade pyinstaller | ||
pip install pywin32 | ||
pip install waitress | ||
pip install requests | ||
pip install -e ../../t2wml-api | ||
# Build: | ||
pyinstaller --clean --noupx t2wml-service.spec | ||
# With Administrator privilges | ||
# Install: | ||
dist\t2wml-service.exe install | ||
# Start: | ||
dist\t2wml-service.exe start | ||
# Install with autostart: | ||
dist\t2wml-service.exe --startup delayed install | ||
# Debug: | ||
dist\t2wml-service.exe debug | ||
# Stop: | ||
dist\t2wml-service.exe stop | ||
# Uninstall: | ||
dist\t2wml-service.exe remove | ||
""" | ||
|
||
import time | ||
import ctypes | ||
import sys | ||
import win32serviceutil # ServiceFramework and commandline helper | ||
import win32service # Events | ||
import servicemanager # Simple setup and logging | ||
import win32event | ||
from waitress import serve | ||
import socket | ||
import threading | ||
|
||
from causx_application import app | ||
class WaitressService(threading.Thread): | ||
|
||
def __init__(self): | ||
threading.Thread.__init__(self) | ||
|
||
def run(self): | ||
print('thread start\n') | ||
serve(app, host='localhost', port=13000, trusted_proxy='localhost') | ||
print('thread done\n') | ||
|
||
def get_id(self): | ||
# returns id of the respective thread | ||
if hasattr(self, '_thread_id'): | ||
return self._thread_id | ||
for id, thread in threading._active.items(): | ||
if thread is self: | ||
return id | ||
|
||
def exit(self): | ||
thread_id = self.get_id() | ||
res = ctypes.pythonapi.PyThreadState_SetAsyncExc( | ||
thread_id, ctypes.py_object(SystemExit)) | ||
if res > 1: | ||
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) | ||
print('Exception raise failure') | ||
|
||
|
||
class MyServiceFramework(win32serviceutil.ServiceFramework): | ||
|
||
_svc_name_ = 't2wml_backend' | ||
_svc_display_name_ = 'T2WML Backend Service' | ||
_svc_description_ = 'T2WML Backend Service for Causx' | ||
|
||
def __init__(self, args): | ||
win32serviceutil.ServiceFramework.__init__(self, args) | ||
self.stopEvt = win32event.CreateEvent(None, 0, 0, None) | ||
socket.setdefaulttimeout(60) | ||
|
||
def SvcStop(self): | ||
"""Stop the service""" | ||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, | ||
servicemanager.PYS_SERVICE_STOPPED, | ||
(self._svc_name_, '')) | ||
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) | ||
win32event.SetEvent(self.stopEvt) | ||
|
||
def SvcDoRun(self): | ||
"""Start the service; does not return until stopped""" | ||
print('main start') | ||
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, | ||
servicemanager.PYS_SERVICE_STARTED, | ||
(self._svc_name_, '')) | ||
self.service_impl = WaitressService() | ||
self.ReportServiceStatus(win32service.SERVICE_RUNNING) | ||
# Run the service | ||
self.service_impl.start() | ||
|
||
print('waiting on win32event') | ||
win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE) | ||
self.service_impl.exit() # raise SystemExit in inner thread | ||
print('waiting on thread') | ||
self.service_impl.join() | ||
print('main done') | ||
|
||
|
||
def init(): | ||
if len(sys.argv) == 1: | ||
servicemanager.Initialize() | ||
servicemanager.PrepareToHostSingle(MyServiceFramework) | ||
servicemanager.StartServiceCtrlDispatcher() | ||
else: | ||
win32serviceutil.HandleCommandLine(MyServiceFramework) | ||
|
||
|
||
if __name__ == '__main__': | ||
init() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# -*- mode: python ; coding: utf-8 -*- | ||
|
||
""" | ||
# Prerequisites: | ||
cd backend | ||
virtualenv env-service | ||
(activate virtual env) | ||
pip install -r requirements.txt | ||
pip install --upgrade pyinstaller | ||
pip install pywin32 | ||
pip install waitress | ||
pip install requests | ||
pip install t2wml-api | ||
# Build: | ||
pyinstaller --clean --noupx t2wml-service.spec | ||
# With Administrator privilges | ||
# Install: | ||
dist\t2wml-service.exe install | ||
# Start: | ||
dist\t2wml-service.exe start | ||
# Debug: | ||
dist\t2wml-service.exe debug | ||
# Stop: | ||
dist\t2wml-service.exe stop | ||
# Uninstall: | ||
dist\t2wml-service.exe remove | ||
""" | ||
|
||
import sys | ||
from os import path, getcwd | ||
site_packages = next(p for p in sys.path if 'site-packages' in p) | ||
|
||
def copy_package(name): | ||
return [(path.join(site_packages, name), name)] | ||
|
||
block_cipher = None | ||
|
||
|
||
a = Analysis(['t2wml-service.py'], | ||
pathex=[getcwd()], | ||
binaries=[], | ||
datas=copy_package('distributed'), | ||
hiddenimports=['win32timezone', 'pandas','pandas._libs.tslibs.base', 'rltk', 'logging.config', 'cmath'], | ||
hookspath=[], | ||
runtime_hooks=[], | ||
excludes=[], | ||
win_no_prefer_redirects=False, | ||
win_private_assemblies=False, | ||
cipher=block_cipher, | ||
noarchive=False) | ||
|
||
pyz = PYZ(a.pure, a.zipped_data, | ||
cipher=block_cipher) | ||
|
||
exe = EXE(pyz, | ||
a.scripts, | ||
a.binaries, | ||
a.zipfiles, | ||
a.datas, | ||
[], | ||
name='t2wml-service', | ||
debug=False, | ||
bootloader_ignore_signals=False, | ||
strip=False, | ||
upx=True, | ||
upx_exclude=[], | ||
runtime_tmpdir='.', | ||
console=True, | ||
disable_windowed_traceback=False, | ||
target_arch=None, | ||
codesign_identity=None, | ||
entitlements_file=None | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from waitress import serve | ||
|
||
from causx_application import app | ||
|
||
#def run(): | ||
# app.run(port=13000, debug=False, host=None, use_reloader=False) | ||
|
||
serve(app, port=13000, host='localhost') | ||
|
||
# serve(wsgiapp, host='localhost', port=13000) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# -*- mode: python ; coding: utf-8 -*- | ||
# Pyinstaller spec file. | ||
|
||
# pip install --upgrade pyinstaller | ||
# pyinstaller --clean --noupx .\t2wml-waitress.spec | ||
|
||
from PyInstaller.utils.hooks import copy_metadata | ||
import sys | ||
from os import path, getcwd | ||
site_packages = next(p for p in sys.path if 'site-packages' in p) | ||
|
||
def copy_package(name): | ||
return [(path.join(site_packages, name), name)] | ||
|
||
block_cipher = None | ||
|
||
|
||
a = Analysis(['t2wml-waitress.py'], | ||
pathex=[getcwd()], | ||
binaries=[], | ||
datas=copy_package('distributed'), | ||
hiddenimports=['pandas','pandas._libs.tslibs.base', 'rltk', 'logging.config', 'cmath'], | ||
hookspath=[], | ||
runtime_hooks=[], | ||
excludes=[], | ||
win_no_prefer_redirects=False, | ||
win_private_assemblies=False, | ||
cipher=block_cipher, | ||
noarchive=False) | ||
|
||
pyz = PYZ(a.pure, a.zipped_data, | ||
cipher=block_cipher) | ||
exe = EXE(pyz, | ||
a.scripts, | ||
a.binaries, | ||
a.zipfiles, | ||
a.datas, | ||
[], | ||
name='t2wml-waitress', | ||
debug=False, | ||
bootloader_ignore_signals=False, | ||
strip=False, | ||
upx=True, | ||
upx_exclude=[], | ||
runtime_tmpdir=None, | ||
console=True ) |