refs #309 #393 #408 build and package ogagent py3/qt6 for windows

pull/4/head
Natalia Serrano 2024-06-24 15:46:11 +02:00
parent 5294919c98
commit d7a7a1f0bf
14 changed files with 133 additions and 230 deletions

5
.gitignore vendored
View File

@ -15,6 +15,11 @@ ogagent_*_all.deb
ogagent_*_amd64.buildinfo
ogagent_*_amd64.changes
ogagent_*_amd64.build
OGAgentSetup-*.exe
bin
src/about_dialog_ui.py
src/message_dialog_ui.py
src/OGAgent_rc.py
src/dist
src/build
windows/VERSION

96
src/OGAgent.spec 100755
View File

@ -0,0 +1,96 @@
# -*- mode: python ; coding: utf-8 -*-
ogausr_a = Analysis(
['OGAgentUser.py'],
pathex=[],
binaries=[],
datas=[
# ('cfg', 'cfg'), ## add the entire directory
],
hiddenimports=['win32timezone', 'socketserver', 'http.server', 'urllib'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
ogasvc_a = Analysis(
['opengnsys\\windows\\OGAgentService.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=['win32timezone', 'socketserver', 'http.server', 'urllib'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
MERGE(
(ogausr_a, 'OGAgentUser', 'OGAgentUser'), ## class, py name, exe name
(ogasvc_a, 'OGAgentService', 'OGAgentService')
)
ogausr_pyz = PYZ(ogausr_a.pure)
ogasvc_pyz = PYZ(ogasvc_a.pure)
ogausr_exe = EXE(
ogausr_pyz,
ogausr_a.scripts,
[],
exclude_binaries=True,
name='OGAgentUser',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['img\\oga.ico'],
)
ogasvc_exe = EXE(
ogasvc_pyz,
ogasvc_a.scripts,
[],
exclude_binaries=True,
name='OGAgentService',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['img\\oga.ico'],
manifest='OGAgent.manifest',
)
dist_name = 'OGAgent'
coll = COLLECT(
ogausr_exe,
ogausr_a.binaries,
ogausr_a.datas,
ogasvc_exe,
ogasvc_a.binaries,
ogasvc_a.datas,
strip=False,
upx=True,
upx_exclude=[],
name=dist_name,
)
import shutil
shutil.copytree ('cfg', '{}/{}/cfg'.format(DISTPATH, dist_name))

View File

@ -32,7 +32,7 @@
# pylint: disable=unused-wildcard-import, wildcard-import
from configparser import SafeConfigParser
from configparser import ConfigParser
config = None
@ -45,7 +45,7 @@ def readConfig(client=False):
This is this way so we can protect ogagent.cfg against reading for non admin users on all platforms.
"""
cfg = SafeConfigParser()
cfg = ConfigParser()
if client is True:
fname = 'ogclient.cfg'
else:

View File

@ -57,7 +57,8 @@ class HTTPServerHandler(BaseHTTPRequestHandler):
return
def sendJsonResponse(self, data):
self.send_response(200)
try: self.send_response(200)
except Exception as e: logger.warn (str(e))
data = json.dumps(data)
self.send_header('Content-type', 'application/json')
self.send_header('Content-Length', str(len(data)))
@ -132,7 +133,9 @@ class HTTPServerThread(threading.Thread):
self.certFile = createSelfSignedCert()
self.server = HTTPThreadingServer(address, HTTPServerHandler)
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=self.certFile, server_side=True)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=self.certFile)
self.server.socket = context.wrap_socket(self.server.socket, server_side=True)
logger.debug('Initialized HTTPS Server thread on {}'.format(address))

View File

@ -65,7 +65,7 @@ def check_secret(fnc):
else:
raise Exception('Unauthorized operation')
except Exception as e:
logger.error(e)
logger.error(str(e))
raise Exception(e)
return wrapper
@ -83,7 +83,7 @@ def execution_level(level):
else:
raise Exception('Unauthorized operation')
except Exception as e:
logger.error(e)
logger.error(str(e))
raise Exception(e)
return wrapper

View File

@ -61,7 +61,7 @@ def exceptionToMessage(e):
if isinstance(arg, Exception):
msg = msg + exceptionToMessage(arg)
else:
msg = msg + toUnicode(arg) + '. '
msg = msg + str(arg) + '. '
return msg

View File

@ -120,5 +120,9 @@ class OGAgentSvc(win32serviceutil.ServiceFramework, CommonService):
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(OGAgentSvc)
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(OGAgentSvc)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(OGAgentSvc)

View File

@ -47,7 +47,7 @@ class LocalLogger(object):
logging.basicConfig(
filename=os.path.join(tempfile.gettempdir(), 'opengnsys.log'),
filemode='a',
format='%(levelname)s %(asctime)s %(message)s',
format='%(levelname)s %(asctime)s (%(threadName)s) %(message)s',
level=logging.DEBUG
)
self.logger = logging.getLogger('opengnsys')
@ -58,7 +58,7 @@ class LocalLogger(object):
# our loglevels are 10000 (other), 20000 (debug), ....
# logging levels are 10 (debug), 20 (info)
# OTHER = logging.NOTSET
self.logger.log(level / 1000 - 10, message)
self.logger.log(int(level / 1000 - 10), message)
if level < INFO or self.serviceLogger is False: # Only information and above will be on event log
return

View File

@ -64,7 +64,7 @@ def getNetworkInfo():
ip: ip of the interface
'''
obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
wmobj = obj.ConnectServer("localhost", "root\cimv2")
wmobj = obj.ConnectServer("localhost", "root\\cimv2")
adapters = wmobj.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IpEnabled=True")
try:
for obj in adapters:
@ -102,12 +102,12 @@ def getWindowsVersion():
'''
Returns Windows version.
'''
import _winreg
reg = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion')
import winreg
reg = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion')
try:
data = '{} {}'.format(_winreg.QueryValueEx(reg, 'ProductName')[0], _winreg.QueryValueEx(reg, 'ReleaseId')[0])
data = '{} {}'.format(winreg.QueryValueEx(reg, 'ProductName')[0], winreg.QueryValueEx(reg, 'ReleaseId')[0])
except Exception:
data = '{} {}'.format(_winreg.QueryValueEx(reg, 'ProductName')[0], _winreg.QueryValueEx(reg, 'CurrentBuildNumber')[0])
data = '{} {}'.format(winreg.QueryValueEx(reg, 'ProductName')[0], winreg.QueryValueEx(reg, 'CurrentBuildNumber')[0])
reg.Close()
return data

View File

@ -1,3 +1,7 @@
netifaces
#netifaces <--- este es solo para macos...
pywin32
pyqt6
requests
urllib3
six
pycryptodome
pyinstaller

View File

@ -1,139 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
@author: Adolfo Gómez, dkmaster at dkmon dot com
@author: Ramón M. Gómez, ramongomez at us dot es
"""
# ModuleFinder can't handle runtime changes to __path__, but win32com uses them
try:
# py2exe 0.6.4 introduced a replacement modulefinder.
# This means we have to add package paths there, not to the built-in
# one. If this new modulefinder gets integrated into Python, then
# we might be able to revert this some day.
# if this doesn't work, try import modulefinder
try:
import py2exe.mf as modulefinder
except ImportError:
import modulefinder
import win32com
import sys
for p in win32com.__path__[1:]:
modulefinder.AddPackagePath("win32com", p)
for extra in ["win32com.shell"]: # ,"win32com.mapi"
__import__(extra)
m = sys.modules[extra]
for p in m.__path__[1:]:
modulefinder.AddPackagePath(extra, p)
except ImportError:
# no build path setup, no worries.
pass
import os
from distutils.core import setup
import py2exe
import sys
# update.sh changes this value
VERSION='1.3.0'
sys.argv.append('py2exe')
def get_requests_cert_file():
"""Add Python requests or certifi .pem file for installers."""
import requests
f = os.path.join(os.path.dirname(requests.__file__), 'cacert.pem')
if not os.path.exists(f):
import certifi
f = os.path.join(os.path.dirname(certifi.__file__), 'cacert.pem')
return f
class Target:
def __init__(self, **kw):
self.__dict__.update(kw)
# for the versioninfo resources
self.version = VERSION
self.name = 'OGAgentService'
self.description = 'OpenGnsys Agent Service'
self.author = 'Adolfo Gomez'
self.url = 'https://opengnsys.es/'
self.company_name = "OpenGnsys Project"
self.copyright = "(c) 2014 VirtualCable S.L.U."
self.name = "OpenGnsys Agent"
# Now you need to pass arguments to setup
# windows is a list of scripts that have their own UI and
# thus don't need to run in a console.
ogaservice = Target(
description='OpenGnsys Agent Service',
modules=['opengnsys.windows.OGAgentService'],
icon_resources=[(0, 'img\\oga.ico'), (1, 'img\\oga.ico')],
cmdline_style='pywin32'
)
# Some test_modules are hidden to py2exe by six, we ensure that they appear on "includes"
HIDDEN_BY_SIX = ['SocketServer', 'SimpleHTTPServer', 'urllib']
setup(
windows=[
{
'script': 'OGAgentUser-qt4.py',
'icon_resources': [(0, 'img\\oga.ico'), (1, 'img\\oga.ico')]
},
],
console=[
{
'script': 'OGAServiceHelper.py'
}
],
service=[ogaservice],
data_files=[('', [get_requests_cert_file()]), ('cfg', ['cfg/ogagent.cfg', 'cfg/ogclient.cfg'])],
options={
'py2exe': {
'bundle_files': 3,
'compressed': True,
'optimize': 2,
'includes': ['sip', 'PyQt4', 'win32com.shell', 'requests', 'encodings', 'encodings.utf_8'] + HIDDEN_BY_SIX,
'excludes': ['doctest', 'unittest'],
'dll_excludes': ['msvcp90.dll'],
'dist_dir': '..\\bin',
}
},
name='OpenGnsys Agent',
version=VERSION,
description='OpenGnsys Agent',
author='Adolfo Gomez',
author_email='agomez@virtualcable.es',
zipfile='OGAgent.zip',
)

View File

@ -32,7 +32,6 @@ function update_version {
if [[ -r VERSION ]]; then
V="$(cat VERSION)"
sed -i "s/Version [^<]*/Version $V/" about-dialog.ui
sed -i "s/^VERSION='.*'$/VERSION='$V'/" setup.py
sed -i "s/^VERSION='.*'$/VERSION='$V'/" opengnsys/__init__.py
else
echo 'src/VERSION: No such file or directory'

View File

@ -88,8 +88,8 @@ Section -Main SEC0000
SetShellVarContext all
SetOutPath $INSTDIR
SetOverwrite on
File /r bin\*.*
File vcredist_x86.exe
File /r src\dist\OGAgent\*.*
File windows\setup\VC_redist.x64.exe
File src\VERSION
WriteRegStr HKLM "${REGKEY}\Components" Main 1
SectionEnd
@ -111,7 +111,7 @@ Section -post SEC0001
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" OGAgentTool $INSTDIR\OGAgentUser.exe
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1
ExecWait '"$INSTDIR\vcredist_x86.exe" /passive /norestart'
ExecWait '"$INSTDIR\VC_redist.x64.exe" /passive /norestart'
# Add the application to the firewall exception list - All Networks - All IP Version - Enabled
# SimpleFC::AddApplication "OpenGnsys Agent Service" "$INSTDIR\OGAgentService.exe" 0 2 "" 1
# SimpleFC::AdvAddRule [name] [description] [protocol] [direction]
@ -128,8 +128,6 @@ Section -post SEC0001
WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Power" HiberbootEnabled 0
# Install service
nsExec::Exec /OEM "$INSTDIR\OGAgentService.exe --startup auto install" # Add service after installation
# Update recovery options
nsExec::Exec /OEM "$INSTDIR\OGAServiceHelper.exe"
Exec "net start ogagent"
Exec "$INSTDIR\OGAgentUser.exe"
SectionEnd

View File

@ -1,67 +0,0 @@
#!/bin/sh
# We need:
# * Wine (32 bit)
# * winetricks (in some distributions)
export WINEARCH=win32 WINEPREFIX=$PWD/wine WINEDEBUG=fixme-all
WINE=wine
download() {
mkdir downloads
# Get needed software
cd downloads
wget -nd https://www.python.org/ftp/python/2.7.17/python-2.7.17.msi -O python-2.7.msi
wget -nd https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi
wget -nd https://bootstrap.pypa.io/get-pip.py
wget -nd https://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.11.4/PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe/download -O pyqt-install.exe
wget -nd https://prdownloads.sourceforge.net/nsis/nsis-3.05-setup.exe?download -O nsis-install.exe
wget -nd http://nsis.sourceforge.net/mediawiki/images/d/d7/NSIS_Simple_Firewall_Plugin_1.20.zip
cd ..
}
install_python() {
if which winetricks &>/dev/null; then
echo "Setting up wine prefix (using winetricks)"
winetricks
fi
cd downloads
echo "Installing python"
$WINE msiexec /qn /i python-2.7.msi
echo "Installing vc for python"
$WINE msiexec /qn /i VCForPython27.msi
echo "Installing pyqt (needs X)"
$WINE pyqt-install.exe
echo "Installing nsis (needs X?)"
$WINE nsis-install.exe
cd ..
}
setup_pip() {
echo "Seting up pip..."
$WINE C:\\Python27\\python -m pip install --upgrade pip
}
install_packages() {
echo "Installing pywin32"
$WINE C:\\Python27\\python -m pip install pywin32
echo "Installing py2exe"
$WINE C:\\Python27\\python -m pip install py2exe_py2
echo "Installing required packages"
$WINE C:\\Python27\\python -m pip install requests six
# Using easy_install instead of pip to install pycrypto
$WINE C:\\Python27\\Scripts\\easy_install http://www.voidspace.org.uk/python/pycrypto-2.6.1/pycrypto-2.6.1.win32-py2.7.exe
# Copy nsis required NSIS_Simple_Firewall_Plugin_1
echo "Copying simple firewall plugin for nsis installer"
unzip -o downloads/NSIS_Simple_Firewall_Plugin_1.20.zip SimpleFC.dll -d $WINEPREFIX/drive_c/Program\ Files/NSIS/Plugins/x86-ansi/
unzip -o downloads/NSIS_Simple_Firewall_Plugin_1.20.zip SimpleFC.dll -d $WINEPREFIX/drive_c/Program\ Files/NSIS/Plugins/x86-unicode/
}
download
install_python
setup_pip
install_packages